Merge branches 'defcfg', 'drivers' and 'cyberpro-next' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'defcfg' of master.kernel.org:/home/rmk/linux-2.6-arm:
  ARM: 6647/1: add Versatile Express defconfig
  ARM: 6644/1: mach-ux500: update the U8500 defconfig

* 'drivers' of master.kernel.org:/home/rmk/linux-2.6-arm:
  ARM: 6764/1: pl011: factor out FIFO to TTY code
  ARM: 6763/1: pl011: add optional RX DMA to PL011 v2
  ARM: 6758/1: amba: support pm ops
  ARM: amba: make amba_driver id_table const
  ARM: amba: make internal ID table handling const
  ARM: amba: make probe() functions take const id tables
  ARM: 6662/1: amba: make amba_bustype non-static
  ARM: mmci: add dmaengine-based DMA support
  ARM: mmci: no need for separate host->data_xfered
  ARM: mmci: avoid unnecessary switch to data available PIO interrupts
  ARM: mmci: no need to call flush_dcache_page() with sg_miter API
  ARM: mmci: avoid reporting too many completed bytes on fifo overrun
  ALSA: AACI: make fifo variables more explanitory
  ALSA: AACI: no need to call snd_pcm_period_elapsed() for each period
  ALSA: AACI: use snd_pcm_lib_period_bytes()
  ALSA: AACI: clean up AACI announcement printk
  ALSA: AACI: fix channel mask selection
  ALSA: AACI: fix number of channels for record
  ALSA: AACI: fix multiple IRQ claiming

* 'cyberpro-next' of master.kernel.org:/home/rmk/linux-2.6-arm:
  VIDEO: cyberpro: remove unused cyber2000fb_get_fb_var()
  VIDEO: cyberpro: remove useless function extreg pointers
  VIDEO: cyberpro: update handling of device structures
  VIDEO: cyberpro: add support for video capture I2C
  VIDEO: cyberpro: make 'reg_b0_lock' always present
  VIDEO: cyberpro: add I2C support
  VIDEO: cyberpro: select lowest multipler/divisor for PLL
This commit is contained in:
Linus Torvalds 2011-03-17 18:48:35 -07:00
25 changed files with 1710 additions and 356 deletions

View file

@ -376,6 +376,24 @@ config FB_CYBER2000
Say Y if you have a NetWinder or a graphics card containing this
device, otherwise say N.
config FB_CYBER2000_DDC
bool "DDC for CyberPro support"
depends on FB_CYBER2000
select FB_DDC
default y
help
Say Y here if you want DDC support for your CyberPro graphics
card. This is only I2C bus support, driver does not use EDID.
config FB_CYBER2000_I2C
bool "CyberPro 2000/2010/5000 I2C support"
depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
select I2C_ALGOBIT
help
Enable support for the I2C video decoder interface on the
Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
on the Netwinder machines for the SAA7111 video capture.
config FB_APOLLO
bool
depends on (FB = y) && APOLLO

View file

@ -461,7 +461,7 @@ static int clcdfb_register(struct clcd_fb *fb)
return ret;
}
static int clcdfb_probe(struct amba_device *dev, struct amba_id *id)
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct clcd_board *board = dev->dev.platform_data;
struct clcd_fb *fb;

View file

@ -47,6 +47,8 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@ -61,10 +63,10 @@ struct cfb_info {
struct fb_info fb;
struct display_switch *dispsw;
struct display *display;
struct pci_dev *dev;
unsigned char __iomem *region;
unsigned char __iomem *regs;
u_int id;
u_int irq;
int func_use_count;
u_long ref_ps;
@ -88,6 +90,19 @@ struct cfb_info {
u_char ramdac_powerdown;
u32 pseudo_palette[16];
spinlock_t reg_b0_lock;
#ifdef CONFIG_FB_CYBER2000_DDC
bool ddc_registered;
struct i2c_adapter ddc_adapter;
struct i2c_algo_bit_data ddc_algo;
#endif
#ifdef CONFIG_FB_CYBER2000_I2C
struct i2c_adapter i2c_adapter;
struct i2c_algo_bit_data i2c_algo;
#endif
};
static char *default_font = "Acorn8x8";
@ -494,6 +509,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
cyber2000_attrw(0x14, 0x00, cfb);
/* PLL registers */
spin_lock(&cfb->reg_b0_lock);
cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
@ -501,6 +517,7 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
cyber2000_grphw(0x90, 0x01, cfb);
cyber2000_grphw(0xb9, 0x80, cfb);
cyber2000_grphw(0xb9, 0x00, cfb);
spin_unlock(&cfb->reg_b0_lock);
cfb->ramdac_ctrl = hw->ramdac;
cyber2000fb_write_ramdac_ctrl(cfb);
@ -681,9 +698,9 @@ cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
* pll_ps_calc = best_div1 / (ref_ps * best_mult)
*/
best_diff = 0x7fffffff;
best_mult = 32;
best_div1 = 255;
for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) {
best_mult = 2;
best_div1 = 32;
for (t_div1 = 2; t_div1 < 32; t_div1 += 1) {
u_int rr, t_mult, t_pll_ps;
int diff;
@ -1105,24 +1122,22 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
}
EXPORT_SYMBOL(cyber2000fb_disable_extregs);
void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
{
memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
}
EXPORT_SYMBOL(cyber2000fb_get_fb_var);
/*
* Attach a capture/tv driver to the core CyberX0X0 driver.
*/
int cyber2000fb_attach(struct cyberpro_info *info, int idx)
{
if (int_cfb_info != NULL) {
info->dev = int_cfb_info->dev;
info->dev = int_cfb_info->fb.device;
#ifdef CONFIG_FB_CYBER2000_I2C
info->i2c = &int_cfb_info->i2c_adapter;
#else
info->i2c = NULL;
#endif
info->regs = int_cfb_info->regs;
info->irq = int_cfb_info->irq;
info->fb = int_cfb_info->fb.screen_base;
info->fb_size = int_cfb_info->fb.fix.smem_len;
info->enable_extregs = cyber2000fb_enable_extregs;
info->disable_extregs = cyber2000fb_disable_extregs;
info->info = int_cfb_info;
strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
@ -1141,6 +1156,183 @@ void cyber2000fb_detach(int idx)
}
EXPORT_SYMBOL(cyber2000fb_detach);
#ifdef CONFIG_FB_CYBER2000_DDC
#define DDC_REG 0xb0
#define DDC_SCL_OUT (1 << 0)
#define DDC_SDA_OUT (1 << 4)
#define DDC_SCL_IN (1 << 2)
#define DDC_SDA_IN (1 << 6)
static void cyber2000fb_enable_ddc(struct cfb_info *cfb)
{
spin_lock(&cfb->reg_b0_lock);
cyber2000fb_writew(0x1bf, 0x3ce, cfb);
}
static void cyber2000fb_disable_ddc(struct cfb_info *cfb)
{
cyber2000fb_writew(0x0bf, 0x3ce, cfb);
spin_unlock(&cfb->reg_b0_lock);
}
static void cyber2000fb_ddc_setscl(void *data, int val)
{
struct cfb_info *cfb = data;
unsigned char reg;
cyber2000fb_enable_ddc(cfb);
reg = cyber2000_grphr(DDC_REG, cfb);
if (!val) /* bit is inverted */
reg |= DDC_SCL_OUT;
else
reg &= ~DDC_SCL_OUT;
cyber2000_grphw(DDC_REG, reg, cfb);
cyber2000fb_disable_ddc(cfb);
}
static void cyber2000fb_ddc_setsda(void *data, int val)
{
struct cfb_info *cfb = data;
unsigned char reg;
cyber2000fb_enable_ddc(cfb);
reg = cyber2000_grphr(DDC_REG, cfb);
if (!val) /* bit is inverted */
reg |= DDC_SDA_OUT;
else
reg &= ~DDC_SDA_OUT;
cyber2000_grphw(DDC_REG, reg, cfb);
cyber2000fb_disable_ddc(cfb);
}
static int cyber2000fb_ddc_getscl(void *data)
{
struct cfb_info *cfb = data;
int retval;
cyber2000fb_enable_ddc(cfb);
retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SCL_IN);
cyber2000fb_disable_ddc(cfb);
return retval;
}
static int cyber2000fb_ddc_getsda(void *data)
{
struct cfb_info *cfb = data;
int retval;
cyber2000fb_enable_ddc(cfb);
retval = !!(cyber2000_grphr(DDC_REG, cfb) & DDC_SDA_IN);
cyber2000fb_disable_ddc(cfb);
return retval;
}
static int __devinit cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
{
strlcpy(cfb->ddc_adapter.name, cfb->fb.fix.id,
sizeof(cfb->ddc_adapter.name));
cfb->ddc_adapter.owner = THIS_MODULE;
cfb->ddc_adapter.class = I2C_CLASS_DDC;
cfb->ddc_adapter.algo_data = &cfb->ddc_algo;
cfb->ddc_adapter.dev.parent = cfb->fb.device;
cfb->ddc_algo.setsda = cyber2000fb_ddc_setsda;
cfb->ddc_algo.setscl = cyber2000fb_ddc_setscl;
cfb->ddc_algo.getsda = cyber2000fb_ddc_getsda;
cfb->ddc_algo.getscl = cyber2000fb_ddc_getscl;
cfb->ddc_algo.udelay = 10;
cfb->ddc_algo.timeout = 20;
cfb->ddc_algo.data = cfb;
i2c_set_adapdata(&cfb->ddc_adapter, cfb);
return i2c_bit_add_bus(&cfb->ddc_adapter);
}
#endif /* CONFIG_FB_CYBER2000_DDC */
#ifdef CONFIG_FB_CYBER2000_I2C
static void cyber2000fb_i2c_setsda(void *data, int state)
{
struct cfb_info *cfb = data;
unsigned int latch2;
spin_lock(&cfb->reg_b0_lock);
latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
latch2 &= EXT_LATCH2_I2C_CLKEN;
if (state)
latch2 |= EXT_LATCH2_I2C_DATEN;
cyber2000_grphw(EXT_LATCH2, latch2, cfb);
spin_unlock(&cfb->reg_b0_lock);
}
static void cyber2000fb_i2c_setscl(void *data, int state)
{
struct cfb_info *cfb = data;
unsigned int latch2;
spin_lock(&cfb->reg_b0_lock);
latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
latch2 &= EXT_LATCH2_I2C_DATEN;
if (state)
latch2 |= EXT_LATCH2_I2C_CLKEN;
cyber2000_grphw(EXT_LATCH2, latch2, cfb);
spin_unlock(&cfb->reg_b0_lock);
}
static int cyber2000fb_i2c_getsda(void *data)
{
struct cfb_info *cfb = data;
int ret;
spin_lock(&cfb->reg_b0_lock);
ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT);
spin_unlock(&cfb->reg_b0_lock);
return ret;
}
static int cyber2000fb_i2c_getscl(void *data)
{
struct cfb_info *cfb = data;
int ret;
spin_lock(&cfb->reg_b0_lock);
ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK);
spin_unlock(&cfb->reg_b0_lock);
return ret;
}
static int __devinit cyber2000fb_i2c_register(struct cfb_info *cfb)
{
strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
sizeof(cfb->i2c_adapter.name));
cfb->i2c_adapter.owner = THIS_MODULE;
cfb->i2c_adapter.algo_data = &cfb->i2c_algo;
cfb->i2c_adapter.dev.parent = cfb->fb.device;
cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda;
cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl;
cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda;
cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl;
cfb->i2c_algo.udelay = 5;
cfb->i2c_algo.timeout = msecs_to_jiffies(100);
cfb->i2c_algo.data = cfb;
return i2c_bit_add_bus(&cfb->i2c_adapter);
}
static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
{
i2c_del_adapter(&cfb->i2c_adapter);
}
#else
#define cyber2000fb_i2c_register(cfb) (0)
#define cyber2000fb_i2c_unregister(cfb) do { } while (0)
#endif
/*
* These parameters give
* 640x480, hsync 31.5kHz, vsync 60Hz
@ -1275,6 +1467,8 @@ static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
cfb->fb.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
cfb->fb.pseudo_palette = cfb->pseudo_palette;
spin_lock_init(&cfb->reg_b0_lock);
fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
return cfb;
@ -1369,6 +1563,11 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
cfb->fb.fix.mmio_len = MMIO_SIZE;
cfb->fb.screen_base = cfb->region;
#ifdef CONFIG_FB_CYBER2000_DDC
if (cyber2000fb_setup_ddc_bus(cfb) == 0)
cfb->ddc_registered = true;
#endif
err = -EINVAL;
if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
&cyber2000fb_default_mode, 8)) {
@ -1401,14 +1600,32 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
cfb->fb.var.xres, cfb->fb.var.yres,
h_sync / 1000, h_sync % 1000, v_sync);
if (cfb->dev)
cfb->fb.device = &cfb->dev->dev;
err = cyber2000fb_i2c_register(cfb);
if (err)
goto failed;
err = register_framebuffer(&cfb->fb);
if (err)
cyber2000fb_i2c_unregister(cfb);
failed:
#ifdef CONFIG_FB_CYBER2000_DDC
if (err && cfb->ddc_registered)
i2c_del_adapter(&cfb->ddc_adapter);
#endif
return err;
}
static void __devexit cyberpro_common_remove(struct cfb_info *cfb)
{
unregister_framebuffer(&cfb->fb);
#ifdef CONFIG_FB_CYBER2000_DDC
if (cfb->ddc_registered)
i2c_del_adapter(&cfb->ddc_adapter);
#endif
cyber2000fb_i2c_unregister(cfb);
}
static void cyberpro_common_resume(struct cfb_info *cfb)
{
cyberpro_init_hw(cfb);
@ -1442,12 +1659,13 @@ static int __devinit cyberpro_vl_probe(void)
if (!cfb)
goto failed_release;
cfb->dev = NULL;
cfb->irq = -1;
cfb->region = ioremap(FB_START, FB_SIZE);
if (!cfb->region)
goto failed_ioremap;
cfb->regs = cfb->region + MMIO_OFFSET;
cfb->fb.device = NULL;
cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
cfb->fb.fix.smem_start = FB_START;
@ -1585,12 +1803,13 @@ cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (err)
goto failed_regions;
cfb->dev = dev;
cfb->irq = dev->irq;
cfb->region = pci_ioremap_bar(dev, 0);
if (!cfb->region)
goto failed_ioremap;
cfb->regs = cfb->region + MMIO_OFFSET;
cfb->fb.device = &dev->dev;
cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
@ -1648,15 +1867,7 @@ static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
struct cfb_info *cfb = pci_get_drvdata(dev);
if (cfb) {
/*
* If unregister_framebuffer fails, then
* we will be leaving hooks that could cause
* oopsen laying around.
*/
if (unregister_framebuffer(&cfb->fb))
printk(KERN_WARNING "%s: danger Will Robinson, "
"danger danger! Oopsen imminent!\n",
cfb->fb.fix.id);
cyberpro_common_remove(cfb);
iounmap(cfb->region);
cyberpro_free_fb_info(cfb);

View file

@ -464,12 +464,14 @@ static void debug_printf(char *fmt, ...)
struct cfb_info;
struct cyberpro_info {
struct pci_dev *dev;
struct device *dev;
struct i2c_adapter *i2c;
unsigned char __iomem *regs;
char __iomem *fb;
char dev_name[32];
unsigned int fb_size;
unsigned int chip_id;
unsigned int irq;
/*
* The following is a pointer to be passed into the
@ -478,15 +480,6 @@ struct cyberpro_info {
* is within this structure.
*/
struct cfb_info *info;
/*
* Use these to enable the BM or TV registers. In an SMP
* environment, these two function pointers should only be
* called from the module_init() or module_exit()
* functions.
*/
void (*enable_extregs)(struct cfb_info *);
void (*disable_extregs)(struct cfb_info *);
};
#define ID_IGA_1682 0
@ -494,8 +487,6 @@ struct cyberpro_info {
#define ID_CYBERPRO_2010 2
#define ID_CYBERPRO_5000 3
struct fb_var_screeninfo;
/*
* Note! Writing to the Cyber20x0 registers from an interrupt
* routine is definitely a bad idea atm.
@ -504,4 +495,3 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx);
void cyber2000fb_detach(int idx);
void cyber2000fb_enable_extregs(struct cfb_info *cfb);
void cyber2000fb_disable_extregs(struct cfb_info *cfb);
void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var);