• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * linux/arch/arm/mach-pxa/poodle.c
4  *
5  *  Support for the SHARP Poodle Board.
6  *
7  * Based on:
8  *  linux/arch/arm/mach-pxa/lubbock.c Author:	Nicolas Pitre
9  *
10  * Change Log
11  *  12-Dec-2002 Sharp Corporation for Poodle
12  *  John Lenz <lenz@cs.wisc.edu> updates to 2.6
13  */
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/export.h>
17 #include <linux/platform_device.h>
18 #include <linux/fb.h>
19 #include <linux/pm.h>
20 #include <linux/delay.h>
21 #include <linux/mtd/physmap.h>
22 #include <linux/gpio.h>
23 #include <linux/gpio/machine.h>
24 #include <linux/i2c.h>
25 #include <linux/platform_data/i2c-pxa.h>
26 #include <linux/regulator/machine.h>
27 #include <linux/spi/spi.h>
28 #include <linux/spi/ads7846.h>
29 #include <linux/spi/pxa2xx_spi.h>
30 #include <linux/mtd/sharpsl.h>
31 #include <linux/memblock.h>
32 
33 #include <mach/hardware.h>
34 #include <asm/mach-types.h>
35 #include <asm/irq.h>
36 #include <asm/setup.h>
37 
38 #include <asm/mach/arch.h>
39 #include <asm/mach/map.h>
40 #include <asm/mach/irq.h>
41 
42 #include "pxa25x.h"
43 #include <linux/platform_data/mmc-pxamci.h>
44 #include "udc.h"
45 #include <linux/platform_data/irda-pxaficp.h>
46 #include <mach/poodle.h>
47 #include <linux/platform_data/video-pxafb.h>
48 
49 #include <asm/hardware/scoop.h>
50 #include <asm/hardware/locomo.h>
51 #include <asm/mach/sharpsl_param.h>
52 
53 #include "generic.h"
54 #include "devices.h"
55 
56 static unsigned long poodle_pin_config[] __initdata = {
57 	/* I/O */
58 	GPIO79_nCS_3,
59 	GPIO80_nCS_4,
60 	GPIO18_RDY,
61 
62 	/* Clock */
63 	GPIO12_32KHz,
64 
65 	/* SSP1 */
66 	GPIO23_SSP1_SCLK,
67 	GPIO25_SSP1_TXD,
68 	GPIO26_SSP1_RXD,
69 	GPIO24_GPIO,	/* POODLE_GPIO_TP_CS - SFRM as chip select */
70 
71 	/* I2S */
72 	GPIO28_I2S_BITCLK_OUT,
73 	GPIO29_I2S_SDATA_IN,
74 	GPIO30_I2S_SDATA_OUT,
75 	GPIO31_I2S_SYNC,
76 	GPIO32_I2S_SYSCLK,
77 
78 	/* Infra-Red */
79 	GPIO47_FICP_TXD,
80 	GPIO46_FICP_RXD,
81 
82 	/* FFUART */
83 	GPIO40_FFUART_DTR,
84 	GPIO41_FFUART_RTS,
85 	GPIO39_FFUART_TXD,
86 	GPIO37_FFUART_DSR,
87 	GPIO34_FFUART_RXD,
88 	GPIO35_FFUART_CTS,
89 
90 	/* LCD */
91 	GPIOxx_LCD_TFT_16BPP,
92 
93 	/* PC Card */
94 	GPIO48_nPOE,
95 	GPIO49_nPWE,
96 	GPIO50_nPIOR,
97 	GPIO51_nPIOW,
98 	GPIO52_nPCE_1,
99 	GPIO53_nPCE_2,
100 	GPIO54_nPSKTSEL,
101 	GPIO55_nPREG,
102 	GPIO56_nPWAIT,
103 	GPIO57_nIOIS16,
104 
105 	/* MMC */
106 	GPIO6_MMC_CLK,
107 	GPIO8_MMC_CS0,
108 
109 	/* GPIO */
110 	GPIO9_GPIO,	/* POODLE_GPIO_nSD_DETECT */
111 	GPIO7_GPIO,	/* POODLE_GPIO_nSD_WP */
112 	GPIO3_GPIO,	/* POODLE_GPIO_SD_PWR */
113 	GPIO33_GPIO,	/* POODLE_GPIO_SD_PWR1 */
114 
115 	GPIO20_GPIO,	/* POODLE_GPIO_USB_PULLUP */
116 	GPIO22_GPIO,	/* POODLE_GPIO_IR_ON */
117 };
118 
119 static struct resource poodle_scoop_resources[] = {
120 	[0] = {
121 		.start		= 0x10800000,
122 		.end		= 0x10800fff,
123 		.flags		= IORESOURCE_MEM,
124 	},
125 };
126 
127 static struct scoop_config poodle_scoop_setup = {
128 	.io_dir		= POODLE_SCOOP_IO_DIR,
129 	.io_out		= POODLE_SCOOP_IO_OUT,
130 	.gpio_base	= POODLE_SCOOP_GPIO_BASE,
131 };
132 
133 struct platform_device poodle_scoop_device = {
134 	.name		= "sharp-scoop",
135 	.id		= -1,
136 	.dev		= {
137 		.platform_data	= &poodle_scoop_setup,
138 	},
139 	.num_resources	= ARRAY_SIZE(poodle_scoop_resources),
140 	.resource	= poodle_scoop_resources,
141 };
142 
143 static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = {
144 {
145 	.dev        = &poodle_scoop_device.dev,
146 	.irq        = POODLE_IRQ_GPIO_CF_IRQ,
147 	.cd_irq     = POODLE_IRQ_GPIO_CF_CD,
148 	.cd_irq_str = "PCMCIA0 CD",
149 },
150 };
151 
152 static struct scoop_pcmcia_config poodle_pcmcia_config = {
153 	.devs         = &poodle_pcmcia_scoop[0],
154 	.num_devs     = 1,
155 };
156 
157 EXPORT_SYMBOL(poodle_scoop_device);
158 
159 
160 static struct platform_device poodle_audio_device = {
161 	.name	= "poodle-audio",
162 	.id	= -1,
163 };
164 
165 /* LoCoMo device */
166 static struct resource locomo_resources[] = {
167 	[0] = {
168 		.start		= 0x10000000,
169 		.end		= 0x10001fff,
170 		.flags		= IORESOURCE_MEM,
171 	},
172 	[1] = {
173 		.start		= PXA_GPIO_TO_IRQ(10),
174 		.end		= PXA_GPIO_TO_IRQ(10),
175 		.flags		= IORESOURCE_IRQ,
176 	},
177 };
178 
179 static struct locomo_platform_data locomo_info = {
180 	.irq_base	= IRQ_BOARD_START,
181 };
182 
183 struct platform_device poodle_locomo_device = {
184 	.name		= "locomo",
185 	.id		= 0,
186 	.num_resources	= ARRAY_SIZE(locomo_resources),
187 	.resource	= locomo_resources,
188 	.dev		= {
189 		.platform_data	= &locomo_info,
190 	},
191 };
192 
193 EXPORT_SYMBOL(poodle_locomo_device);
194 
195 #if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE)
196 static struct pxa2xx_spi_controller poodle_spi_info = {
197 	.num_chipselect	= 1,
198 };
199 
200 static struct ads7846_platform_data poodle_ads7846_info = {
201 	.model			= 7846,
202 	.vref_delay_usecs	= 100,
203 	.x_plate_ohms		= 419,
204 	.y_plate_ohms		= 486,
205 	.gpio_pendown		= POODLE_GPIO_TP_INT,
206 };
207 
208 static struct pxa2xx_spi_chip poodle_ads7846_chip = {
209 	.gpio_cs		= POODLE_GPIO_TP_CS,
210 };
211 
212 static struct spi_board_info poodle_spi_devices[] = {
213 	{
214 		.modalias	= "ads7846",
215 		.max_speed_hz	= 10000,
216 		.bus_num	= 1,
217 		.platform_data	= &poodle_ads7846_info,
218 		.controller_data= &poodle_ads7846_chip,
219 		.irq		= PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
220 	},
221 };
222 
poodle_init_spi(void)223 static void __init poodle_init_spi(void)
224 {
225 	pxa2xx_set_spi_info(1, &poodle_spi_info);
226 	spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
227 }
228 #else
poodle_init_spi(void)229 static inline void poodle_init_spi(void) {}
230 #endif
231 
232 /*
233  * MMC/SD Device
234  *
235  * The card detect interrupt isn't debounced so we delay it by 250ms
236  * to give the card a chance to fully insert/eject.
237  */
poodle_mci_init(struct device * dev,irq_handler_t poodle_detect_int,void * data)238 static int poodle_mci_init(struct device *dev, irq_handler_t poodle_detect_int, void *data)
239 {
240 	int err;
241 
242 	err = gpio_request(POODLE_GPIO_SD_PWR, "SD_PWR");
243 	if (err)
244 		goto err_free_2;
245 
246 	err = gpio_request(POODLE_GPIO_SD_PWR1, "SD_PWR1");
247 	if (err)
248 		goto err_free_3;
249 
250 	gpio_direction_output(POODLE_GPIO_SD_PWR, 0);
251 	gpio_direction_output(POODLE_GPIO_SD_PWR1, 0);
252 
253 	return 0;
254 
255 err_free_3:
256 	gpio_free(POODLE_GPIO_SD_PWR);
257 err_free_2:
258 	return err;
259 }
260 
poodle_mci_setpower(struct device * dev,unsigned int vdd)261 static int poodle_mci_setpower(struct device *dev, unsigned int vdd)
262 {
263 	struct pxamci_platform_data* p_d = dev->platform_data;
264 
265 	if ((1 << vdd) & p_d->ocr_mask) {
266 		gpio_set_value(POODLE_GPIO_SD_PWR, 1);
267 		mdelay(2);
268 		gpio_set_value(POODLE_GPIO_SD_PWR1, 1);
269 	} else {
270 		gpio_set_value(POODLE_GPIO_SD_PWR1, 0);
271 		gpio_set_value(POODLE_GPIO_SD_PWR, 0);
272 	}
273 
274 	return 0;
275 }
276 
poodle_mci_exit(struct device * dev,void * data)277 static void poodle_mci_exit(struct device *dev, void *data)
278 {
279 	gpio_free(POODLE_GPIO_SD_PWR1);
280 	gpio_free(POODLE_GPIO_SD_PWR);
281 }
282 
283 static struct pxamci_platform_data poodle_mci_platform_data = {
284 	.detect_delay_ms	= 250,
285 	.ocr_mask		= MMC_VDD_32_33|MMC_VDD_33_34,
286 	.init 			= poodle_mci_init,
287 	.setpower 		= poodle_mci_setpower,
288 	.exit			= poodle_mci_exit,
289 };
290 
291 static struct gpiod_lookup_table poodle_mci_gpio_table = {
292 	.dev_id = "pxa2xx-mci.0",
293 	.table = {
294 		GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_DETECT,
295 			    "cd", GPIO_ACTIVE_LOW),
296 		GPIO_LOOKUP("gpio-pxa", POODLE_GPIO_nSD_WP,
297 			    "wp", GPIO_ACTIVE_LOW),
298 		{ },
299 	},
300 };
301 
302 /*
303  * Irda
304  */
305 static struct pxaficp_platform_data poodle_ficp_platform_data = {
306 	.gpio_pwdown		= POODLE_GPIO_IR_ON,
307 	.transceiver_cap	= IR_SIRMODE | IR_OFF,
308 };
309 
310 
311 /*
312  * USB Device Controller
313  */
314 static struct pxa2xx_udc_mach_info udc_info __initdata = {
315 	/* no connect GPIO; poodle can't tell connection status */
316 	.gpio_pullup	= POODLE_GPIO_USB_PULLUP,
317 };
318 
319 
320 /* PXAFB device */
321 static struct pxafb_mode_info poodle_fb_mode = {
322 	.pixclock	= 144700,
323 	.xres		= 320,
324 	.yres		= 240,
325 	.bpp		= 16,
326 	.hsync_len	= 7,
327 	.left_margin	= 11,
328 	.right_margin	= 30,
329 	.vsync_len	= 2,
330 	.upper_margin	= 2,
331 	.lower_margin	= 0,
332 	.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
333 };
334 
335 static struct pxafb_mach_info poodle_fb_info = {
336 	.modes		= &poodle_fb_mode,
337 	.num_modes	= 1,
338 	.lcd_conn	= LCD_COLOR_TFT_16BPP,
339 };
340 
341 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
342 
343 static struct nand_bbt_descr sharpsl_bbt = {
344 	.options = 0,
345 	.offs = 4,
346 	.len = 2,
347 	.pattern = scan_ff_pattern
348 };
349 
350 static const char * const probes[] = {
351 	"cmdlinepart",
352 	"ofpart",
353 	"sharpslpart",
354 	NULL,
355 };
356 
357 static struct sharpsl_nand_platform_data sharpsl_nand_platform_data = {
358 	.badblock_pattern	= &sharpsl_bbt,
359 	.part_parsers		= probes,
360 };
361 
362 static struct resource sharpsl_nand_resources[] = {
363 	{
364 		.start	= 0x0C000000,
365 		.end	= 0x0C000FFF,
366 		.flags	= IORESOURCE_MEM,
367 	},
368 };
369 
370 static struct platform_device sharpsl_nand_device = {
371 	.name		= "sharpsl-nand",
372 	.id		= -1,
373 	.resource	= sharpsl_nand_resources,
374 	.num_resources	= ARRAY_SIZE(sharpsl_nand_resources),
375 	.dev.platform_data	= &sharpsl_nand_platform_data,
376 };
377 
378 static struct mtd_partition sharpsl_rom_parts[] = {
379 	{
380 		.name	="Boot PROM Filesystem",
381 		.offset	= 0x00120000,
382 		.size	= MTDPART_SIZ_FULL,
383 	},
384 };
385 
386 static struct physmap_flash_data sharpsl_rom_data = {
387 	.width		= 2,
388 	.nr_parts	= ARRAY_SIZE(sharpsl_rom_parts),
389 	.parts		= sharpsl_rom_parts,
390 };
391 
392 static struct resource sharpsl_rom_resources[] = {
393 	{
394 		.start	= 0x00000000,
395 		.end	= 0x007fffff,
396 		.flags	= IORESOURCE_MEM,
397 	},
398 };
399 
400 static struct platform_device sharpsl_rom_device = {
401 	.name	= "physmap-flash",
402 	.id	= -1,
403 	.resource = sharpsl_rom_resources,
404 	.num_resources = ARRAY_SIZE(sharpsl_rom_resources),
405 	.dev.platform_data = &sharpsl_rom_data,
406 };
407 
408 static struct platform_device *devices[] __initdata = {
409 	&poodle_locomo_device,
410 	&poodle_scoop_device,
411 	&poodle_audio_device,
412 	&sharpsl_nand_device,
413 	&sharpsl_rom_device,
414 };
415 
416 static struct i2c_board_info __initdata poodle_i2c_devices[] = {
417 	{ I2C_BOARD_INFO("wm8731", 0x1b) },
418 };
419 
poodle_poweroff(void)420 static void poodle_poweroff(void)
421 {
422 	pxa_restart(REBOOT_HARD, NULL);
423 }
424 
poodle_init(void)425 static void __init poodle_init(void)
426 {
427 	int ret = 0;
428 
429 	pm_power_off = poodle_poweroff;
430 
431 	PCFR |= PCFR_OPDE;
432 
433 	pxa2xx_mfp_config(ARRAY_AND_SIZE(poodle_pin_config));
434 
435 	pxa_set_ffuart_info(NULL);
436 	pxa_set_btuart_info(NULL);
437 	pxa_set_stuart_info(NULL);
438 
439 	platform_scoop_config = &poodle_pcmcia_config;
440 
441 	ret = platform_add_devices(devices, ARRAY_SIZE(devices));
442 	if (ret)
443 		pr_warn("poodle: Unable to register LoCoMo device\n");
444 
445 	pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
446 	pxa_set_udc_info(&udc_info);
447 	gpiod_add_lookup_table(&poodle_mci_gpio_table);
448 	pxa_set_mci_info(&poodle_mci_platform_data);
449 	pxa_set_ficp_info(&poodle_ficp_platform_data);
450 	pxa_set_i2c_info(NULL);
451 	i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
452 	poodle_init_spi();
453 	regulator_has_full_constraints();
454 }
455 
fixup_poodle(struct tag * tags,char ** cmdline)456 static void __init fixup_poodle(struct tag *tags, char **cmdline)
457 {
458 	sharpsl_save_param();
459 	memblock_add(0xa0000000, SZ_32M);
460 }
461 
462 MACHINE_START(POODLE, "SHARP Poodle")
463 	.fixup		= fixup_poodle,
464 	.map_io		= pxa25x_map_io,
465 	.nr_irqs	= POODLE_NR_IRQS,	/* 4 for LoCoMo */
466 	.init_irq	= pxa25x_init_irq,
467 	.handle_irq	= pxa25x_handle_irq,
468 	.init_time	= pxa_timer_init,
469 	.init_machine	= poodle_init,
470 	.restart	= pxa_restart,
471 MACHINE_END
472