Commit | Line | Data |
---|---|---|
9b93e244 KM |
1 | /* |
2 | * KZM-A9-GT board support | |
3 | * | |
4 | * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; version 2 of the License. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | */ | |
26786111 KM |
19 | |
20 | #include <linux/delay.h> | |
9b93e244 | 21 | #include <linux/gpio.h> |
1e354641 | 22 | #include <linux/gpio_keys.h> |
9b93e244 KM |
23 | #include <linux/io.h> |
24 | #include <linux/irq.h> | |
407c0526 | 25 | #include <linux/i2c.h> |
1e354641 KM |
26 | #include <linux/i2c/pcf857x.h> |
27 | #include <linux/input.h> | |
520f7bd7 | 28 | #include <linux/irqchip/arm-gic.h> |
cc2512bc KM |
29 | #include <linux/mmc/host.h> |
30 | #include <linux/mmc/sh_mmcif.h> | |
7775a933 | 31 | #include <linux/mmc/sh_mobile_sdhi.h> |
28307e0a | 32 | #include <linux/mfd/as3711.h> |
7775a933 | 33 | #include <linux/mfd/tmio.h> |
f3202e1b | 34 | #include <linux/pinctrl/machine.h> |
83aeac98 | 35 | #include <linux/pinctrl/pinconf-generic.h> |
9b93e244 | 36 | #include <linux/platform_device.h> |
7b6d864b | 37 | #include <linux/reboot.h> |
44a4244e GL |
38 | #include <linux/regulator/fixed.h> |
39 | #include <linux/regulator/machine.h> | |
c15c4257 | 40 | #include <linux/smsc911x.h> |
dd818180 | 41 | #include <linux/usb/r8a66597.h> |
77bcefd9 | 42 | #include <linux/usb/renesas_usbhs.h> |
26786111 | 43 | #include <linux/videodev2.h> |
accb90c8 KM |
44 | #include <sound/sh_fsi.h> |
45 | #include <sound/simple_card.h> | |
c15c4257 | 46 | #include <mach/irqs.h> |
9b93e244 KM |
47 | #include <mach/sh73a0.h> |
48 | #include <mach/common.h> | |
49 | #include <asm/hardware/cache-l2x0.h> | |
9b93e244 KM |
50 | #include <asm/mach-types.h> |
51 | #include <asm/mach/arch.h> | |
26786111 | 52 | #include <video/sh_mobile_lcdc.h> |
9b93e244 | 53 | |
1e354641 KM |
54 | /* |
55 | * external GPIO | |
56 | */ | |
57 | #define GPIO_PCF8575_BASE (GPIO_NR) | |
58 | #define GPIO_PCF8575_PORT10 (GPIO_NR + 8) | |
59 | #define GPIO_PCF8575_PORT11 (GPIO_NR + 9) | |
60 | #define GPIO_PCF8575_PORT12 (GPIO_NR + 10) | |
61 | #define GPIO_PCF8575_PORT13 (GPIO_NR + 11) | |
62 | #define GPIO_PCF8575_PORT14 (GPIO_NR + 12) | |
63 | #define GPIO_PCF8575_PORT15 (GPIO_NR + 13) | |
64 | #define GPIO_PCF8575_PORT16 (GPIO_NR + 14) | |
65 | ||
44a4244e GL |
66 | /* Dummy supplies, where voltage doesn't matter */ |
67 | static struct regulator_consumer_supply dummy_supplies[] = { | |
48296a13 SH |
68 | REGULATOR_SUPPLY("vddvario", "smsc911x.0"), |
69 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | |
44a4244e GL |
70 | }; |
71 | ||
accb90c8 KM |
72 | /* |
73 | * FSI-AK4648 | |
74 | * | |
75 | * this command is required when playback. | |
76 | * | |
77 | * # amixer set "LINEOUT Mixer DACL" on | |
78 | */ | |
79 | ||
c15c4257 KM |
80 | /* SMSC 9221 */ |
81 | static struct resource smsc9221_resources[] = { | |
82 | [0] = { | |
83 | .start = 0x10000000, /* CS4 */ | |
84 | .end = 0x100000ff, | |
85 | .flags = IORESOURCE_MEM, | |
86 | }, | |
87 | [1] = { | |
341eb546 | 88 | .start = irq_pin(3), /* IRQ3 */ |
c15c4257 KM |
89 | .flags = IORESOURCE_IRQ, |
90 | }, | |
91 | }; | |
92 | ||
93 | static struct smsc911x_platform_config smsc9221_platdata = { | |
94 | .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, | |
95 | .phy_interface = PHY_INTERFACE_MODE_MII, | |
96 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | |
97 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | |
98 | }; | |
99 | ||
100 | static struct platform_device smsc_device = { | |
101 | .name = "smsc911x", | |
102 | .dev = { | |
103 | .platform_data = &smsc9221_platdata, | |
104 | }, | |
105 | .resource = smsc9221_resources, | |
106 | .num_resources = ARRAY_SIZE(smsc9221_resources), | |
107 | }; | |
108 | ||
dd818180 KM |
109 | /* USB external chip */ |
110 | static struct r8a66597_platdata usb_host_data = { | |
111 | .on_chip = 0, | |
112 | .xtal = R8A66597_PLATDATA_XTAL_48MHZ, | |
113 | }; | |
114 | ||
115 | static struct resource usb_resources[] = { | |
116 | [0] = { | |
117 | .start = 0x10010000, | |
118 | .end = 0x1001ffff - 1, | |
119 | .flags = IORESOURCE_MEM, | |
120 | }, | |
121 | [1] = { | |
341eb546 | 122 | .start = irq_pin(1), /* IRQ1 */ |
dd818180 KM |
123 | .flags = IORESOURCE_IRQ, |
124 | }, | |
125 | }; | |
126 | ||
127 | static struct platform_device usb_host_device = { | |
128 | .name = "r8a66597_hcd", | |
129 | .dev = { | |
130 | .platform_data = &usb_host_data, | |
131 | .dma_mask = NULL, | |
132 | .coherent_dma_mask = 0xffffffff, | |
133 | }, | |
134 | .num_resources = ARRAY_SIZE(usb_resources), | |
135 | .resource = usb_resources, | |
136 | }; | |
137 | ||
77bcefd9 KM |
138 | /* USB Func CN17 */ |
139 | struct usbhs_private { | |
0a4b04dc AB |
140 | void __iomem *phy; |
141 | void __iomem *cr2; | |
77bcefd9 KM |
142 | struct renesas_usbhs_platform_info info; |
143 | }; | |
144 | ||
341eb546 | 145 | #define IRQ15 irq_pin(15) |
77bcefd9 KM |
146 | #define USB_PHY_MODE (1 << 4) |
147 | #define USB_PHY_INT_EN ((1 << 3) | (1 << 2)) | |
148 | #define USB_PHY_ON (1 << 1) | |
149 | #define USB_PHY_OFF (1 << 0) | |
150 | #define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF) | |
151 | ||
152 | #define usbhs_get_priv(pdev) \ | |
153 | container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info) | |
154 | ||
155 | static int usbhs_get_vbus(struct platform_device *pdev) | |
156 | { | |
157 | struct usbhs_private *priv = usbhs_get_priv(pdev); | |
158 | ||
159 | return !((1 << 7) & __raw_readw(priv->cr2)); | |
160 | } | |
161 | ||
225da3e3 | 162 | static int usbhs_phy_reset(struct platform_device *pdev) |
77bcefd9 KM |
163 | { |
164 | struct usbhs_private *priv = usbhs_get_priv(pdev); | |
165 | ||
166 | /* init phy */ | |
167 | __raw_writew(0x8a0a, priv->cr2); | |
225da3e3 KM |
168 | |
169 | return 0; | |
77bcefd9 KM |
170 | } |
171 | ||
172 | static int usbhs_get_id(struct platform_device *pdev) | |
173 | { | |
174 | return USBHS_GADGET; | |
175 | } | |
176 | ||
177 | static irqreturn_t usbhs_interrupt(int irq, void *data) | |
178 | { | |
179 | struct platform_device *pdev = data; | |
180 | struct usbhs_private *priv = usbhs_get_priv(pdev); | |
181 | ||
182 | renesas_usbhs_call_notify_hotplug(pdev); | |
183 | ||
184 | /* clear status */ | |
185 | __raw_writew(__raw_readw(priv->phy) | USB_PHY_INT_CLR, priv->phy); | |
186 | ||
187 | return IRQ_HANDLED; | |
188 | } | |
189 | ||
190 | static int usbhs_hardware_init(struct platform_device *pdev) | |
191 | { | |
192 | struct usbhs_private *priv = usbhs_get_priv(pdev); | |
193 | int ret; | |
194 | ||
195 | /* clear interrupt status */ | |
196 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); | |
197 | ||
198 | ret = request_irq(IRQ15, usbhs_interrupt, IRQF_TRIGGER_HIGH, | |
199 | dev_name(&pdev->dev), pdev); | |
200 | if (ret) { | |
201 | dev_err(&pdev->dev, "request_irq err\n"); | |
202 | return ret; | |
203 | } | |
204 | ||
205 | /* enable USB phy interrupt */ | |
206 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->phy); | |
207 | ||
208 | return 0; | |
209 | } | |
210 | ||
225da3e3 | 211 | static int usbhs_hardware_exit(struct platform_device *pdev) |
77bcefd9 KM |
212 | { |
213 | struct usbhs_private *priv = usbhs_get_priv(pdev); | |
214 | ||
215 | /* clear interrupt status */ | |
216 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); | |
217 | ||
218 | free_irq(IRQ15, pdev); | |
225da3e3 KM |
219 | |
220 | return 0; | |
77bcefd9 KM |
221 | } |
222 | ||
223 | static u32 usbhs_pipe_cfg[] = { | |
224 | USB_ENDPOINT_XFER_CONTROL, | |
225 | USB_ENDPOINT_XFER_ISOC, | |
226 | USB_ENDPOINT_XFER_ISOC, | |
227 | USB_ENDPOINT_XFER_BULK, | |
228 | USB_ENDPOINT_XFER_BULK, | |
229 | USB_ENDPOINT_XFER_BULK, | |
230 | USB_ENDPOINT_XFER_INT, | |
231 | USB_ENDPOINT_XFER_INT, | |
232 | USB_ENDPOINT_XFER_INT, | |
233 | USB_ENDPOINT_XFER_BULK, | |
234 | USB_ENDPOINT_XFER_BULK, | |
235 | USB_ENDPOINT_XFER_BULK, | |
236 | USB_ENDPOINT_XFER_BULK, | |
237 | USB_ENDPOINT_XFER_BULK, | |
238 | USB_ENDPOINT_XFER_BULK, | |
239 | USB_ENDPOINT_XFER_BULK, | |
240 | }; | |
241 | ||
242 | static struct usbhs_private usbhs_private = { | |
0a4b04dc AB |
243 | .phy = IOMEM(0xe60781e0), /* USBPHYINT */ |
244 | .cr2 = IOMEM(0xe605810c), /* USBCR2 */ | |
77bcefd9 KM |
245 | .info = { |
246 | .platform_callback = { | |
247 | .hardware_init = usbhs_hardware_init, | |
248 | .hardware_exit = usbhs_hardware_exit, | |
249 | .get_id = usbhs_get_id, | |
250 | .phy_reset = usbhs_phy_reset, | |
251 | .get_vbus = usbhs_get_vbus, | |
252 | }, | |
253 | .driver_param = { | |
254 | .buswait_bwait = 4, | |
255 | .has_otg = 1, | |
256 | .pipe_type = usbhs_pipe_cfg, | |
257 | .pipe_size = ARRAY_SIZE(usbhs_pipe_cfg), | |
258 | }, | |
259 | }, | |
260 | }; | |
261 | ||
262 | static struct resource usbhs_resources[] = { | |
263 | [0] = { | |
264 | .start = 0xE6890000, | |
265 | .end = 0xE68900e6 - 1, | |
266 | .flags = IORESOURCE_MEM, | |
267 | }, | |
268 | [1] = { | |
269 | .start = gic_spi(62), | |
270 | .end = gic_spi(62), | |
271 | .flags = IORESOURCE_IRQ, | |
272 | }, | |
273 | }; | |
274 | ||
275 | static struct platform_device usbhs_device = { | |
276 | .name = "renesas_usbhs", | |
277 | .id = -1, | |
278 | .dev = { | |
279 | .dma_mask = NULL, | |
280 | .coherent_dma_mask = 0xffffffff, | |
281 | .platform_data = &usbhs_private.info, | |
282 | }, | |
283 | .num_resources = ARRAY_SIZE(usbhs_resources), | |
284 | .resource = usbhs_resources, | |
285 | }; | |
286 | ||
26786111 KM |
287 | /* LCDC */ |
288 | static struct fb_videomode kzm_lcdc_mode = { | |
289 | .name = "WVGA Panel", | |
290 | .xres = 800, | |
291 | .yres = 480, | |
292 | .left_margin = 220, | |
293 | .right_margin = 110, | |
294 | .hsync_len = 70, | |
295 | .upper_margin = 20, | |
296 | .lower_margin = 5, | |
297 | .vsync_len = 5, | |
298 | .sync = 0, | |
299 | }; | |
300 | ||
301 | static struct sh_mobile_lcdc_info lcdc_info = { | |
302 | .clock_source = LCDC_CLK_BUS, | |
303 | .ch[0] = { | |
304 | .chan = LCDC_CHAN_MAINLCD, | |
305 | .fourcc = V4L2_PIX_FMT_RGB565, | |
306 | .interface_type = RGB24, | |
307 | .lcd_modes = &kzm_lcdc_mode, | |
308 | .num_modes = 1, | |
309 | .clock_divider = 5, | |
310 | .flags = 0, | |
311 | .panel_cfg = { | |
312 | .width = 152, | |
313 | .height = 91, | |
314 | }, | |
315 | } | |
316 | }; | |
317 | ||
318 | static struct resource lcdc_resources[] = { | |
319 | [0] = { | |
320 | .name = "LCDC", | |
321 | .start = 0xfe940000, | |
322 | .end = 0xfe943fff, | |
323 | .flags = IORESOURCE_MEM, | |
324 | }, | |
325 | [1] = { | |
326 | .start = intcs_evt2irq(0x580), | |
327 | .flags = IORESOURCE_IRQ, | |
328 | }, | |
329 | }; | |
330 | ||
331 | static struct platform_device lcdc_device = { | |
332 | .name = "sh_mobile_lcdc_fb", | |
333 | .num_resources = ARRAY_SIZE(lcdc_resources), | |
334 | .resource = lcdc_resources, | |
335 | .dev = { | |
336 | .platform_data = &lcdc_info, | |
337 | .coherent_dma_mask = ~0, | |
338 | }, | |
339 | }; | |
340 | ||
44a4244e GL |
341 | /* Fixed 1.8V regulator to be used by MMCIF */ |
342 | static struct regulator_consumer_supply fixed1v8_power_consumers[] = | |
343 | { | |
344 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | |
345 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | |
346 | }; | |
347 | ||
cc2512bc KM |
348 | /* MMCIF */ |
349 | static struct resource sh_mmcif_resources[] = { | |
350 | [0] = { | |
351 | .name = "MMCIF", | |
352 | .start = 0xe6bd0000, | |
353 | .end = 0xe6bd00ff, | |
354 | .flags = IORESOURCE_MEM, | |
355 | }, | |
356 | [1] = { | |
a704835d | 357 | .start = gic_spi(140), |
cc2512bc KM |
358 | .flags = IORESOURCE_IRQ, |
359 | }, | |
360 | [2] = { | |
a704835d | 361 | .start = gic_spi(141), |
cc2512bc KM |
362 | .flags = IORESOURCE_IRQ, |
363 | }, | |
364 | }; | |
365 | ||
366 | static struct sh_mmcif_plat_data sh_mmcif_platdata = { | |
367 | .ocr = MMC_VDD_165_195, | |
368 | .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, | |
a1ca8f49 KM |
369 | .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, |
370 | .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, | |
cc2512bc KM |
371 | }; |
372 | ||
373 | static struct platform_device mmc_device = { | |
374 | .name = "sh_mmcif", | |
375 | .dev = { | |
376 | .dma_mask = NULL, | |
377 | .coherent_dma_mask = 0xffffffff, | |
378 | .platform_data = &sh_mmcif_platdata, | |
379 | }, | |
380 | .num_resources = ARRAY_SIZE(sh_mmcif_resources), | |
381 | .resource = sh_mmcif_resources, | |
382 | }; | |
383 | ||
54ca74ef GL |
384 | /* Fixed 3.3V regulators to be used by SDHI0 */ |
385 | static struct regulator_consumer_supply vcc_sdhi0_consumers[] = | |
44a4244e GL |
386 | { |
387 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | |
54ca74ef GL |
388 | }; |
389 | ||
390 | static struct regulator_init_data vcc_sdhi0_init_data = { | |
391 | .constraints = { | |
392 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
393 | }, | |
394 | .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers), | |
395 | .consumer_supplies = vcc_sdhi0_consumers, | |
396 | }; | |
397 | ||
398 | static struct fixed_voltage_config vcc_sdhi0_info = { | |
399 | .supply_name = "SDHI0 Vcc", | |
400 | .microvolts = 3300000, | |
401 | .gpio = 15, | |
402 | .enable_high = 1, | |
403 | .init_data = &vcc_sdhi0_init_data, | |
404 | }; | |
405 | ||
406 | static struct platform_device vcc_sdhi0 = { | |
407 | .name = "reg-fixed-voltage", | |
408 | .id = 0, | |
409 | .dev = { | |
410 | .platform_data = &vcc_sdhi0_info, | |
411 | }, | |
412 | }; | |
413 | ||
414 | /* Fixed 3.3V regulators to be used by SDHI2 */ | |
415 | static struct regulator_consumer_supply vcc_sdhi2_consumers[] = | |
416 | { | |
11b8e452 | 417 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"), |
54ca74ef GL |
418 | }; |
419 | ||
420 | static struct regulator_init_data vcc_sdhi2_init_data = { | |
421 | .constraints = { | |
422 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | |
423 | }, | |
424 | .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi2_consumers), | |
425 | .consumer_supplies = vcc_sdhi2_consumers, | |
426 | }; | |
427 | ||
428 | static struct fixed_voltage_config vcc_sdhi2_info = { | |
429 | .supply_name = "SDHI2 Vcc", | |
430 | .microvolts = 3300000, | |
431 | .gpio = 14, | |
432 | .enable_high = 1, | |
433 | .init_data = &vcc_sdhi2_init_data, | |
434 | }; | |
435 | ||
436 | static struct platform_device vcc_sdhi2 = { | |
437 | .name = "reg-fixed-voltage", | |
438 | .id = 1, | |
439 | .dev = { | |
440 | .platform_data = &vcc_sdhi2_info, | |
441 | }, | |
44a4244e GL |
442 | }; |
443 | ||
7775a933 KM |
444 | /* SDHI */ |
445 | static struct sh_mobile_sdhi_info sdhi0_info = { | |
bd9e2e71 TK |
446 | .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, |
447 | .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, | |
7775a933 | 448 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, |
54ca74ef GL |
449 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ | |
450 | MMC_CAP_POWER_OFF_CARD, | |
7775a933 KM |
451 | }; |
452 | ||
453 | static struct resource sdhi0_resources[] = { | |
454 | [0] = { | |
455 | .name = "SDHI0", | |
456 | .start = 0xee100000, | |
457 | .end = 0xee1000ff, | |
458 | .flags = IORESOURCE_MEM, | |
459 | }, | |
460 | [1] = { | |
461 | .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT, | |
462 | .start = gic_spi(83), | |
463 | .flags = IORESOURCE_IRQ, | |
464 | }, | |
465 | [2] = { | |
466 | .name = SH_MOBILE_SDHI_IRQ_SDCARD, | |
467 | .start = gic_spi(84), | |
468 | .flags = IORESOURCE_IRQ, | |
469 | }, | |
470 | [3] = { | |
471 | .name = SH_MOBILE_SDHI_IRQ_SDIO, | |
472 | .start = gic_spi(85), | |
473 | .flags = IORESOURCE_IRQ, | |
474 | }, | |
475 | }; | |
476 | ||
477 | static struct platform_device sdhi0_device = { | |
478 | .name = "sh_mobile_sdhi", | |
479 | .num_resources = ARRAY_SIZE(sdhi0_resources), | |
480 | .resource = sdhi0_resources, | |
481 | .dev = { | |
482 | .platform_data = &sdhi0_info, | |
483 | }, | |
484 | }; | |
485 | ||
425d6940 KM |
486 | /* Micro SD */ |
487 | static struct sh_mobile_sdhi_info sdhi2_info = { | |
bd9e2e71 TK |
488 | .dma_slave_tx = SHDMA_SLAVE_SDHI2_TX, |
489 | .dma_slave_rx = SHDMA_SLAVE_SDHI2_RX, | |
425d6940 KM |
490 | .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT | |
491 | TMIO_MMC_USE_GPIO_CD | | |
492 | TMIO_MMC_WRPROTECT_DISABLE, | |
54ca74ef | 493 | .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_POWER_OFF_CARD, |
b58e5fac | 494 | .cd_gpio = 13, |
425d6940 KM |
495 | }; |
496 | ||
497 | static struct resource sdhi2_resources[] = { | |
498 | [0] = { | |
499 | .name = "SDHI2", | |
500 | .start = 0xee140000, | |
501 | .end = 0xee1400ff, | |
502 | .flags = IORESOURCE_MEM, | |
503 | }, | |
504 | [1] = { | |
505 | .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT, | |
506 | .start = gic_spi(103), | |
507 | .flags = IORESOURCE_IRQ, | |
508 | }, | |
509 | [2] = { | |
510 | .name = SH_MOBILE_SDHI_IRQ_SDCARD, | |
511 | .start = gic_spi(104), | |
512 | .flags = IORESOURCE_IRQ, | |
513 | }, | |
514 | [3] = { | |
515 | .name = SH_MOBILE_SDHI_IRQ_SDIO, | |
516 | .start = gic_spi(105), | |
517 | .flags = IORESOURCE_IRQ, | |
518 | }, | |
519 | }; | |
520 | ||
521 | static struct platform_device sdhi2_device = { | |
522 | .name = "sh_mobile_sdhi", | |
523 | .id = 2, | |
524 | .num_resources = ARRAY_SIZE(sdhi2_resources), | |
525 | .resource = sdhi2_resources, | |
526 | .dev = { | |
527 | .platform_data = &sdhi2_info, | |
528 | }, | |
529 | }; | |
530 | ||
1e354641 KM |
531 | /* KEY */ |
532 | #define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 } | |
533 | ||
534 | static struct gpio_keys_button gpio_buttons[] = { | |
535 | GPIO_KEY(KEY_BACK, GPIO_PCF8575_PORT10, "SW3"), | |
536 | GPIO_KEY(KEY_RIGHT, GPIO_PCF8575_PORT11, "SW2-R"), | |
537 | GPIO_KEY(KEY_LEFT, GPIO_PCF8575_PORT12, "SW2-L"), | |
538 | GPIO_KEY(KEY_ENTER, GPIO_PCF8575_PORT13, "SW2-P"), | |
539 | GPIO_KEY(KEY_UP, GPIO_PCF8575_PORT14, "SW2-U"), | |
540 | GPIO_KEY(KEY_DOWN, GPIO_PCF8575_PORT15, "SW2-D"), | |
541 | GPIO_KEY(KEY_HOME, GPIO_PCF8575_PORT16, "SW1"), | |
542 | }; | |
543 | ||
544 | static struct gpio_keys_platform_data gpio_key_info = { | |
545 | .buttons = gpio_buttons, | |
546 | .nbuttons = ARRAY_SIZE(gpio_buttons), | |
1e354641 KM |
547 | }; |
548 | ||
549 | static struct platform_device gpio_keys_device = { | |
ee6691d7 | 550 | .name = "gpio-keys", |
1e354641 KM |
551 | .dev = { |
552 | .platform_data = &gpio_key_info, | |
553 | }, | |
554 | }; | |
555 | ||
accb90c8 KM |
556 | /* FSI-AK4648 */ |
557 | static struct sh_fsi_platform_info fsi_info = { | |
558 | .port_a = { | |
76b80329 | 559 | .tx_id = SHDMA_SLAVE_FSI2A_TX, |
accb90c8 KM |
560 | }, |
561 | }; | |
562 | ||
563 | static struct resource fsi_resources[] = { | |
564 | [0] = { | |
565 | .name = "FSI", | |
566 | .start = 0xEC230000, | |
567 | .end = 0xEC230400 - 1, | |
568 | .flags = IORESOURCE_MEM, | |
569 | }, | |
570 | [1] = { | |
571 | .start = gic_spi(146), | |
572 | .flags = IORESOURCE_IRQ, | |
573 | }, | |
574 | }; | |
575 | ||
576 | static struct platform_device fsi_device = { | |
577 | .name = "sh_fsi2", | |
578 | .id = -1, | |
579 | .num_resources = ARRAY_SIZE(fsi_resources), | |
580 | .resource = fsi_resources, | |
581 | .dev = { | |
582 | .platform_data = &fsi_info, | |
583 | }, | |
584 | }; | |
585 | ||
accb90c8 KM |
586 | static struct asoc_simple_card_info fsi2_ak4648_info = { |
587 | .name = "AK4648", | |
588 | .card = "FSI2A-AK4648", | |
accb90c8 KM |
589 | .codec = "ak4642-codec.0-0012", |
590 | .platform = "sh_fsi2", | |
a4a2992c KM |
591 | .daifmt = SND_SOC_DAIFMT_LEFT_J, |
592 | .cpu_dai = { | |
593 | .name = "fsia-dai", | |
594 | .fmt = SND_SOC_DAIFMT_CBS_CFS, | |
595 | }, | |
596 | .codec_dai = { | |
597 | .name = "ak4642-hifi", | |
598 | .fmt = SND_SOC_DAIFMT_CBM_CFM, | |
599 | .sysclk = 11289600, | |
600 | }, | |
accb90c8 KM |
601 | }; |
602 | ||
603 | static struct platform_device fsi_ak4648_device = { | |
604 | .name = "asoc-simple-card", | |
605 | .dev = { | |
606 | .platform_data = &fsi2_ak4648_info, | |
607 | }, | |
608 | }; | |
609 | ||
7775a933 | 610 | /* I2C */ |
28307e0a GL |
611 | |
612 | /* StepDown1 is used to supply 1.315V to the CPU */ | |
613 | static struct regulator_init_data as3711_sd1 = { | |
614 | .constraints = { | |
615 | .name = "1.315V CPU", | |
616 | .boot_on = 1, | |
617 | .always_on = 1, | |
618 | .min_uV = 1315000, | |
619 | .max_uV = 1335000, | |
620 | }, | |
621 | }; | |
622 | ||
623 | /* StepDown2 is used to supply 1.8V to the CPU and to the board */ | |
624 | static struct regulator_init_data as3711_sd2 = { | |
625 | .constraints = { | |
626 | .name = "1.8V", | |
627 | .boot_on = 1, | |
628 | .always_on = 1, | |
629 | .min_uV = 1800000, | |
630 | .max_uV = 1800000, | |
631 | }, | |
632 | }; | |
633 | ||
634 | /* | |
635 | * StepDown3 is switched in parallel with StepDown2, seems to be off, | |
636 | * according to read-back pre-set register values | |
637 | */ | |
638 | ||
639 | /* StepDown4 is used to supply 1.215V to the CPU and to the board */ | |
640 | static struct regulator_init_data as3711_sd4 = { | |
641 | .constraints = { | |
642 | .name = "1.215V", | |
643 | .boot_on = 1, | |
644 | .always_on = 1, | |
645 | .min_uV = 1215000, | |
646 | .max_uV = 1235000, | |
647 | }, | |
648 | }; | |
649 | ||
650 | /* LDO1 is unused and unconnected */ | |
651 | ||
652 | /* LDO2 is used to supply 2.8V to the CPU */ | |
653 | static struct regulator_init_data as3711_ldo2 = { | |
654 | .constraints = { | |
655 | .name = "2.8V CPU", | |
656 | .boot_on = 1, | |
657 | .always_on = 1, | |
658 | .min_uV = 2800000, | |
659 | .max_uV = 2800000, | |
660 | }, | |
661 | }; | |
662 | ||
663 | /* LDO3 is used to supply 3.0V to the CPU */ | |
664 | static struct regulator_init_data as3711_ldo3 = { | |
665 | .constraints = { | |
666 | .name = "3.0V CPU", | |
667 | .boot_on = 1, | |
668 | .always_on = 1, | |
669 | .min_uV = 3000000, | |
670 | .max_uV = 3000000, | |
671 | }, | |
672 | }; | |
673 | ||
674 | /* LDO4 is used to supply 2.8V to the board */ | |
675 | static struct regulator_init_data as3711_ldo4 = { | |
676 | .constraints = { | |
677 | .name = "2.8V", | |
678 | .boot_on = 1, | |
679 | .always_on = 1, | |
680 | .min_uV = 2800000, | |
681 | .max_uV = 2800000, | |
682 | }, | |
683 | }; | |
684 | ||
685 | /* LDO5 is switched parallel to LDO4, also set to 2.8V */ | |
686 | static struct regulator_init_data as3711_ldo5 = { | |
687 | .constraints = { | |
688 | .name = "2.8V #2", | |
689 | .boot_on = 1, | |
690 | .always_on = 1, | |
691 | .min_uV = 2800000, | |
692 | .max_uV = 2800000, | |
693 | }, | |
694 | }; | |
695 | ||
696 | /* LDO6 is unused and unconnected */ | |
697 | ||
698 | /* LDO7 is used to supply 1.15V to the CPU */ | |
699 | static struct regulator_init_data as3711_ldo7 = { | |
700 | .constraints = { | |
701 | .name = "1.15V CPU", | |
702 | .boot_on = 1, | |
703 | .always_on = 1, | |
704 | .min_uV = 1150000, | |
705 | .max_uV = 1150000, | |
706 | }, | |
707 | }; | |
708 | ||
709 | /* LDO8 is switched parallel to LDO7, also set to 1.15V */ | |
710 | static struct regulator_init_data as3711_ldo8 = { | |
711 | .constraints = { | |
712 | .name = "1.15V CPU #2", | |
713 | .boot_on = 1, | |
714 | .always_on = 1, | |
715 | .min_uV = 1150000, | |
716 | .max_uV = 1150000, | |
717 | }, | |
718 | }; | |
719 | ||
720 | static struct as3711_platform_data as3711_pdata = { | |
721 | .regulator = { | |
722 | .init_data = { | |
723 | [AS3711_REGULATOR_SD_1] = &as3711_sd1, | |
724 | [AS3711_REGULATOR_SD_2] = &as3711_sd2, | |
725 | [AS3711_REGULATOR_SD_4] = &as3711_sd4, | |
726 | [AS3711_REGULATOR_LDO_2] = &as3711_ldo2, | |
727 | [AS3711_REGULATOR_LDO_3] = &as3711_ldo3, | |
728 | [AS3711_REGULATOR_LDO_4] = &as3711_ldo4, | |
729 | [AS3711_REGULATOR_LDO_5] = &as3711_ldo5, | |
730 | [AS3711_REGULATOR_LDO_7] = &as3711_ldo7, | |
731 | [AS3711_REGULATOR_LDO_8] = &as3711_ldo8, | |
732 | }, | |
733 | }, | |
734 | .backlight = { | |
735 | .su2_fb = "sh_mobile_lcdc_fb.0", | |
736 | .su2_max_uA = 36000, | |
737 | .su2_feedback = AS3711_SU2_CURR_AUTO, | |
738 | .su2_fbprot = AS3711_SU2_GPIO4, | |
739 | .su2_auto_curr1 = true, | |
740 | .su2_auto_curr2 = true, | |
741 | .su2_auto_curr3 = true, | |
742 | }, | |
743 | }; | |
744 | ||
1e354641 KM |
745 | static struct pcf857x_platform_data pcf8575_pdata = { |
746 | .gpio_base = GPIO_PCF8575_BASE, | |
747 | }; | |
748 | ||
accb90c8 KM |
749 | static struct i2c_board_info i2c0_devices[] = { |
750 | { | |
751 | I2C_BOARD_INFO("ak4648", 0x12), | |
080e0d13 TK |
752 | }, |
753 | { | |
754 | I2C_BOARD_INFO("r2025sd", 0x32), | |
8cec0123 TK |
755 | }, |
756 | { | |
757 | I2C_BOARD_INFO("ak8975", 0x0c), | |
341eb546 | 758 | .irq = irq_pin(28), /* IRQ28 */ |
8cec0123 | 759 | }, |
608c5620 TK |
760 | { |
761 | I2C_BOARD_INFO("adxl34x", 0x1d), | |
341eb546 | 762 | .irq = irq_pin(26), /* IRQ26 */ |
608c5620 | 763 | }, |
28307e0a GL |
764 | { |
765 | I2C_BOARD_INFO("as3711", 0x40), | |
766 | .irq = intcs_evt2irq(0x3300), /* IRQ24 */ | |
767 | .platform_data = &as3711_pdata, | |
768 | }, | |
accb90c8 KM |
769 | }; |
770 | ||
407c0526 KM |
771 | static struct i2c_board_info i2c1_devices[] = { |
772 | { | |
773 | I2C_BOARD_INFO("st1232-ts", 0x55), | |
341eb546 | 774 | .irq = irq_pin(8), /* IRQ8 */ |
407c0526 KM |
775 | }, |
776 | }; | |
777 | ||
1e354641 KM |
778 | static struct i2c_board_info i2c3_devices[] = { |
779 | { | |
780 | I2C_BOARD_INFO("pcf8575", 0x20), | |
341eb546 | 781 | .irq = irq_pin(19), /* IRQ19 */ |
1e354641 KM |
782 | .platform_data = &pcf8575_pdata, |
783 | }, | |
784 | }; | |
785 | ||
9b93e244 | 786 | static struct platform_device *kzm_devices[] __initdata = { |
c15c4257 | 787 | &smsc_device, |
dd818180 | 788 | &usb_host_device, |
77bcefd9 | 789 | &usbhs_device, |
26786111 | 790 | &lcdc_device, |
cc2512bc | 791 | &mmc_device, |
54ca74ef GL |
792 | &vcc_sdhi0, |
793 | &vcc_sdhi2, | |
7775a933 | 794 | &sdhi0_device, |
425d6940 | 795 | &sdhi2_device, |
1e354641 | 796 | &gpio_keys_device, |
accb90c8 KM |
797 | &fsi_device, |
798 | &fsi_ak4648_device, | |
9b93e244 KM |
799 | }; |
800 | ||
83aeac98 LP |
801 | static unsigned long pin_pullup_conf[] = { |
802 | PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 0), | |
803 | }; | |
804 | ||
f3202e1b | 805 | static const struct pinctrl_map kzm_pinctrl_map[] = { |
ee9f8da7 | 806 | /* FSIA (AK4648) */ |
41534a37 | 807 | PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", |
ee9f8da7 | 808 | "fsia_mclk_in", "fsia"), |
41534a37 | 809 | PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", |
ee9f8da7 | 810 | "fsia_sclk_in", "fsia"), |
41534a37 | 811 | PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", |
ee9f8da7 | 812 | "fsia_data_in", "fsia"), |
41534a37 | 813 | PIN_MAP_MUX_GROUP_DEFAULT("sh_fsi2", "pfc-sh73a0", |
ee9f8da7 | 814 | "fsia_data_out", "fsia"), |
118b673e LP |
815 | /* I2C3 */ |
816 | PIN_MAP_MUX_GROUP_DEFAULT("i2c-sh_mobile.3", "pfc-sh73a0", | |
817 | "i2c3_1", "i2c3"), | |
f3202e1b LP |
818 | /* LCD */ |
819 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh73a0", | |
820 | "lcd_data24", "lcd"), | |
821 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_lcdc_fb.0", "pfc-sh73a0", | |
822 | "lcd_sync", "lcd"), | |
83aeac98 LP |
823 | /* MMCIF */ |
824 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", | |
825 | "mmc0_data8_0", "mmc0"), | |
826 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", | |
827 | "mmc0_ctrl_0", "mmc0"), | |
828 | PIN_MAP_CONFIGS_PIN_DEFAULT("sh_mmcif.0", "pfc-sh73a0", | |
829 | "PORT279", pin_pullup_conf), | |
830 | PIN_MAP_CONFIGS_GROUP_DEFAULT("sh_mmcif.0", "pfc-sh73a0", | |
831 | "mmc0_data8_0", pin_pullup_conf), | |
5606ed9c LP |
832 | /* SCIFA4 */ |
833 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", | |
834 | "scifa4_data", "scifa4"), | |
835 | PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.4", "pfc-sh73a0", | |
836 | "scifa4_ctrl", "scifa4"), | |
83aeac98 LP |
837 | /* SDHI0 */ |
838 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", | |
839 | "sdhi0_data4", "sdhi0"), | |
840 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", | |
841 | "sdhi0_ctrl", "sdhi0"), | |
842 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", | |
843 | "sdhi0_cd", "sdhi0"), | |
844 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-sh73a0", | |
845 | "sdhi0_wp", "sdhi0"), | |
846 | /* SDHI2 */ | |
847 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh73a0", | |
848 | "sdhi2_data4", "sdhi2"), | |
849 | PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-sh73a0", | |
850 | "sdhi2_ctrl", "sdhi2"), | |
fed94cf8 LP |
851 | /* SMSC */ |
852 | PIN_MAP_MUX_GROUP_DEFAULT("smsc911x.0", "pfc-sh73a0", | |
853 | "bsc_cs4", "bsc"), | |
f4243860 LP |
854 | /* USB */ |
855 | PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-sh73a0", | |
856 | "usb_vbus", "usb"), | |
f3202e1b LP |
857 | }; |
858 | ||
9b93e244 KM |
859 | static void __init kzm_init(void) |
860 | { | |
54ca74ef | 861 | regulator_register_always_on(2, "fixed-1.8V", fixed1v8_power_consumers, |
44a4244e | 862 | ARRAY_SIZE(fixed1v8_power_consumers), 1800000); |
54ca74ef | 863 | regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies)); |
44a4244e | 864 | |
f3202e1b | 865 | pinctrl_register_mappings(kzm_pinctrl_map, ARRAY_SIZE(kzm_pinctrl_map)); |
9b93e244 | 866 | |
9b93e244 | 867 | sh73a0_pinmux_init(); |
c15c4257 KM |
868 | |
869 | /* SMSC */ | |
b58e5fac | 870 | gpio_request_one(224, GPIOF_IN, NULL); /* IRQ3 */ |
c15c4257 | 871 | |
26786111 | 872 | /* LCDC */ |
b58e5fac GL |
873 | gpio_request_one(222, GPIOF_OUT_INIT_HIGH, NULL); /* LCDCDON */ |
874 | gpio_request_one(226, GPIOF_OUT_INIT_HIGH, NULL); /* SC */ | |
26786111 | 875 | |
407c0526 | 876 | /* Touchscreen */ |
b58e5fac | 877 | gpio_request_one(223, GPIOF_IN, NULL); /* IRQ8 */ |
cc2512bc | 878 | |
9b93e244 KM |
879 | #ifdef CONFIG_CACHE_L2X0 |
880 | /* Early BRESP enable, Shared attribute override enable, 64K*8way */ | |
881 | l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff); | |
882 | #endif | |
883 | ||
accb90c8 | 884 | i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices)); |
407c0526 | 885 | i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices)); |
1e354641 | 886 | i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices)); |
407c0526 | 887 | |
9b93e244 KM |
888 | sh73a0_add_standard_devices(); |
889 | platform_add_devices(kzm_devices, ARRAY_SIZE(kzm_devices)); | |
13baf88b BH |
890 | |
891 | sh73a0_pm_init(); | |
9b93e244 KM |
892 | } |
893 | ||
7b6d864b | 894 | static void kzm9g_restart(enum reboot_mode mode, const char *cmd) |
7952717a | 895 | { |
28901c1f | 896 | #define RESCNT2 IOMEM(0xe6188020) |
7952717a TK |
897 | /* Do soft power on reset */ |
898 | writel((1 << 31), RESCNT2); | |
899 | } | |
900 | ||
7296d932 MD |
901 | static const char *kzm9g_boards_compat_dt[] __initdata = { |
902 | "renesas,kzm9g", | |
903 | NULL, | |
904 | }; | |
905 | ||
906 | DT_MACHINE_START(KZM9G_DT, "kzm9g") | |
a62580e5 | 907 | .smp = smp_ops(sh73a0_smp_ops), |
9b93e244 KM |
908 | .map_io = sh73a0_map_io, |
909 | .init_early = sh73a0_add_early_devices, | |
910 | .nr_irqs = NR_IRQS_LEGACY, | |
911 | .init_irq = sh73a0_init_irq, | |
9b93e244 | 912 | .init_machine = kzm_init, |
14dd52f4 | 913 | .init_late = shmobile_init_late, |
6bb27d73 | 914 | .init_time = sh73a0_earlytimer_init, |
7952717a | 915 | .restart = kzm9g_restart, |
7296d932 | 916 | .dt_compat = kzm9g_boards_compat_dt, |
9b93e244 | 917 | MACHINE_END |