diff options
Diffstat (limited to 'drivers/mfd/tc6393xb.c')
-rw-r--r-- | drivers/mfd/tc6393xb.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 6197db7d4859..f856e9463a9f 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -114,6 +114,7 @@ enum { | |||
114 | TC6393XB_CELL_NAND, | 114 | TC6393XB_CELL_NAND, |
115 | TC6393XB_CELL_MMC, | 115 | TC6393XB_CELL_MMC, |
116 | TC6393XB_CELL_OHCI, | 116 | TC6393XB_CELL_OHCI, |
117 | TC6393XB_CELL_FB, | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /*--------------------------------------------------------------------------*/ | 120 | /*--------------------------------------------------------------------------*/ |
@@ -199,6 +200,29 @@ const static struct resource tc6393xb_ohci_resources[] = { | |||
199 | }, | 200 | }, |
200 | }; | 201 | }; |
201 | 202 | ||
203 | static struct resource __devinitdata tc6393xb_fb_resources[] = { | ||
204 | { | ||
205 | .start = 0x5000, | ||
206 | .end = 0x51ff, | ||
207 | .flags = IORESOURCE_MEM, | ||
208 | }, | ||
209 | { | ||
210 | .start = 0x0500, | ||
211 | .end = 0x05ff, | ||
212 | .flags = IORESOURCE_MEM, | ||
213 | }, | ||
214 | { | ||
215 | .start = 0x100000, | ||
216 | .end = 0x1fffff, | ||
217 | .flags = IORESOURCE_MEM, | ||
218 | }, | ||
219 | { | ||
220 | .start = IRQ_TC6393_FB, | ||
221 | .end = IRQ_TC6393_FB, | ||
222 | .flags = IORESOURCE_IRQ, | ||
223 | }, | ||
224 | }; | ||
225 | |||
202 | static int tc6393xb_ohci_enable(struct platform_device *dev) | 226 | static int tc6393xb_ohci_enable(struct platform_device *dev) |
203 | { | 227 | { |
204 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | 228 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); |
@@ -243,6 +267,81 @@ static int tc6393xb_ohci_disable(struct platform_device *dev) | |||
243 | return 0; | 267 | return 0; |
244 | } | 268 | } |
245 | 269 | ||
270 | static int tc6393xb_fb_enable(struct platform_device *dev) | ||
271 | { | ||
272 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
273 | unsigned long flags; | ||
274 | u16 ccr; | ||
275 | |||
276 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
277 | |||
278 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
279 | ccr &= ~SCR_CCR_MCLK_MASK; | ||
280 | ccr |= SCR_CCR_MCLK_48; | ||
281 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
282 | |||
283 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static int tc6393xb_fb_disable(struct platform_device *dev) | ||
289 | { | ||
290 | struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); | ||
291 | unsigned long flags; | ||
292 | u16 ccr; | ||
293 | |||
294 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
295 | |||
296 | ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); | ||
297 | ccr &= ~SCR_CCR_MCLK_MASK; | ||
298 | ccr |= SCR_CCR_MCLK_OFF; | ||
299 | tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); | ||
300 | |||
301 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) | ||
307 | { | ||
308 | struct platform_device *dev = to_platform_device(fb->dev.parent); | ||
309 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
310 | u8 fer; | ||
311 | unsigned long flags; | ||
312 | |||
313 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
314 | |||
315 | fer = ioread8(tc6393xb->scr + SCR_FER); | ||
316 | if (on) | ||
317 | fer |= SCR_FER_SLCDEN; | ||
318 | else | ||
319 | fer &= ~SCR_FER_SLCDEN; | ||
320 | iowrite8(fer, tc6393xb->scr + SCR_FER); | ||
321 | |||
322 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
323 | |||
324 | return 0; | ||
325 | } | ||
326 | EXPORT_SYMBOL(tc6393xb_lcd_set_power); | ||
327 | |||
328 | int tc6393xb_lcd_mode(struct platform_device *fb, | ||
329 | const struct fb_videomode *mode) { | ||
330 | struct platform_device *dev = to_platform_device(fb->dev.parent); | ||
331 | struct tc6393xb *tc6393xb = platform_get_drvdata(dev); | ||
332 | unsigned long flags; | ||
333 | |||
334 | spin_lock_irqsave(&tc6393xb->lock, flags); | ||
335 | |||
336 | iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); | ||
337 | iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); | ||
338 | |||
339 | spin_unlock_irqrestore(&tc6393xb->lock, flags); | ||
340 | |||
341 | return 0; | ||
342 | } | ||
343 | EXPORT_SYMBOL(tc6393xb_lcd_mode); | ||
344 | |||
246 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { | 345 | static struct mfd_cell __devinitdata tc6393xb_cells[] = { |
247 | [TC6393XB_CELL_NAND] = { | 346 | [TC6393XB_CELL_NAND] = { |
248 | .name = "tmio-nand", | 347 | .name = "tmio-nand", |
@@ -264,6 +363,15 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { | |||
264 | .resume = tc6393xb_ohci_enable, | 363 | .resume = tc6393xb_ohci_enable, |
265 | .disable = tc6393xb_ohci_disable, | 364 | .disable = tc6393xb_ohci_disable, |
266 | }, | 365 | }, |
366 | [TC6393XB_CELL_FB] = { | ||
367 | .name = "tmio-fb", | ||
368 | .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), | ||
369 | .resources = tc6393xb_fb_resources, | ||
370 | .enable = tc6393xb_fb_enable, | ||
371 | .suspend = tc6393xb_fb_disable, | ||
372 | .resume = tc6393xb_fb_enable, | ||
373 | .disable = tc6393xb_fb_disable, | ||
374 | }, | ||
267 | }; | 375 | }; |
268 | 376 | ||
269 | /*--------------------------------------------------------------------------*/ | 377 | /*--------------------------------------------------------------------------*/ |
@@ -547,6 +655,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
547 | &tc6393xb_cells[TC6393XB_CELL_NAND]; | 655 | &tc6393xb_cells[TC6393XB_CELL_NAND]; |
548 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = | 656 | tc6393xb_cells[TC6393XB_CELL_NAND].data_size = |
549 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); | 657 | sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); |
658 | |||
550 | tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = | 659 | tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = |
551 | &tc6393xb_cells[TC6393XB_CELL_MMC]; | 660 | &tc6393xb_cells[TC6393XB_CELL_MMC]; |
552 | tc6393xb_cells[TC6393XB_CELL_MMC].data_size = | 661 | tc6393xb_cells[TC6393XB_CELL_MMC].data_size = |
@@ -557,6 +666,11 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
557 | tc6393xb_cells[TC6393XB_CELL_OHCI].data_size = | 666 | tc6393xb_cells[TC6393XB_CELL_OHCI].data_size = |
558 | sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]); | 667 | sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]); |
559 | 668 | ||
669 | tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data; | ||
670 | tc6393xb_cells[TC6393XB_CELL_FB].platform_data = | ||
671 | &tc6393xb_cells[TC6393XB_CELL_FB]; | ||
672 | tc6393xb_cells[TC6393XB_CELL_FB].data_size = | ||
673 | sizeof(tc6393xb_cells[TC6393XB_CELL_FB]); | ||
560 | 674 | ||
561 | ret = mfd_add_devices(&dev->dev, dev->id, | 675 | ret = mfd_add_devices(&dev->dev, dev->id, |
562 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 676 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |