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