Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: support tmiofb cell on tc6393xb

Add support for tmiofb cell found in tc6393xb chip.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Cc: Ian Molton <spyro@f2s.com>
Signed-off-by: Samuel Ortiz <sameo@openedhand.com>

authored by

Dmitry Baryshkov and committed by
Samuel Ortiz
9e78cfe5 51a55623

+122
+114
drivers/mfd/tc6393xb.c
··· 114 114 TC6393XB_CELL_NAND, 115 115 TC6393XB_CELL_MMC, 116 116 TC6393XB_CELL_OHCI, 117 + TC6393XB_CELL_FB, 117 118 }; 118 119 119 120 /*--------------------------------------------------------------------------*/ ··· 200 199 }, 201 200 }; 202 201 202 + static struct resource __devinitdata tc6393xb_fb_resources[] = { 203 + { 204 + .start = 0x5000, 205 + .end = 0x51ff, 206 + .flags = IORESOURCE_MEM, 207 + }, 208 + { 209 + .start = 0x0500, 210 + .end = 0x05ff, 211 + .flags = IORESOURCE_MEM, 212 + }, 213 + { 214 + .start = 0x100000, 215 + .end = 0x1fffff, 216 + .flags = IORESOURCE_MEM, 217 + }, 218 + { 219 + .start = IRQ_TC6393_FB, 220 + .end = IRQ_TC6393_FB, 221 + .flags = IORESOURCE_IRQ, 222 + }, 223 + }; 224 + 203 225 static int tc6393xb_ohci_enable(struct platform_device *dev) 204 226 { 205 227 struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); ··· 267 243 return 0; 268 244 } 269 245 246 + static int tc6393xb_fb_enable(struct platform_device *dev) 247 + { 248 + struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 249 + unsigned long flags; 250 + u16 ccr; 251 + 252 + spin_lock_irqsave(&tc6393xb->lock, flags); 253 + 254 + ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 255 + ccr &= ~SCR_CCR_MCLK_MASK; 256 + ccr |= SCR_CCR_MCLK_48; 257 + tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 258 + 259 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 260 + 261 + return 0; 262 + } 263 + 264 + static int tc6393xb_fb_disable(struct platform_device *dev) 265 + { 266 + struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); 267 + unsigned long flags; 268 + u16 ccr; 269 + 270 + spin_lock_irqsave(&tc6393xb->lock, flags); 271 + 272 + ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR); 273 + ccr &= ~SCR_CCR_MCLK_MASK; 274 + ccr |= SCR_CCR_MCLK_OFF; 275 + tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR); 276 + 277 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 278 + 279 + return 0; 280 + } 281 + 282 + int tc6393xb_lcd_set_power(struct platform_device *fb, bool on) 283 + { 284 + struct platform_device *dev = to_platform_device(fb->dev.parent); 285 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 286 + u8 fer; 287 + unsigned long flags; 288 + 289 + spin_lock_irqsave(&tc6393xb->lock, flags); 290 + 291 + fer = ioread8(tc6393xb->scr + SCR_FER); 292 + if (on) 293 + fer |= SCR_FER_SLCDEN; 294 + else 295 + fer &= ~SCR_FER_SLCDEN; 296 + iowrite8(fer, tc6393xb->scr + SCR_FER); 297 + 298 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 299 + 300 + return 0; 301 + } 302 + EXPORT_SYMBOL(tc6393xb_lcd_set_power); 303 + 304 + int tc6393xb_lcd_mode(struct platform_device *fb, 305 + const struct fb_videomode *mode) { 306 + struct platform_device *dev = to_platform_device(fb->dev.parent); 307 + struct tc6393xb *tc6393xb = platform_get_drvdata(dev); 308 + unsigned long flags; 309 + 310 + spin_lock_irqsave(&tc6393xb->lock, flags); 311 + 312 + iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0); 313 + iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2); 314 + 315 + spin_unlock_irqrestore(&tc6393xb->lock, flags); 316 + 317 + return 0; 318 + } 319 + EXPORT_SYMBOL(tc6393xb_lcd_mode); 320 + 270 321 static struct mfd_cell __devinitdata tc6393xb_cells[] = { 271 322 [TC6393XB_CELL_NAND] = { 272 323 .name = "tmio-nand", ··· 362 263 .suspend = tc6393xb_ohci_disable, 363 264 .resume = tc6393xb_ohci_enable, 364 265 .disable = tc6393xb_ohci_disable, 266 + }, 267 + [TC6393XB_CELL_FB] = { 268 + .name = "tmio-fb", 269 + .num_resources = ARRAY_SIZE(tc6393xb_fb_resources), 270 + .resources = tc6393xb_fb_resources, 271 + .enable = tc6393xb_fb_enable, 272 + .suspend = tc6393xb_fb_disable, 273 + .resume = tc6393xb_fb_enable, 274 + .disable = tc6393xb_fb_disable, 365 275 }, 366 276 }; 367 277 ··· 655 547 &tc6393xb_cells[TC6393XB_CELL_NAND]; 656 548 tc6393xb_cells[TC6393XB_CELL_NAND].data_size = 657 549 sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); 550 + 658 551 tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = 659 552 &tc6393xb_cells[TC6393XB_CELL_MMC]; 660 553 tc6393xb_cells[TC6393XB_CELL_MMC].data_size = ··· 666 557 tc6393xb_cells[TC6393XB_CELL_OHCI].data_size = 667 558 sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]); 668 559 560 + tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data; 561 + tc6393xb_cells[TC6393XB_CELL_FB].platform_data = 562 + &tc6393xb_cells[TC6393XB_CELL_FB]; 563 + tc6393xb_cells[TC6393XB_CELL_FB].data_size = 564 + sizeof(tc6393xb_cells[TC6393XB_CELL_FB]); 669 565 670 566 ret = mfd_add_devices(&dev->dev, dev->id, 671 567 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
+8
include/linux/mfd/tc6393xb.h
··· 17 17 #ifndef MFD_TC6393XB_H 18 18 #define MFD_TC6393XB_H 19 19 20 + #include <linux/fb.h> 21 + 20 22 /* Also one should provide the CK3P6MI clock */ 21 23 struct tc6393xb_platform_data { 22 24 u16 scr_pll2cr; /* PLL2 Control */ ··· 35 33 void (*teardown)(struct platform_device *dev); 36 34 37 35 struct tmio_nand_data *nand_data; 36 + struct tmio_fb_data *fb_data; 38 37 39 38 unsigned resume_restore : 1; /* make special actions 40 39 to preserve the state 41 40 on suspend/resume */ 42 41 }; 42 + 43 + extern int tc6393xb_lcd_mode(struct platform_device *fb, 44 + const struct fb_videomode *mode); 45 + extern int tc6393xb_lcd_set_power(struct platform_device *fb, bool on); 43 46 44 47 /* 45 48 * Relative to irq_base ··· 52 45 #define IRQ_TC6393_NAND 0 53 46 #define IRQ_TC6393_MMC 1 54 47 #define IRQ_TC6393_OHCI 2 48 + #define IRQ_TC6393_FB 4 55 49 56 50 #define TC6393XB_NR_IRQS 8 57 51