Commit 9e78cfe5 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Samuel Ortiz

mfd: support tmiofb cell on tc6393xb

Add support for tmiofb cell found in tc6393xb chip.
Signed-off-by: default avatarDmitry Baryshkov <dbaryshkov@gmail.com>
Cc: Ian Molton <spyro@f2s.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@openedhand.com>
parent 51a55623
...@@ -114,6 +114,7 @@ enum { ...@@ -114,6 +114,7 @@ enum {
TC6393XB_CELL_NAND, TC6393XB_CELL_NAND,
TC6393XB_CELL_MMC, TC6393XB_CELL_MMC,
TC6393XB_CELL_OHCI, TC6393XB_CELL_OHCI,
TC6393XB_CELL_FB,
}; };
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -199,6 +200,29 @@ const static struct resource tc6393xb_ohci_resources[] = { ...@@ -199,6 +200,29 @@ const static struct resource tc6393xb_ohci_resources[] = {
}, },
}; };
static struct resource __devinitdata tc6393xb_fb_resources[] = {
{
.start = 0x5000,
.end = 0x51ff,
.flags = IORESOURCE_MEM,
},
{
.start = 0x0500,
.end = 0x05ff,
.flags = IORESOURCE_MEM,
},
{
.start = 0x100000,
.end = 0x1fffff,
.flags = IORESOURCE_MEM,
},
{
.start = IRQ_TC6393_FB,
.end = IRQ_TC6393_FB,
.flags = IORESOURCE_IRQ,
},
};
static int tc6393xb_ohci_enable(struct platform_device *dev) static int tc6393xb_ohci_enable(struct platform_device *dev)
{ {
struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent); struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
...@@ -243,6 +267,81 @@ static int tc6393xb_ohci_disable(struct platform_device *dev) ...@@ -243,6 +267,81 @@ static int tc6393xb_ohci_disable(struct platform_device *dev)
return 0; return 0;
} }
static int tc6393xb_fb_enable(struct platform_device *dev)
{
struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
unsigned long flags;
u16 ccr;
spin_lock_irqsave(&tc6393xb->lock, flags);
ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
ccr &= ~SCR_CCR_MCLK_MASK;
ccr |= SCR_CCR_MCLK_48;
tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
static int tc6393xb_fb_disable(struct platform_device *dev)
{
struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
unsigned long flags;
u16 ccr;
spin_lock_irqsave(&tc6393xb->lock, flags);
ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
ccr &= ~SCR_CCR_MCLK_MASK;
ccr |= SCR_CCR_MCLK_OFF;
tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
{
struct platform_device *dev = to_platform_device(fb->dev.parent);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
u8 fer;
unsigned long flags;
spin_lock_irqsave(&tc6393xb->lock, flags);
fer = ioread8(tc6393xb->scr + SCR_FER);
if (on)
fer |= SCR_FER_SLCDEN;
else
fer &= ~SCR_FER_SLCDEN;
iowrite8(fer, tc6393xb->scr + SCR_FER);
spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
EXPORT_SYMBOL(tc6393xb_lcd_set_power);
int tc6393xb_lcd_mode(struct platform_device *fb,
const struct fb_videomode *mode) {
struct platform_device *dev = to_platform_device(fb->dev.parent);
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
unsigned long flags;
spin_lock_irqsave(&tc6393xb->lock, flags);
iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
spin_unlock_irqrestore(&tc6393xb->lock, flags);
return 0;
}
EXPORT_SYMBOL(tc6393xb_lcd_mode);
static struct mfd_cell __devinitdata tc6393xb_cells[] = { static struct mfd_cell __devinitdata tc6393xb_cells[] = {
[TC6393XB_CELL_NAND] = { [TC6393XB_CELL_NAND] = {
.name = "tmio-nand", .name = "tmio-nand",
...@@ -264,6 +363,15 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = { ...@@ -264,6 +363,15 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
.resume = tc6393xb_ohci_enable, .resume = tc6393xb_ohci_enable,
.disable = tc6393xb_ohci_disable, .disable = tc6393xb_ohci_disable,
}, },
[TC6393XB_CELL_FB] = {
.name = "tmio-fb",
.num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
.resources = tc6393xb_fb_resources,
.enable = tc6393xb_fb_enable,
.suspend = tc6393xb_fb_disable,
.resume = tc6393xb_fb_enable,
.disable = tc6393xb_fb_disable,
},
}; };
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
...@@ -547,6 +655,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) ...@@ -547,6 +655,7 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
&tc6393xb_cells[TC6393XB_CELL_NAND]; &tc6393xb_cells[TC6393XB_CELL_NAND];
tc6393xb_cells[TC6393XB_CELL_NAND].data_size = tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]); sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]);
tc6393xb_cells[TC6393XB_CELL_MMC].platform_data = tc6393xb_cells[TC6393XB_CELL_MMC].platform_data =
&tc6393xb_cells[TC6393XB_CELL_MMC]; &tc6393xb_cells[TC6393XB_CELL_MMC];
tc6393xb_cells[TC6393XB_CELL_MMC].data_size = tc6393xb_cells[TC6393XB_CELL_MMC].data_size =
...@@ -557,6 +666,11 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) ...@@ -557,6 +666,11 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
tc6393xb_cells[TC6393XB_CELL_OHCI].data_size = tc6393xb_cells[TC6393XB_CELL_OHCI].data_size =
sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]); sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]);
tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data;
tc6393xb_cells[TC6393XB_CELL_FB].platform_data =
&tc6393xb_cells[TC6393XB_CELL_FB];
tc6393xb_cells[TC6393XB_CELL_FB].data_size =
sizeof(tc6393xb_cells[TC6393XB_CELL_FB]);
ret = mfd_add_devices(&dev->dev, dev->id, ret = mfd_add_devices(&dev->dev, dev->id,
tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#ifndef MFD_TC6393XB_H #ifndef MFD_TC6393XB_H
#define MFD_TC6393XB_H #define MFD_TC6393XB_H
#include <linux/fb.h>
/* Also one should provide the CK3P6MI clock */ /* Also one should provide the CK3P6MI clock */
struct tc6393xb_platform_data { struct tc6393xb_platform_data {
u16 scr_pll2cr; /* PLL2 Control */ u16 scr_pll2cr; /* PLL2 Control */
...@@ -33,18 +35,24 @@ struct tc6393xb_platform_data { ...@@ -33,18 +35,24 @@ struct tc6393xb_platform_data {
void (*teardown)(struct platform_device *dev); void (*teardown)(struct platform_device *dev);
struct tmio_nand_data *nand_data; struct tmio_nand_data *nand_data;
struct tmio_fb_data *fb_data;
unsigned resume_restore : 1; /* make special actions unsigned resume_restore : 1; /* make special actions
to preserve the state to preserve the state
on suspend/resume */ on suspend/resume */
}; };
extern int tc6393xb_lcd_mode(struct platform_device *fb,
const struct fb_videomode *mode);
extern int tc6393xb_lcd_set_power(struct platform_device *fb, bool on);
/* /*
* Relative to irq_base * Relative to irq_base
*/ */
#define IRQ_TC6393_NAND 0 #define IRQ_TC6393_NAND 0
#define IRQ_TC6393_MMC 1 #define IRQ_TC6393_MMC 1
#define IRQ_TC6393_OHCI 2 #define IRQ_TC6393_OHCI 2
#define IRQ_TC6393_FB 4
#define TC6393XB_NR_IRQS 8 #define TC6393XB_NR_IRQS 8
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment