From e770e8506110a57c868bbef9706d132285c2090f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 3 Sep 2005 15:54:18 -0700 Subject: [PATCH] dvb: saa7134-dvb must select tda1004x Please apply this to 2.6.14, and also to 2.6.13.1 -stable. Without this patch, users will have to EXPLICITLY select tda1004x in Kconfig. This SHOULD be done automatically when saa7134-dvb is selected. This patch corrects this problem. Signed-off-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media/video') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 3f5742396096..16c85c081e6e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -254,6 +254,7 @@ config VIDEO_SAA7134_DVB select VIDEO_BUF_DVB select DVB_MT352 select DVB_CX22702 + select DVB_TDA1004X ---help--- This adds support for DVB cards based on the Philips saa7134 chip. -- cgit v1.2.3-55-g7522 From 829ca9a30a2ddb727981d80fabdbff2ea86bc9ea Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 3 Sep 2005 15:56:56 -0700 Subject: [PATCH] swsusp: fix remaining u32 vs. pm_message_t confusion Fix remaining bits of u32 vs. pm_message confusion. Should not break anything. Signed-off-by: Pavel Machek Signed-off-by: Rafael J. Wysocki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mtrr/main.c | 2 +- arch/ppc/platforms/pmac_pic.c | 2 +- arch/ppc/syslib/open_pic.c | 2 +- arch/x86_64/kernel/nmi.c | 2 +- drivers/ide/ppc/pmac.c | 8 ++++---- drivers/macintosh/mediabay.c | 2 +- drivers/media/video/bttv-driver.c | 1 - drivers/media/video/msp3400.c | 4 ++-- drivers/media/video/tda9887.c | 2 +- drivers/media/video/tuner-core.c | 2 +- drivers/net/bnx2.c | 18 +++++++++--------- drivers/net/e1000/e1000_main.c | 14 ++++++-------- drivers/net/irda/vlsi_ir.c | 11 +++-------- drivers/net/phy/mdio_bus.c | 2 +- drivers/net/wireless/orinoco_pci.c | 2 -- drivers/net/wireless/prism54/islpci_hotplug.c | 2 -- drivers/video/s1d13xxxfb.c | 2 +- drivers/video/savage/savagefb_driver.c | 1 - sound/pci/atiixp.c | 4 ++-- 19 files changed, 35 insertions(+), 48 deletions(-) (limited to 'drivers/media/video') diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 764cac64e211..dd4ebd6af7e4 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -561,7 +561,7 @@ struct mtrr_value { static struct mtrr_value * mtrr_state; -static int mtrr_save(struct sys_device * sysdev, u32 state) +static int mtrr_save(struct sys_device * sysdev, pm_message_t state) { int i; int size = num_var_ranges * sizeof(struct mtrr_value); diff --git a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c index 9f92e1bb7f34..2ce058895e03 100644 --- a/arch/ppc/platforms/pmac_pic.c +++ b/arch/ppc/platforms/pmac_pic.c @@ -619,7 +619,7 @@ not_found: return viaint; } -static int pmacpic_suspend(struct sys_device *sysdev, u32 state) +static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state) { int viaint = pmacpic_find_viaint(); diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index ad39b86ca92c..53da58523e39 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -948,7 +948,7 @@ static void openpic_cached_disable_irq(u_int irq) * we need something better to deal with that... Maybe switch to S1 for * cpufreq changes */ -int openpic_suspend(struct sys_device *sysdev, u32 state) +int openpic_suspend(struct sys_device *sysdev, pm_message_t state) { int i; unsigned long flags; diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 4e44d6e6b7e5..64a8e05d5811 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -290,7 +290,7 @@ void enable_timer_nmi_watchdog(void) static int nmi_pm_active; /* nmi_active before suspend */ -static int lapic_nmi_suspend(struct sys_device *dev, u32 state) +static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) { nmi_pm_active = nmi_active; disable_lapic_nmi_watchdog(); diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ea65b070a367..d2760b8ca159 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1504,7 +1504,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) } static int -pmac_ide_macio_suspend(struct macio_dev *mdev, u32 state) +pmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t state) { ide_hwif_t *hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev); int rc = 0; @@ -1527,7 +1527,7 @@ pmac_ide_macio_resume(struct macio_dev *mdev) if (mdev->ofdev.dev.power.power_state != 0) { rc = pmac_ide_do_resume(hwif); if (rc == 0) - mdev->ofdev.dev.power.power_state = 0; + mdev->ofdev.dev.power.power_state = PMSG_ON; } return rc; @@ -1608,7 +1608,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id) } static int -pmac_ide_pci_suspend(struct pci_dev *pdev, u32 state) +pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t state) { ide_hwif_t *hwif = (ide_hwif_t *)pci_get_drvdata(pdev); int rc = 0; @@ -1631,7 +1631,7 @@ pmac_ide_pci_resume(struct pci_dev *pdev) if (pdev->dev.power.power_state != 0) { rc = pmac_ide_do_resume(hwif); if (rc == 0) - pdev->dev.power.power_state = 0; + pdev->dev.power.power_state = PMSG_ON; } return rc; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 7c16c25fc5d4..7e1afca75e41 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -724,7 +724,7 @@ static int __pmac media_bay_resume(struct macio_dev *mdev) struct media_bay_info *bay = macio_get_drvdata(mdev); if (mdev->ofdev.dev.power.power_state != 0) { - mdev->ofdev.dev.power.power_state = 0; + mdev->ofdev.dev.power.power_state = PMSG_ON; /* We re-enable the bay using it's previous content only if it did not change. Note those bozo timings, diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index eee9322ce21b..087efb4dea09 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -4047,7 +4047,6 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) struct bttv_buffer_set idle; unsigned long flags; - dprintk("bttv%d: suspend %d\n", btv->c.nr, state); /* stop dma + irqs */ spin_lock_irqsave(&btv->s_lock,flags); diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index 62f1b8ddb98b..e956234abf24 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -1416,7 +1416,7 @@ static int msp_detach(struct i2c_client *client); static int msp_probe(struct i2c_adapter *adap); static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); -static int msp_suspend(struct device * dev, u32 state, u32 level); +static int msp_suspend(struct device * dev, pm_message_t state, u32 level); static int msp_resume(struct device * dev, u32 level); static void msp_wake_thread(struct i2c_client *client); @@ -1817,7 +1817,7 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int msp_suspend(struct device * dev, u32 state, u32 level) +static int msp_suspend(struct device * dev, pm_message_t state, u32 level) { struct i2c_client *c = container_of(dev, struct i2c_client, dev); diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 108c3ad7d622..a28a395d6dfe 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -760,7 +760,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tda9887_suspend(struct device * dev, u32 state, u32 level) +static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level) { dprintk("tda9887: suspend\n"); return 0; diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index f0a579827a24..a155e99a263b 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -672,7 +672,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) return 0; } -static int tuner_suspend(struct device *dev, u32 state, u32 level) +static int tuner_suspend(struct device *dev, pm_message_t state, u32 level) { struct i2c_client *c = container_of (dev, struct i2c_client, dev); struct tuner *t = i2c_get_clientdata (c); diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7babf6af4e28..55a72c7ad001 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -2004,14 +2004,14 @@ bnx2_init_cpus(struct bnx2 *bp) } static int -bnx2_set_power_state(struct bnx2 *bp, int state) +bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) { u16 pmcsr; pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); switch (state) { - case 0: { + case PCI_D0: { u32 val; pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, @@ -2032,7 +2032,7 @@ bnx2_set_power_state(struct bnx2 *bp, int state) REG_WR(bp, BNX2_RPM_CONFIG, val); break; } - case 3: { + case PCI_D3hot: { int i; u32 val, wol_msg; @@ -3886,7 +3886,7 @@ bnx2_open(struct net_device *dev) struct bnx2 *bp = dev->priv; int rc; - bnx2_set_power_state(bp, 0); + bnx2_set_power_state(bp, PCI_D0); bnx2_disable_int(bp); rc = bnx2_alloc_mem(bp); @@ -4197,7 +4197,7 @@ bnx2_close(struct net_device *dev) bnx2_free_mem(bp); bp->link_up = 0; netif_carrier_off(bp->dev); - bnx2_set_power_state(bp, 3); + bnx2_set_power_state(bp, PCI_D3hot); return 0; } @@ -5203,7 +5203,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); - bnx2_set_power_state(bp, 0); + bnx2_set_power_state(bp, PCI_D0); bp->chip_id = REG_RD(bp, BNX2_MISC_ID); @@ -5495,7 +5495,7 @@ bnx2_remove_one(struct pci_dev *pdev) } static int -bnx2_suspend(struct pci_dev *pdev, u32 state) +bnx2_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = dev->priv; @@ -5513,7 +5513,7 @@ bnx2_suspend(struct pci_dev *pdev, u32 state) reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; bnx2_reset_chip(bp, reset_code); bnx2_free_skbs(bp); - bnx2_set_power_state(bp, state); + bnx2_set_power_state(bp, pci_choose_state(pdev, state)); return 0; } @@ -5526,7 +5526,7 @@ bnx2_resume(struct pci_dev *pdev) if (!netif_running(dev)) return 0; - bnx2_set_power_state(bp, 0); + bnx2_set_power_state(bp, PCI_D0); netif_device_attach(dev); bnx2_init_nic(bp); bnx2_netif_start(bp); diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 9b596e0bbf95..7c8a0a22dcd5 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -162,7 +162,7 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void e1000_restore_vlan(struct e1000_adapter *adapter); -static int e1000_suspend(struct pci_dev *pdev, uint32_t state); +static int e1000_suspend(struct pci_dev *pdev, pm_message_t state); #ifdef CONFIG_PM static int e1000_resume(struct pci_dev *pdev); #endif @@ -3642,7 +3642,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) } static int -e1000_suspend(struct pci_dev *pdev, uint32_t state) +e1000_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -3726,9 +3726,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) } pci_disable_device(pdev); - - state = (state > 0) ? 3 : 0; - pci_set_power_state(pdev, state); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -3741,13 +3739,13 @@ e1000_resume(struct pci_dev *pdev) struct e1000_adapter *adapter = netdev_priv(netdev); uint32_t manc, ret_val, swsm; - pci_set_power_state(pdev, 0); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); ret_val = pci_enable_device(pdev); pci_set_master(pdev); - pci_enable_wake(pdev, 3, 0); - pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 006e4f575606..4be95398bac4 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -1749,11 +1749,6 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) struct net_device *ndev = pci_get_drvdata(pdev); vlsi_irda_dev_t *idev; - if (state < 1 || state > 3 ) { - IRDA_ERROR("%s - %s: invalid pm state request: %u\n", - __FUNCTION__, PCIDEV_NAME(pdev), state); - return 0; - } if (!ndev) { IRDA_ERROR("%s - %s: no netdevice \n", __FUNCTION__, PCIDEV_NAME(pdev)); @@ -1781,7 +1776,7 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, pm_message_t state) idev->new_baud = idev->baud; } - pci_set_power_state(pdev,state); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); pdev->current_state = state; idev->resume_ok = 1; up(&idev->sem); @@ -1807,8 +1802,8 @@ static int vlsi_irda_resume(struct pci_dev *pdev) return 0; } - pci_set_power_state(pdev, 0); - pdev->current_state = 0; + pci_set_power_state(pdev, PCI_D0); + pdev->current_state = PM_EVENT_ON; if (!idev->resume_ok) { /* should be obsolete now - but used to happen due to: diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 41f62c0c5fcb..5e81494e9a9a 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -128,7 +128,7 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv) /* Suspend and resume. Copied from platform_suspend and * platform_resume */ -static int mdio_bus_suspend(struct device * dev, u32 state) +static int mdio_bus_suspend(struct device * dev, pm_message_t state) { int ret = 0; struct device_driver *drv = dev->driver; diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c index 7a6f52ea7faa..42e03438291b 100644 --- a/drivers/net/wireless/orinoco_pci.c +++ b/drivers/net/wireless/orinoco_pci.c @@ -301,8 +301,6 @@ static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) unsigned long flags; int err; - printk(KERN_DEBUG "%s: Orinoco-PCI entering sleep mode (state=%d)\n", - dev->name, state); err = orinoco_lock(priv, &flags); if (err) { diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index c17391d947f3..dc040caab7d7 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c @@ -267,8 +267,6 @@ prism54_suspend(struct pci_dev *pdev, pm_message_t state) islpci_private *priv = ndev ? netdev_priv(ndev) : NULL; BUG_ON(!priv); - printk(KERN_NOTICE "%s: got suspend request (state %d)\n", - ndev->name, state); pci_save_state(pdev); diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c index 3848be2b9d2d..fa98d91c42eb 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/s1d13xxxfb.c @@ -655,7 +655,7 @@ bail: } #ifdef CONFIG_PM -static int s1d13xxxfb_suspend(struct device *dev, u32 state, u32 level) +static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level) { struct fb_info *info = dev_get_drvdata(dev); struct s1d13xxxfb_par *s1dfb = info->par; diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index f4633d1891f1..117ad42f120d 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -2110,7 +2110,6 @@ static int savagefb_suspend (struct pci_dev* dev, pm_message_t state) struct savagefb_par *par = (struct savagefb_par *)info->par; DBG("savagefb_suspend"); - printk(KERN_DEBUG "state: %u\n", state); acquire_console_sem(); fb_set_suspend(info, pci_choose_state(dev, state)); diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 904d17394e1c..188df085b7ee 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1427,7 +1427,7 @@ static int snd_atiixp_suspend(snd_card_t *card, pm_message_t state) snd_atiixp_aclink_down(chip); snd_atiixp_chip_stop(chip); - pci_set_power_state(chip->pci, 3); + pci_set_power_state(chip->pci, PCI_D3hot); pci_disable_device(chip->pci); return 0; } @@ -1438,7 +1438,7 @@ static int snd_atiixp_resume(snd_card_t *card) int i; pci_enable_device(chip->pci); - pci_set_power_state(chip->pci, 0); + pci_set_power_state(chip->pci, PCI_D0); pci_set_master(chip->pci); snd_atiixp_aclink_reset(chip); -- cgit v1.2.3-55-g7522 From 9fc6adfa9adf2be84119a3c2592287f33bd1dff2 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 31 Jul 2005 21:20:43 +0200 Subject: [PATCH] hwmon: hwmon vs i2c, second round (01/11) Add support for kind-forced addresses to i2c_probe, like i2c_detect has for (essentially) hardware monitoring drivers. Note that this change will slightly increase the size of the drivers using I2C_CLIENT_INSMOD, with no immediate benefit. This is a requirement if we want to merge i2c_probe and i2c_detect though, and seems a reasonable price to pay in comparison with the previous cleanups which saved much more than that (such as the i2c-isa cleanup or the i2c address ranges removal.) Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/chips/ds1374.c | 1 - drivers/i2c/chips/m41t00.c | 1 - drivers/i2c/chips/rtc8564.c | 1 - drivers/i2c/i2c-core.c | 38 ++++++++++++++++++++++++++++---------- drivers/media/video/adv7170.c | 1 - drivers/media/video/adv7175.c | 1 - drivers/media/video/bt819.c | 1 - drivers/media/video/bt856.c | 1 - drivers/media/video/saa7110.c | 1 - drivers/media/video/saa7111.c | 1 - drivers/media/video/saa7114.c | 1 - drivers/media/video/saa7185.c | 1 - drivers/media/video/tuner-3036.c | 1 - drivers/media/video/vpx3220.c | 1 - include/linux/i2c.h | 9 ++++++--- 15 files changed, 34 insertions(+), 26 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index a445736d8838..e2d1daf79880 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c @@ -53,7 +53,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, .probe = ignore, .ignore = ignore, - .force = ignore, }; static ulong ds1374_read_rtc(void) diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 778d7e12859d..e516dadc453f 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c @@ -42,7 +42,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, .probe = ignore, .ignore = ignore, - .force = ignore, }; ulong diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index 588fc2261a91..0b5385c892b1 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c @@ -67,7 +67,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_addr, .probe = ignore, .ignore = ignore, - .force = ignore, }; static int rtc8564_read_mem(struct i2c_client *client, struct mem *mem); diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 19d8a994b3b7..372b5996d045 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -662,6 +662,28 @@ int i2c_control(struct i2c_client *client, * Will not work for 10-bit addresses! * ---------------------------------------------------- */ +/* Return: kind (>= 0) if force found, -1 if not found */ +static inline int i2c_probe_forces(struct i2c_adapter *adapter, int addr, + unsigned short **forces) +{ + unsigned short kind; + int j, adap_id = i2c_adapter_id(adapter); + + for (kind = 0; forces[kind]; kind++) { + for (j = 0; forces[kind][j] != I2C_CLIENT_END; j += 2) { + if ((forces[kind][j] == adap_id || + forces[kind][j] == ANY_I2C_BUS) + && forces[kind][j + 1] == addr) { + dev_dbg(&adapter->dev, "found force parameter, " + "addr 0x%02x, kind %u\n", addr, kind); + return kind; + } + } + } + + return -1; +} + int i2c_probe(struct i2c_adapter *adapter, struct i2c_client_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)) @@ -683,19 +705,15 @@ int i2c_probe(struct i2c_adapter *adapter, at all */ found = 0; - for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 2) { - if (((adap_id == address_data->force[i]) || - (address_data->force[i] == ANY_I2C_BUS)) && - (addr == address_data->force[i+1])) { - dev_dbg(&adapter->dev, "found force parameter for adapter %d, addr %04x\n", - adap_id, addr); - if ((err = found_proc(adapter,addr,0))) + if (address_data->forces) { + int kind = i2c_probe_forces(adapter, addr, + address_data->forces); + if (kind >= 0) { /* force found */ + if ((err = found_proc(adapter, addr, kind))) return err; - found = 1; + continue; } } - if (found) - continue; /* If this address is in one of the ignores, we can forget about it right now */ diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 48989eda2400..52e32f05d625 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -391,7 +391,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_adv7170; diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index f898b6586374..b5ed9544bdea 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -441,7 +441,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_adv7175; diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 8733588f6db3..c6cfa7c48b04 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -507,7 +507,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_bt819; diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index a5d529ccf3ad..c13d28658868 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -295,7 +295,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_bt856; diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c index 22d055d8a695..e116bdbed310 100644 --- a/drivers/media/video/saa7110.c +++ b/drivers/media/video/saa7110.c @@ -470,7 +470,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_saa7110; diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index fcd897382fcf..f18df53d98ff 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -489,7 +489,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_saa7111; diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 2ba997f5ef1d..e0c70f54f073 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -827,7 +827,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_saa7114; diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index 108e7a4a0273..e93412f4407c 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -387,7 +387,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver i2c_driver_saa7185; diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 7d825e510ffd..103def1abe3c 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -41,7 +41,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 5dbd9f6bf353..4437bdebe24f 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -576,7 +576,6 @@ static struct i2c_client_address_data addr_data = { .normal_i2c = normal_i2c, .probe = &ignore, .ignore = &ignore, - .force = &ignore, }; static struct i2c_driver vpx3220_i2c_driver; diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ad1c0fb164bc..9419bc5584ad 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -48,7 +48,6 @@ struct i2c_algorithm; struct i2c_adapter; struct i2c_client; struct i2c_driver; -struct i2c_client_address_data; union i2c_smbus_data; /* @@ -301,7 +300,7 @@ struct i2c_client_address_data { unsigned short *normal_i2c; unsigned short *probe; unsigned short *ignore; - unsigned short *force; + unsigned short **forces; }; /* Internal numbers to terminate lists */ @@ -575,11 +574,15 @@ union i2c_smbus_data { I2C_CLIENT_MODULE_PARM(force, \ "List of adapter,address pairs to boldly assume " \ "to be present"); \ + static unsigned short *addr_forces[] = { \ + force, \ + NULL \ + }; \ static struct i2c_client_address_data addr_data = { \ .normal_i2c = normal_i2c, \ .probe = probe, \ .ignore = ignore, \ - .force = force, \ + .forces = addr_forces, \ } #endif /* _LINUX_I2C_H */ -- cgit v1.2.3-55-g7522 From 975185880d55676b1352047e82a0cb84173c6c28 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 11 Aug 2005 23:33:24 +0200 Subject: [PATCH] I2C: Kill i2c_algorithm.name (1/7) The name member of the i2c_algorithm is never used, although all drivers conscientiously fill it. We can drop it completely, this structure doesn't need to have a name. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/algos/i2c-algo-bit.c | 1 - drivers/i2c/algos/i2c-algo-ite.c | 1 - drivers/i2c/algos/i2c-algo-pca.c | 1 - drivers/i2c/algos/i2c-algo-pcf.c | 1 - drivers/i2c/algos/i2c-algo-sgi.c | 1 - drivers/i2c/algos/i2c-algo-sibyte.c | 1 - drivers/i2c/busses/i2c-ali1535.c | 1 - drivers/i2c/busses/i2c-ali1563.c | 1 - drivers/i2c/busses/i2c-ali15x3.c | 1 - drivers/i2c/busses/i2c-amd756.c | 1 - drivers/i2c/busses/i2c-amd8111.c | 1 - drivers/i2c/busses/i2c-au1550.c | 1 - drivers/i2c/busses/i2c-i801.c | 1 - drivers/i2c/busses/i2c-ibm_iic.c | 1 - drivers/i2c/busses/i2c-iop3xx.c | 1 - drivers/i2c/busses/i2c-isa.c | 1 - drivers/i2c/busses/i2c-keywest.c | 1 - drivers/i2c/busses/i2c-mpc.c | 1 - drivers/i2c/busses/i2c-mv64xxx.c | 1 - drivers/i2c/busses/i2c-nforce2.c | 1 - drivers/i2c/busses/i2c-piix4.c | 1 - drivers/i2c/busses/i2c-s3c2410.c | 1 - drivers/i2c/busses/i2c-sis5595.c | 1 - drivers/i2c/busses/i2c-sis630.c | 1 - drivers/i2c/busses/i2c-sis96x.c | 1 - drivers/i2c/busses/i2c-stub.c | 1 - drivers/i2c/busses/i2c-viapro.c | 1 - drivers/i2c/busses/scx200_acb.c | 1 - drivers/media/common/saa7146_i2c.c | 1 - drivers/media/dvb/b2c2/flexcop-i2c.c | 1 - drivers/media/dvb/dvb-usb/cxusb.c | 1 - drivers/media/dvb/dvb-usb/dibusb-common.c | 1 - drivers/media/dvb/dvb-usb/digitv.c | 1 - drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 1 - drivers/media/video/bttv-i2c.c | 1 - drivers/media/video/saa7134/saa7134-i2c.c | 1 - drivers/usb/media/w9968cf.c | 1 - include/linux/i2c.h | 1 - 38 files changed, 38 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index fb5b732238ed..6e1e1601accb 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -519,7 +519,6 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm i2c_bit_algo = { - .name = "Bit-shift algorithm", .id = I2C_ALGO_BIT, .master_xfer = bit_xfer, .functionality = bit_func, diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c index e6cae39f47aa..a9c2b1115e07 100644 --- a/drivers/i2c/algos/i2c-algo-ite.c +++ b/drivers/i2c/algos/i2c-algo-ite.c @@ -713,7 +713,6 @@ static u32 iic_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm iic_algo = { - .name = "ITE IIC algorithm", .id = I2C_ALGO_IIC, .master_xfer = iic_xfer, .algo_control = algo_control, /* ioctl */ diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index ff2db0da4417..16157391cdf5 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -356,7 +356,6 @@ static int pca_init(struct i2c_algo_pca_data *adap) } static struct i2c_algorithm pca_algo = { - .name = "PCA9564 algorithm", .id = I2C_ALGO_PCA, .master_xfer = pca_xfer, .functionality = pca_func, diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 8d087dac32af..eb3e9e39d75b 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -459,7 +459,6 @@ static u32 pcf_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm pcf_algo = { - .name = "PCF8584 algorithm", .id = I2C_ALGO_PCF, .master_xfer = pcf_xfer, .functionality = pcf_func, diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c index 422721b241e5..55284c9e41dc 100644 --- a/drivers/i2c/algos/i2c-algo-sgi.c +++ b/drivers/i2c/algos/i2c-algo-sgi.c @@ -158,7 +158,6 @@ static u32 sgi_func(struct i2c_adapter *adap) } static struct i2c_algorithm sgi_algo = { - .name = "SGI algorithm", .id = I2C_ALGO_SGI, .master_xfer = sgi_xfer, .functionality = sgi_func, diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index f2785499237b..4ca3e69461bc 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -135,7 +135,6 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm i2c_sibyte_algo = { - .name = "SiByte algorithm", .id = I2C_ALGO_SIBYTE, .smbus_xfer = smbus_xfer, .algo_control = algo_control, /* ioctl */ diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index f634a0780cf0..d7e05a1a5125 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -472,7 +472,6 @@ static u32 ali1535_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-i2c SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = ali1535_access, .functionality = ali1535_func, diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index fdd881aee618..48f85e53d7d6 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -366,7 +366,6 @@ static void ali1563_shutdown(struct pci_dev *dev) } static struct i2c_algorithm ali1563_algorithm = { - .name = "Non-i2c SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = ali1563_access, .functionality = ali1563_func, diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 0f781a1a3323..523f0129e4cd 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -462,7 +462,6 @@ static u32 ali15x3_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = ali15x3_access, .functionality = ali15x3_func, diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 6347ebc6fb53..7cf33325ac14 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -295,7 +295,6 @@ static u32 amd756_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = amd756_access, .functionality = amd756_func, diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index d6644481d2a0..3b98d3b40042 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -323,7 +323,6 @@ static u32 amd8111_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus 2.0 adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = amd8111_access, .functionality = amd8111_func, diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index a7ff112e49bf..41fff3531aee 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -283,7 +283,6 @@ au1550_func(struct i2c_adapter *adap) } static struct i2c_algorithm au1550_algo = { - .name = "Au1550 algorithm", .id = I2C_ALGO_AU1550, .master_xfer = au1550_xfer, .functionality = au1550_func, diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1ab41313ce51..b916317b76a6 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -535,7 +535,6 @@ static u32 i801_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = i801_access, .functionality = i801_func, diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 93ca36dc777e..1a3366287087 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -627,7 +627,6 @@ static u32 iic_func(struct i2c_adapter *adap) } static struct i2c_algorithm iic_algo = { - .name = "IBM IIC algorithm", .id = I2C_ALGO_OCP, .master_xfer = iic_xfer, .functionality = iic_func diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 6b682e903f09..c763039638d9 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -399,7 +399,6 @@ iop3xx_i2c_func(struct i2c_adapter *adap) } static struct i2c_algorithm iop3xx_i2c_algo = { - .name = "IOP3xx I2C algorithm", .id = I2C_ALGO_IOP3XX, .master_xfer = iop3xx_i2c_master_xfer, .algo_control = iop3xx_i2c_algo_control, diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index a60f4801757e..bbfd4449b921 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -43,7 +43,6 @@ static u32 isa_func(struct i2c_adapter *adapter); /* This is the actual algorithm we define */ static struct i2c_algorithm isa_algorithm = { - .name = "ISA bus algorithm", .id = I2C_ALGO_ISA, .functionality = isa_func, }; diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 94ae808314f7..2937f115abf1 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -498,7 +498,6 @@ keywest_func(struct i2c_adapter * adapter) /* For now, we only handle combined mode (smbus) */ static struct i2c_algorithm keywest_algorithm = { - .name = "Keywest i2c", .id = I2C_ALGO_SMBUS, .smbus_xfer = keywest_smbus_xfer, .master_xfer = keywest_xfer, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 9ad3e9262e8a..ae988cc8cb48 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -272,7 +272,6 @@ static u32 mpc_functionality(struct i2c_adapter *adap) } static struct i2c_algorithm mpc_algo = { - .name = "MPC algorithm", .id = I2C_ALGO_MPC107, .master_xfer = mpc_xfer, .functionality = mpc_functionality, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 5b852782d2f5..f5927c68784c 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -433,7 +433,6 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } static struct i2c_algorithm mv64xxx_i2c_algo = { - .name = MV64XXX_I2C_CTLR_NAME " algorithm", .id = I2C_ALGO_MV64XXX, .master_xfer = mv64xxx_i2c_xfer, .functionality = mv64xxx_i2c_functionality, diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 1df601bb7f4f..44b6dfdd3832 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -110,7 +110,6 @@ static u32 nforce2_func(struct i2c_adapter *adapter); static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = nforce2_access, .functionality = nforce2_func, diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 6d34ee381ce1..976df581e853 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -399,7 +399,6 @@ static u32 piix4_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = piix4_access, .functionality = piix4_func, diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index a3b38257cc3d..73a092fb0e7e 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c @@ -568,7 +568,6 @@ static u32 s3c24xx_i2c_func(struct i2c_adapter *adap) /* i2c bus registration info */ static struct i2c_algorithm s3c24xx_i2c_algorithm = { - .name = "S3C2410-I2C-Algorithm", .master_xfer = s3c24xx_i2c_xfer, .functionality = s3c24xx_i2c_func, }; diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index bbd5e4e52f09..0308ed87e2b9 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -357,7 +357,6 @@ static u32 sis5595_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = sis5595_access, .functionality = sis5595_func, diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index f58455e7689e..8708f9044023 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -448,7 +448,6 @@ exit: static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = sis630_access, .functionality = sis630_func, diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 6484792e23a1..6e7202ed3265 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -249,7 +249,6 @@ static u32 sis96x_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = sis96x_access, .functionality = sis96x_func, diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index 00d94e886955..d7203207754f 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c @@ -109,7 +109,6 @@ static u32 stub_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .functionality = stub_func, .smbus_xfer = stub_xfer, diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 6b5008005c6f..608ad525e7e1 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -286,7 +286,6 @@ static u32 vt596_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .name = "Non-I2C SMBus adapter", .id = I2C_ALGO_SMBUS, .smbus_xfer = vt596_access, .functionality = vt596_func, diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index a18bdd9aa7ba..b695233d5455 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -395,7 +395,6 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter) /* For now, we only handle combined mode (smbus) */ static struct i2c_algorithm scx200_acb_algorithm = { - .name = "NatSemi SCx200 ACCESS.bus", .id = I2C_ALGO_SMBUS, .smbus_xfer = scx200_acb_smbus_xfer, .functionality = scx200_acb_func, diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 781f23f0cbcc..dceda86cd99d 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -387,7 +387,6 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in /* exported algorithm data */ static struct i2c_algorithm saa7146_algo = { - .name = "saa7146 i2c algorithm", .id = I2C_ALGO_SAA7146, .master_xfer = saa7146_i2c_xfer, .functionality = saa7146_i2c_func, diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index be4266d4ae91..75f2c94f3190 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -172,7 +172,6 @@ static u32 flexcop_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm flexcop_algo = { - .name = "FlexCop I2C algorithm", .id = I2C_ALGO_BIT, .master_xfer = flexcop_master_xfer, .functionality = flexcop_i2c_func, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index c3e1b661aae6..36fe602f85b6 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -141,7 +141,6 @@ static u32 cxusb_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm cxusb_i2c_algo = { - .name = "Conexant USB I2C algorithm", .id = I2C_ALGO_BIT, .master_xfer = cxusb_i2c_xfer, .functionality = cxusb_i2c_func, diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 9b9d6f8ee74e..c3a639520e8a 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -156,7 +156,6 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter) } struct i2c_algorithm dibusb_i2c_algo = { - .name = "DiBcom USB I2C algorithm", .id = I2C_ALGO_BIT, .master_xfer = dibusb_i2c_xfer, .functionality = dibusb_i2c_func, diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 9a676afc1d6e..6e4e1e9158e3 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -77,7 +77,6 @@ static u32 digitv_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm digitv_i2c_algo = { - .name = "Nebula DigiTV USB I2C algorithm", .id = I2C_ALGO_BIT, .master_xfer = digitv_i2c_xfer, .functionality = digitv_i2c_func, diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index aa43b5fcb8e7..c337ee546bac 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1472,7 +1472,6 @@ static void frontend_init(struct ttusb* ttusb) static struct i2c_algorithm ttusb_dec_algo = { - .name = "ttusb dec i2c algorithm", .id = I2C_ALGO_BIT, .master_xfer = master_xfer, .functionality = functionality, diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index 234a85563769..dbc96fce7501 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -270,7 +270,6 @@ static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int } static struct i2c_algorithm bttv_algo = { - .name = "bt878", .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, .master_xfer = bttv_i2c_xfer, .algo_control = algo_control, diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 1203b93a572c..1a53c7eb104a 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -370,7 +370,6 @@ static int attach_inform(struct i2c_client *client) } static struct i2c_algorithm saa7134_algo = { - .name = "saa7134", .id = I2C_ALGO_SAA7134, .master_xfer = saa7134_i2c_xfer, .algo_control = algo_control, diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index ca9f3a30634f..ad1d6777e226 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -1573,7 +1573,6 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) int err = 0; static struct i2c_algorithm algo = { - .name = "W996[87]CF algorithm", .id = I2C_ALGO_SMBUS, .smbus_xfer = w9968cf_i2c_smbus_xfer, .algo_control = w9968cf_i2c_control, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 3ad3969b6f0d..f04b1fc6a0fa 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -192,7 +192,6 @@ static inline char *i2c_clientname(struct i2c_client *c) * to name two of the most common. */ struct i2c_algorithm { - char name[32]; /* textual description */ unsigned int id; /* If an adapter algorithm can't do I2C-level access, set master_xfer -- cgit v1.2.3-55-g7522 From 1d8b9e1bad35fa3ea829990b9056c2a257d8fe79 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 11 Aug 2005 23:40:19 +0200 Subject: [PATCH] I2C: Kill i2c_algorithm.id (4/7) There are no more users of i2c_algorithm.id, so we can finally drop this structure member. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/algos/i2c-algo-bit.c | 1 - drivers/i2c/algos/i2c-algo-ite.c | 1 - drivers/i2c/algos/i2c-algo-pca.c | 1 - drivers/i2c/algos/i2c-algo-pcf.c | 1 - drivers/i2c/algos/i2c-algo-sgi.c | 1 - drivers/i2c/algos/i2c-algo-sibyte.c | 1 - drivers/i2c/busses/i2c-ali1535.c | 1 - drivers/i2c/busses/i2c-ali1563.c | 1 - drivers/i2c/busses/i2c-ali15x3.c | 1 - drivers/i2c/busses/i2c-amd756.c | 1 - drivers/i2c/busses/i2c-amd8111.c | 1 - drivers/i2c/busses/i2c-au1550.c | 1 - drivers/i2c/busses/i2c-i801.c | 1 - drivers/i2c/busses/i2c-ibm_iic.c | 1 - drivers/i2c/busses/i2c-iop3xx.c | 1 - drivers/i2c/busses/i2c-isa.c | 1 - drivers/i2c/busses/i2c-keywest.c | 1 - drivers/i2c/busses/i2c-mpc.c | 1 - drivers/i2c/busses/i2c-mv64xxx.c | 1 - drivers/i2c/busses/i2c-nforce2.c | 1 - drivers/i2c/busses/i2c-piix4.c | 1 - drivers/i2c/busses/i2c-sis5595.c | 1 - drivers/i2c/busses/i2c-sis630.c | 1 - drivers/i2c/busses/i2c-sis96x.c | 1 - drivers/i2c/busses/i2c-stub.c | 1 - drivers/i2c/busses/i2c-viapro.c | 1 - drivers/i2c/busses/scx200_acb.c | 1 - drivers/media/common/saa7146_i2c.c | 1 - drivers/media/dvb/b2c2/flexcop-i2c.c | 1 - drivers/media/dvb/dvb-usb/cxusb.c | 1 - drivers/media/dvb/dvb-usb/dibusb-common.c | 1 - drivers/media/dvb/dvb-usb/digitv.c | 1 - drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 1 - drivers/media/video/bttv-i2c.c | 1 - drivers/media/video/saa7134/saa7134-i2c.c | 1 - drivers/usb/media/w9968cf.c | 1 - include/linux/i2c.h | 2 -- 37 files changed, 38 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index b8767382bbac..6060b10ab0ce 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -519,7 +519,6 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm i2c_bit_algo = { - .id = I2C_ALGO_BIT, .master_xfer = bit_xfer, .functionality = bit_func, }; diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c index 6cb02f685db3..b460e57216e1 100644 --- a/drivers/i2c/algos/i2c-algo-ite.c +++ b/drivers/i2c/algos/i2c-algo-ite.c @@ -713,7 +713,6 @@ static u32 iic_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm iic_algo = { - .id = I2C_ALGO_IIC, .master_xfer = iic_xfer, .algo_control = algo_control, /* ioctl */ .functionality = iic_func, diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 79b3c2edcf08..be2c8abc6682 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -356,7 +356,6 @@ static int pca_init(struct i2c_algo_pca_data *adap) } static struct i2c_algorithm pca_algo = { - .id = I2C_ALGO_PCA, .master_xfer = pca_xfer, .functionality = pca_func, }; diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index fbc0b87fe070..95f023ad8c62 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -459,7 +459,6 @@ static u32 pcf_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm pcf_algo = { - .id = I2C_ALGO_PCF, .master_xfer = pcf_xfer, .functionality = pcf_func, }; diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c index 8863a671d977..142505105d6f 100644 --- a/drivers/i2c/algos/i2c-algo-sgi.c +++ b/drivers/i2c/algos/i2c-algo-sgi.c @@ -158,7 +158,6 @@ static u32 sgi_func(struct i2c_adapter *adap) } static struct i2c_algorithm sgi_algo = { - .id = I2C_ALGO_SGI, .master_xfer = sgi_xfer, .functionality = sgi_func, }; diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 6cda0a6332d9..c01108ae7b69 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -135,7 +135,6 @@ static u32 bit_func(struct i2c_adapter *adap) /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm i2c_sibyte_algo = { - .id = I2C_ALGO_SIBYTE, .smbus_xfer = smbus_xfer, .algo_control = algo_control, /* ioctl */ .functionality = bit_func, diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index d7e05a1a5125..f021acd2674e 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c @@ -472,7 +472,6 @@ static u32 ali1535_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = ali1535_access, .functionality = ali1535_func, }; diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 48f85e53d7d6..86947504aea1 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -366,7 +366,6 @@ static void ali1563_shutdown(struct pci_dev *dev) } static struct i2c_algorithm ali1563_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = ali1563_access, .functionality = ali1563_func, }; diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 523f0129e4cd..b3f50bff39a0 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c @@ -462,7 +462,6 @@ static u32 ali15x3_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = ali15x3_access, .functionality = ali15x3_func, }; diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 7cf33325ac14..6ad0603384b8 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c @@ -295,7 +295,6 @@ static u32 amd756_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = amd756_access, .functionality = amd756_func, }; diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 3b98d3b40042..45ea24ba14d5 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -323,7 +323,6 @@ static u32 amd8111_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = amd8111_access, .functionality = amd8111_func, }; diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index 41fff3531aee..d06edce03bf4 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c @@ -283,7 +283,6 @@ au1550_func(struct i2c_adapter *adap) } static struct i2c_algorithm au1550_algo = { - .id = I2C_ALGO_AU1550, .master_xfer = au1550_xfer, .functionality = au1550_func, }; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index b916317b76a6..709beab76609 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -535,7 +535,6 @@ static u32 i801_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = i801_access, .functionality = i801_func, }; diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index ade9b14e6840..f42ab909eb78 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -627,7 +627,6 @@ static u32 iic_func(struct i2c_adapter *adap) } static struct i2c_algorithm iic_algo = { - .id = I2C_ALGO_OCP, .master_xfer = iic_xfer, .functionality = iic_func }; diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index c763039638d9..7bd9102db701 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -399,7 +399,6 @@ iop3xx_i2c_func(struct i2c_adapter *adap) } static struct i2c_algorithm iop3xx_i2c_algo = { - .id = I2C_ALGO_IOP3XX, .master_xfer = iop3xx_i2c_master_xfer, .algo_control = iop3xx_i2c_algo_control, .functionality = iop3xx_i2c_func, diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index dc666d7cf45a..baae5dbc198e 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -43,7 +43,6 @@ static u32 isa_func(struct i2c_adapter *adapter); /* This is the actual algorithm we define */ static struct i2c_algorithm isa_algorithm = { - .id = I2C_ALGO_ISA, .functionality = isa_func, }; diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 2937f115abf1..5254d2db282c 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -498,7 +498,6 @@ keywest_func(struct i2c_adapter * adapter) /* For now, we only handle combined mode (smbus) */ static struct i2c_algorithm keywest_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = keywest_smbus_xfer, .master_xfer = keywest_xfer, .functionality = keywest_func, diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index ae988cc8cb48..70c5ffaee6a3 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -272,7 +272,6 @@ static u32 mpc_functionality(struct i2c_adapter *adap) } static struct i2c_algorithm mpc_algo = { - .id = I2C_ALGO_MPC107, .master_xfer = mpc_xfer, .functionality = mpc_functionality, }; diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index f5927c68784c..6e5dd4949237 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -433,7 +433,6 @@ mv64xxx_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) } static struct i2c_algorithm mv64xxx_i2c_algo = { - .id = I2C_ALGO_MV64XXX, .master_xfer = mv64xxx_i2c_xfer, .functionality = mv64xxx_i2c_functionality, }; diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 44b6dfdd3832..e0b7a913431e 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -110,7 +110,6 @@ static u32 nforce2_func(struct i2c_adapter *adapter); static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = nforce2_access, .functionality = nforce2_func, }; diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 976df581e853..6d48a4da7bed 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -399,7 +399,6 @@ static u32 piix4_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = piix4_access, .functionality = piix4_func, }; diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 0308ed87e2b9..080318d6f54b 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c @@ -357,7 +357,6 @@ static u32 sis5595_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = sis5595_access, .functionality = sis5595_func, }; diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 8708f9044023..86f0f448fa0b 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c @@ -448,7 +448,6 @@ exit: static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = sis630_access, .functionality = sis630_func, }; diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 6e7202ed3265..ead2ff3cf60e 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c @@ -249,7 +249,6 @@ static u32 sis96x_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = sis96x_access, .functionality = sis96x_func, }; diff --git a/drivers/i2c/busses/i2c-stub.c b/drivers/i2c/busses/i2c-stub.c index d7203207754f..73f481e93a36 100644 --- a/drivers/i2c/busses/i2c-stub.c +++ b/drivers/i2c/busses/i2c-stub.c @@ -109,7 +109,6 @@ static u32 stub_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .functionality = stub_func, .smbus_xfer = stub_xfer, }; diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 608ad525e7e1..99d209e0485a 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c @@ -286,7 +286,6 @@ static u32 vt596_func(struct i2c_adapter *adapter) } static struct i2c_algorithm smbus_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = vt596_access, .functionality = vt596_func, }; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index b695233d5455..46b9a7594c99 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -395,7 +395,6 @@ static u32 scx200_acb_func(struct i2c_adapter *adapter) /* For now, we only handle combined mode (smbus) */ static struct i2c_algorithm scx200_acb_algorithm = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = scx200_acb_smbus_xfer, .functionality = scx200_acb_func, }; diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index dceda86cd99d..e413ee7f267a 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -387,7 +387,6 @@ static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, in /* exported algorithm data */ static struct i2c_algorithm saa7146_algo = { - .id = I2C_ALGO_SAA7146, .master_xfer = saa7146_i2c_xfer, .functionality = saa7146_i2c_func, }; diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 75f2c94f3190..848910ff3c9c 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -172,7 +172,6 @@ static u32 flexcop_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm flexcop_algo = { - .id = I2C_ALGO_BIT, .master_xfer = flexcop_master_xfer, .functionality = flexcop_i2c_func, }; diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 36fe602f85b6..9e96a188f1e9 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -141,7 +141,6 @@ static u32 cxusb_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm cxusb_i2c_algo = { - .id = I2C_ALGO_BIT, .master_xfer = cxusb_i2c_xfer, .functionality = cxusb_i2c_func, }; diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index c3a639520e8a..00b946419b40 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -156,7 +156,6 @@ static u32 dibusb_i2c_func(struct i2c_adapter *adapter) } struct i2c_algorithm dibusb_i2c_algo = { - .id = I2C_ALGO_BIT, .master_xfer = dibusb_i2c_xfer, .functionality = dibusb_i2c_func, }; diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index 6e4e1e9158e3..f70e0be0920a 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -77,7 +77,6 @@ static u32 digitv_i2c_func(struct i2c_adapter *adapter) } static struct i2c_algorithm digitv_i2c_algo = { - .id = I2C_ALGO_BIT, .master_xfer = digitv_i2c_xfer, .functionality = digitv_i2c_func, }; diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index c337ee546bac..11afec52f31f 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1472,7 +1472,6 @@ static void frontend_init(struct ttusb* ttusb) static struct i2c_algorithm ttusb_dec_algo = { - .id = I2C_ALGO_BIT, .master_xfer = master_xfer, .functionality = functionality, }; diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index dbc96fce7501..82beb5a8a59c 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -270,7 +270,6 @@ static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int } static struct i2c_algorithm bttv_algo = { - .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, .master_xfer = bttv_i2c_xfer, .algo_control = algo_control, .functionality = functionality, diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 1a53c7eb104a..0bb1073d94bd 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -370,7 +370,6 @@ static int attach_inform(struct i2c_client *client) } static struct i2c_algorithm saa7134_algo = { - .id = I2C_ALGO_SAA7134, .master_xfer = saa7134_i2c_xfer, .algo_control = algo_control, .functionality = functionality, diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index ad1d6777e226..908cfdf17039 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -1573,7 +1573,6 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) int err = 0; static struct i2c_algorithm algo = { - .id = I2C_ALGO_SMBUS, .smbus_xfer = w9968cf_i2c_smbus_xfer, .algo_control = w9968cf_i2c_control, .functionality = w9968cf_i2c_func, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f04b1fc6a0fa..af4983b488b6 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -192,8 +192,6 @@ static inline char *i2c_clientname(struct i2c_client *c) * to name two of the most common. */ struct i2c_algorithm { - unsigned int id; - /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated -- cgit v1.2.3-55-g7522 From c7a46533ff7ef9e1c51bae6e54208527c5275b24 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 11 Aug 2005 23:41:56 +0200 Subject: [PATCH] I2C: Kill i2c_algorithm.id (5/7) Merge the algorithm id part (16 upper bits) of the i2c adapters ids into the definition of the adapters ids directly. After that, we don't need to OR both ids together for each i2c_adapter structure. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/algos/i2c-algo-bit.c | 2 - drivers/i2c/algos/i2c-algo-ite.c | 2 - drivers/i2c/algos/i2c-algo-pca.c | 2 - drivers/i2c/algos/i2c-algo-pcf.c | 2 - drivers/i2c/algos/i2c-algo-sgi.c | 1 - drivers/i2c/algos/i2c-algo-sibyte.c | 2 - drivers/i2c/busses/i2c-ibm_iic.c | 2 +- drivers/i2c/busses/i2c-isa.c | 2 +- drivers/i2c/busses/i2c-mpc.c | 2 +- drivers/i2c/busses/i2c-mv64xxx.c | 2 +- drivers/media/video/bt832.c | 2 +- drivers/media/video/bttv-i2c.c | 2 +- drivers/media/video/ir-kbd-i2c.c | 2 +- drivers/media/video/ovcamchip/ov6x20.c | 6 +- drivers/media/video/ovcamchip/ov6x30.c | 4 +- drivers/media/video/ovcamchip/ovcamchip_core.c | 8 +- drivers/media/video/tda7432.c | 2 +- drivers/media/video/tda9875.c | 2 +- drivers/media/video/tda9887.c | 4 +- drivers/media/video/tuner-3036.c | 2 +- drivers/media/video/tvaudio.c | 6 +- drivers/media/video/tveeprom.c | 2 +- drivers/media/video/tvmixer.c | 6 +- drivers/usb/media/w9968cf.c | 2 +- drivers/video/matrox/matroxfb_maven.c | 2 +- include/linux/i2c-id.h | 128 ++++++++++++------------- include/linux/i2c-isa.h | 2 +- 27 files changed, 95 insertions(+), 106 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 6060b10ab0ce..df05df1a0ef6 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c @@ -539,8 +539,6 @@ int i2c_bit_add_bus(struct i2c_adapter *adap) DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); /* register new adapter to i2c module... */ - - adap->id |= I2C_ALGO_BIT; adap->algo = &i2c_bit_algo; adap->timeout = 100; /* default values, should */ diff --git a/drivers/i2c/algos/i2c-algo-ite.c b/drivers/i2c/algos/i2c-algo-ite.c index b460e57216e1..2db7bfc85225 100644 --- a/drivers/i2c/algos/i2c-algo-ite.c +++ b/drivers/i2c/algos/i2c-algo-ite.c @@ -736,8 +736,6 @@ int i2c_iic_add_bus(struct i2c_adapter *adap) adap->name)); /* register new adapter to i2c module... */ - - adap->id |= I2C_ALGO_IIC; adap->algo = &iic_algo; adap->timeout = 100; /* default values, should */ diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index be2c8abc6682..beb10edfe9c1 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c @@ -369,8 +369,6 @@ int i2c_pca_add_bus(struct i2c_adapter *adap) int rval; /* register new adapter to i2c module... */ - - adap->id |= I2C_ALGO_PCA; adap->algo = &pca_algo; adap->timeout = 100; /* default values, should */ diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 95f023ad8c62..6e498df1f717 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c @@ -474,8 +474,6 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); /* register new adapter to i2c module... */ - - adap->id |= I2C_ALGO_PCF; adap->algo = &pcf_algo; adap->timeout = 100; /* default values, should */ diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c index 142505105d6f..2f8df81317ff 100644 --- a/drivers/i2c/algos/i2c-algo-sgi.c +++ b/drivers/i2c/algos/i2c-algo-sgi.c @@ -167,7 +167,6 @@ static struct i2c_algorithm sgi_algo = { */ int i2c_sgi_add_bus(struct i2c_adapter *adap) { - adap->id |= I2C_ALGO_SGI; adap->algo = &sgi_algo; return i2c_add_adapter(adap); diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index c01108ae7b69..8ed5ad12552f 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c @@ -149,8 +149,6 @@ int i2c_sibyte_add_bus(struct i2c_adapter *i2c_adap, int speed) struct i2c_algo_sibyte_data *adap = i2c_adap->algo_data; /* register new adapter to i2c module... */ - - i2c_adap->id |= I2C_ALGO_SIBYTE; i2c_adap->algo = &i2c_sibyte_algo; /* Set the frequency to 100 kHz */ diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index f42ab909eb78..a3ed9590f028 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -725,7 +725,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ adap = &dev->adap; strcpy(adap->name, "IBM IIC"); i2c_set_adapdata(adap, dev); - adap->id = I2C_ALGO_OCP | I2C_HW_OCP; + adap->id = I2C_HW_OCP; adap->algo = &iic_algo; adap->client_register = NULL; adap->client_unregister = NULL; diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index baae5dbc198e..bdc6806dafae 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c @@ -49,7 +49,7 @@ static struct i2c_algorithm isa_algorithm = { /* There can only be one... */ static struct i2c_adapter isa_adapter = { .owner = THIS_MODULE, - .id = I2C_ALGO_ISA | I2C_HW_ISA, + .id = I2C_HW_ISA, .class = I2C_CLASS_HWMON, .algo = &isa_algorithm, .name = "ISA main adapter", diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 70c5ffaee6a3..f065583ddcf1 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -279,7 +279,7 @@ static struct i2c_algorithm mpc_algo = { static struct i2c_adapter mpc_ops = { .owner = THIS_MODULE, .name = "MPC adapter", - .id = I2C_ALGO_MPC107 | I2C_HW_MPC107, + .id = I2C_HW_MPC107, .algo = &mpc_algo, .class = I2C_CLASS_HWMON, .timeout = 1, diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 6e5dd4949237..eb6cc0869938 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -521,7 +521,7 @@ mv64xxx_i2c_probe(struct device *dev) drv_data->freq_m = pdata->freq_m; drv_data->freq_n = pdata->freq_n; drv_data->irq = platform_get_irq(pd, 0); - drv_data->adapter.id = I2C_ALGO_MV64XXX | I2C_HW_MV64XXX; + drv_data->adapter.id = I2C_HW_MV64XXX; drv_data->adapter.algo = &mv64xxx_i2c_algo; drv_data->adapter.owner = THIS_MODULE; drv_data->adapter.class = I2C_CLASS_HWMON; diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index a070417e65e6..67ffed8a7fea 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -188,7 +188,7 @@ static int bt832_probe(struct i2c_adapter *adap) if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, bt832_attach); #else - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) + if (adap->id == I2C_HW_B_BT848) return i2c_probe(adap, &addr_data, bt832_attach); #endif return 0; diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index 82beb5a8a59c..1db95f75ac68 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -281,7 +281,7 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = { .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("bt878"), - .id = I2C_ALGO_BIT | I2C_HW_B_BT848 /* FIXME */, + .id = I2C_HW_B_BT848 /* FIXME */, .algo = &bttv_algo, .client_register = attach_inform, }; diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 9fc5055e001c..c2f32d522668 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -429,7 +429,7 @@ static int ir_probe(struct i2c_adapter *adap) struct i2c_client c; char buf; int i,rc; switch (adap->id) { - case I2C_ALGO_BIT | I2C_HW_B_BT848: + case I2C_HW_B_BT848: probe = probe_bttv; break; case I2C_ALGO_SAA7134: diff --git a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c index 3433619ad93f..b3f4d266cede 100644 --- a/drivers/media/video/ovcamchip/ov6x20.c +++ b/drivers/media/video/ovcamchip/ov6x20.c @@ -164,10 +164,10 @@ static int ov6x20_init(struct i2c_client *c) DDEBUG(4, &c->dev, "entered"); switch (c->adapter->id) { - case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511: + case I2C_HW_SMBUS_OV511: rc = ov_write_regvals(c, regvals_init_6x20_511); break; - case I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518: + case I2C_HW_SMBUS_OV518: rc = ov_write_regvals(c, regvals_init_6x20_518); break; default: @@ -338,7 +338,7 @@ static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win) /******** Palette-specific regs ********/ /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */ - if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + if (c->adapter->id == I2C_HW_SMBUS_OV518) { if (win->format == VIDEO_PALETTE_GREY) ov_write_mask(c, 0x13, 0x00, 0x20); else diff --git a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c index 44a842379b45..6eab458ab792 100644 --- a/drivers/media/video/ovcamchip/ov6x30.c +++ b/drivers/media/video/ovcamchip/ov6x30.c @@ -301,7 +301,7 @@ static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win) /******** Palette-specific regs ********/ if (win->format == VIDEO_PALETTE_GREY) { - if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + if (c->adapter->id == I2C_HW_SMBUS_OV518) { /* Do nothing - we're already in 8-bit mode */ } else { ov_write_mask(c, 0x13, 0x20, 0x20); @@ -313,7 +313,7 @@ static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win) * Therefore, the OV6630 needs to be in 8-bit multiplexed * output mode */ - if (c->adapter->id == (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518)) { + if (c->adapter->id == I2C_HW_SMBUS_OV518) { /* Do nothing - we want to stay in 8-bit mode */ /* Warning: Messing with reg 0x13 breaks OV518 color */ } else { diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c index 54dd5612d3b8..b98c64ab7c58 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -296,10 +296,10 @@ static int ovcamchip_attach(struct i2c_adapter *adap) * attach to adapters that are known to contain OV camera chips. */ switch (adap->id) { - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV511): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OV518): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_OVFX2): - case (I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF): + case I2C_HW_SMBUS_OV511: + case I2C_HW_SMBUS_OV518: + case I2C_HW_SMBUS_OVFX2: + case I2C_HW_SMBUS_W9968CF: PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id); break; default: diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 7cb1fb3e66f9..bc6b6c0cea6d 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -328,7 +328,7 @@ static int tda7432_probe(struct i2c_adapter *adap) if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda7432_attach); #else - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) + if (adap->id == I2C_HW_B_BT848) return i2c_probe(adap, &addr_data, tda7432_attach); #endif return 0; diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 566e1a5ca135..3eaf2e1211e5 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -262,7 +262,7 @@ static int tda9875_probe(struct i2c_adapter *adap) if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9875_attach); #else - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) + if (adap->id == I2C_HW_B_BT848) return i2c_probe(adap, &addr_data, tda9875_attach); #endif return 0; diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index a28a395d6dfe..f1b1bb5acf70 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -618,8 +618,8 @@ static int tda9887_probe(struct i2c_adapter *adap) return i2c_probe(adap, &addr_data, tda9887_attach); #else switch (adap->id) { - case I2C_ALGO_BIT | I2C_HW_B_BT848: - case I2C_ALGO_BIT | I2C_HW_B_RIVA: + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: case I2C_ALGO_SAA7134: return i2c_probe(adap, &addr_data, tda9887_attach); break; diff --git a/drivers/media/video/tuner-3036.c b/drivers/media/video/tuner-3036.c index 103def1abe3c..79203595b9c1 100644 --- a/drivers/media/video/tuner-3036.c +++ b/drivers/media/video/tuner-3036.c @@ -165,7 +165,7 @@ static int tuner_probe(struct i2c_adapter *adap) { this_adap = 0; - if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_LP)) + if (adap->id == I2C_HW_B_LP) return i2c_probe(adap, &addr_data, tuner_attach); return 0; } diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index f42a1efa8fcf..9420b5f52915 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1098,7 +1098,7 @@ static int tda8425_initialize(struct CHIPSTATE *chip) /* extern */ TDA8425_S1_CH1, /* intern */ TDA8425_S1_OFF, /* off */ TDA8425_S1_OFF, /* on */ TDA8425_S1_CH2}; - if (chip->c.adapter->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) { + if (chip->c.adapter->id == I2C_HW_B_RIVA) { memcpy (desc->inputmap, inputmap, sizeof (inputmap)); } return 0; @@ -1555,8 +1555,8 @@ static int chip_probe(struct i2c_adapter *adap) return i2c_probe(adap, &addr_data, chip_attach); #else switch (adap->id) { - case I2C_ALGO_BIT | I2C_HW_B_BT848: - case I2C_ALGO_BIT | I2C_HW_B_RIVA: + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: case I2C_ALGO_SAA7134: return i2c_probe(adap, &addr_data, chip_attach); } diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 127ec38ebd60..3c3356a01cc6 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -534,7 +534,7 @@ static int tveeprom_attach_adapter (struct i2c_adapter *adapter) { dprintk(1,"%s: id 0x%x\n",__FUNCTION__,adapter->id); - if (adapter->id != (I2C_ALGO_BIT | I2C_HW_B_BT848)) + if (adapter->id != I2C_HW_B_BT848) return 0; return i2c_probe(adapter, &addr_data, tveeprom_detect_client); } diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index 51b99cdbf29e..f0635b19de30 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -276,9 +276,9 @@ static int tvmixer_clients(struct i2c_client *client) #else /* TV card ??? */ switch (client->adapter->id) { - case I2C_ALGO_BIT | I2C_HW_SMBUS_VOODOO3: - case I2C_ALGO_BIT | I2C_HW_B_BT848: - case I2C_ALGO_BIT | I2C_HW_B_RIVA: + case I2C_HW_SMBUS_VOODOO3: + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: /* ok, have a look ... */ break; default: diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 908cfdf17039..83e8dd627154 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -1579,7 +1579,7 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam) }; static struct i2c_adapter adap = { - .id = I2C_ALGO_SMBUS | I2C_HW_SMBUS_W9968CF, + .id = I2C_HW_SMBUS_W9968CF, .class = I2C_CLASS_CAM_DIGITAL, .owner = THIS_MODULE, .client_register = w9968cf_i2c_attach_inform, diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c index 67f85344f0cc..ad60bbb16cdf 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/matrox/matroxfb_maven.c @@ -1271,7 +1271,7 @@ ERROR0:; } static int maven_attach_adapter(struct i2c_adapter* adapter) { - if (adapter->id == (I2C_ALGO_BIT | I2C_HW_B_G400)) + if (adapter->id == I2C_HW_B_G400) return i2c_probe(adapter, &addr_data, &maven_detect_client); return 0; } diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 33f08258f22b..5b72f664cc21 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -218,103 +218,103 @@ */ /* --- Bit algorithm adapters */ -#define I2C_HW_B_LP 0x00 /* Parallel port Philips style adapter */ -#define I2C_HW_B_LPC 0x01 /* Parallel port, over control reg. */ -#define I2C_HW_B_SER 0x02 /* Serial line interface */ -#define I2C_HW_B_ELV 0x03 /* ELV Card */ -#define I2C_HW_B_VELLE 0x04 /* Vellemann K8000 */ -#define I2C_HW_B_BT848 0x05 /* BT848 video boards */ -#define I2C_HW_B_WNV 0x06 /* Winnov Videums */ -#define I2C_HW_B_VIA 0x07 /* Via vt82c586b */ -#define I2C_HW_B_HYDRA 0x08 /* Apple Hydra Mac I/O */ -#define I2C_HW_B_G400 0x09 /* Matrox G400 */ -#define I2C_HW_B_I810 0x0a /* Intel I810 */ -#define I2C_HW_B_VOO 0x0b /* 3dfx Voodoo 3 / Banshee */ -#define I2C_HW_B_PPORT 0x0c /* Primitive parallel port adapter */ -#define I2C_HW_B_SAVG 0x0d /* Savage 4 */ -#define I2C_HW_B_SCX200 0x0e /* Nat'l Semi SCx200 I2C */ -#define I2C_HW_B_RIVA 0x10 /* Riva based graphics cards */ -#define I2C_HW_B_IOC 0x11 /* IOC bit-wiggling */ -#define I2C_HW_B_TSUNA 0x12 /* DEC Tsunami chipset */ -#define I2C_HW_B_FRODO 0x13 /* 2d3D, Inc. SA-1110 Development Board */ -#define I2C_HW_B_OMAHA 0x14 /* Omaha I2C interface (ARM) */ -#define I2C_HW_B_GUIDE 0x15 /* Guide bit-basher */ -#define I2C_HW_B_IXP2000 0x16 /* GPIO on IXP2000 systems */ -#define I2C_HW_B_IXP4XX 0x17 /* GPIO on IXP4XX systems */ -#define I2C_HW_B_S3VIA 0x18 /* S3Via ProSavage adapter */ -#define I2C_HW_B_ZR36067 0x19 /* Zoran-36057/36067 based boards */ -#define I2C_HW_B_PCILYNX 0x1a /* TI PCILynx I2C adapter */ -#define I2C_HW_B_CX2388x 0x1b /* connexant 2388x based tv cards */ +#define I2C_HW_B_LP 0x010000 /* Parallel port Philips style */ +#define I2C_HW_B_LPC 0x010001 /* Parallel port control reg. */ +#define I2C_HW_B_SER 0x010002 /* Serial line interface */ +#define I2C_HW_B_ELV 0x010003 /* ELV Card */ +#define I2C_HW_B_VELLE 0x010004 /* Vellemann K8000 */ +#define I2C_HW_B_BT848 0x010005 /* BT848 video boards */ +#define I2C_HW_B_WNV 0x010006 /* Winnov Videums */ +#define I2C_HW_B_VIA 0x010007 /* Via vt82c586b */ +#define I2C_HW_B_HYDRA 0x010008 /* Apple Hydra Mac I/O */ +#define I2C_HW_B_G400 0x010009 /* Matrox G400 */ +#define I2C_HW_B_I810 0x01000a /* Intel I810 */ +#define I2C_HW_B_VOO 0x01000b /* 3dfx Voodoo 3 / Banshee */ +#define I2C_HW_B_PPORT 0x01000c /* Primitive parallel port adapter */ +#define I2C_HW_B_SAVG 0x01000d /* Savage 4 */ +#define I2C_HW_B_SCX200 0x01000e /* Nat'l Semi SCx200 I2C */ +#define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */ +#define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */ +#define I2C_HW_B_TSUNA 0x010012 /* DEC Tsunami chipset */ +#define I2C_HW_B_FRODO 0x010013 /* 2d3D SA-1110 Development Board */ +#define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */ +#define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */ +#define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */ +#define I2C_HW_B_IXP4XX 0x010017 /* GPIO on IXP4XX systems */ +#define I2C_HW_B_S3VIA 0x010018 /* S3Via ProSavage adapter */ +#define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ +#define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ +#define I2C_HW_B_CX2388x 0x01001b /* connexant 2388x based tv cards */ /* --- PCF 8584 based algorithms */ -#define I2C_HW_P_LP 0x00 /* Parallel port interface */ -#define I2C_HW_P_ISA 0x01 /* generic ISA Bus inteface card */ -#define I2C_HW_P_ELEK 0x02 /* Elektor ISA Bus inteface card */ +#define I2C_HW_P_LP 0x020000 /* Parallel port interface */ +#define I2C_HW_P_ISA 0x020001 /* generic ISA Bus inteface card */ +#define I2C_HW_P_ELEK 0x020002 /* Elektor ISA Bus inteface card */ /* --- PCA 9564 based algorithms */ -#define I2C_HW_A_ISA 0x00 /* generic ISA Bus interface card */ +#define I2C_HW_A_ISA 0x1a0000 /* generic ISA Bus interface card */ /* --- ACPI Embedded controller algorithms */ -#define I2C_HW_ACPI_EC 0x00 +#define I2C_HW_ACPI_EC 0x1f0000 /* --- MPC824x PowerPC adapters */ -#define I2C_HW_MPC824X 0x00 /* Motorola 8240 / 8245 */ +#define I2C_HW_MPC824X 0x100001 /* Motorola 8240 / 8245 */ /* --- MPC8xx PowerPC adapters */ -#define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */ +#define I2C_HW_MPC8XX_EPON 0x110000 /* Eponymous MPC8xx I2C adapter */ /* --- ITE based algorithms */ -#define I2C_HW_I_IIC 0x00 /* controller on the ITE */ +#define I2C_HW_I_IIC 0x080000 /* controller on the ITE */ /* --- PowerPC on-chip adapters */ -#define I2C_HW_OCP 0x00 /* IBM on-chip I2C adapter */ +#define I2C_HW_OCP 0x120000 /* IBM on-chip I2C adapter */ /* --- Broadcom SiByte adapters */ -#define I2C_HW_SIBYTE 0x00 +#define I2C_HW_SIBYTE 0x150000 /* --- SGI adapters */ -#define I2C_HW_SGI_VINO 0x00 -#define I2C_HW_SGI_MACE 0x01 +#define I2C_HW_SGI_VINO 0x160000 +#define I2C_HW_SGI_MACE 0x160001 /* --- XSCALE on-chip adapters */ -#define I2C_HW_IOP3XX 0x00 +#define I2C_HW_IOP3XX 0x140000 /* --- Au1550 PSC adapters adapters */ -#define I2C_HW_AU1550_PSC 0x00 +#define I2C_HW_AU1550_PSC 0x1b0000 /* --- SMBus only adapters */ -#define I2C_HW_SMBUS_PIIX4 0x00 -#define I2C_HW_SMBUS_ALI15X3 0x01 -#define I2C_HW_SMBUS_VIA2 0x02 -#define I2C_HW_SMBUS_VOODOO3 0x03 -#define I2C_HW_SMBUS_I801 0x04 -#define I2C_HW_SMBUS_AMD756 0x05 -#define I2C_HW_SMBUS_SIS5595 0x06 -#define I2C_HW_SMBUS_ALI1535 0x07 -#define I2C_HW_SMBUS_SIS630 0x08 -#define I2C_HW_SMBUS_SIS96X 0x09 -#define I2C_HW_SMBUS_AMD8111 0x0a -#define I2C_HW_SMBUS_SCX200 0x0b -#define I2C_HW_SMBUS_NFORCE2 0x0c -#define I2C_HW_SMBUS_W9968CF 0x0d -#define I2C_HW_SMBUS_OV511 0x0e /* OV511(+) USB 1.1 webcam ICs */ -#define I2C_HW_SMBUS_OV518 0x0f /* OV518(+) USB 1.1 webcam ICs */ -#define I2C_HW_SMBUS_OV519 0x10 /* OV519 USB 1.1 webcam IC */ -#define I2C_HW_SMBUS_OVFX2 0x11 /* Cypress/OmniVision FX2 webcam */ +#define I2C_HW_SMBUS_PIIX4 0x040000 +#define I2C_HW_SMBUS_ALI15X3 0x040001 +#define I2C_HW_SMBUS_VIA2 0x040002 +#define I2C_HW_SMBUS_VOODOO3 0x040003 +#define I2C_HW_SMBUS_I801 0x040004 +#define I2C_HW_SMBUS_AMD756 0x040005 +#define I2C_HW_SMBUS_SIS5595 0x040006 +#define I2C_HW_SMBUS_ALI1535 0x040007 +#define I2C_HW_SMBUS_SIS630 0x040008 +#define I2C_HW_SMBUS_SIS96X 0x040009 +#define I2C_HW_SMBUS_AMD8111 0x04000a +#define I2C_HW_SMBUS_SCX200 0x04000b +#define I2C_HW_SMBUS_NFORCE2 0x04000c +#define I2C_HW_SMBUS_W9968CF 0x04000d +#define I2C_HW_SMBUS_OV511 0x04000e /* OV511(+) USB 1.1 webcam ICs */ +#define I2C_HW_SMBUS_OV518 0x04000f /* OV518(+) USB 1.1 webcam ICs */ +#define I2C_HW_SMBUS_OV519 0x040010 /* OV519 USB 1.1 webcam IC */ +#define I2C_HW_SMBUS_OVFX2 0x040011 /* Cypress/OmniVision FX2 webcam */ /* --- ISA pseudo-adapter */ -#define I2C_HW_ISA 0x00 +#define I2C_HW_ISA 0x050000 /* --- IPMI pseudo-adapter */ -#define I2C_HW_IPMI 0x00 +#define I2C_HW_IPMI 0x0b0000 /* --- IPMB adapter */ -#define I2C_HW_IPMB 0x00 +#define I2C_HW_IPMB 0x0c0000 /* --- MCP107 adapter */ -#define I2C_HW_MPC107 0x00 +#define I2C_HW_MPC107 0x0d0000 /* --- Marvell mv64xxx i2c adapter */ -#define I2C_HW_MV64XXX 0x00 +#define I2C_HW_MV64XXX 0x190000 #endif /* LINUX_I2C_ID_H */ diff --git a/include/linux/i2c-isa.h b/include/linux/i2c-isa.h index 54c27e88d101..67e3598c4cec 100644 --- a/include/linux/i2c-isa.h +++ b/include/linux/i2c-isa.h @@ -29,7 +29,7 @@ extern int i2c_isa_del_driver(struct i2c_driver *driver); /* Detect whether we are on the isa bus. This is only useful to hybrid (i2c+isa) drivers. */ #define i2c_is_isa_adapter(adapptr) \ - ((adapptr)->id == (I2C_ALGO_ISA | I2C_HW_ISA)) + ((adapptr)->id == I2C_HW_ISA) #define i2c_is_isa_client(clientptr) \ i2c_is_isa_adapter((clientptr)->adapter) -- cgit v1.2.3-55-g7522 From 1684a984303abbfc39aa8b59b0fe825c717811a9 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 11 Aug 2005 23:51:10 +0200 Subject: [PATCH] I2C: Kill i2c_algorithm.id (6/7) In theory, there should be no more users of I2C_ALGO_* at this point. However, it happens that several drivers were using I2C_ALGO_* for adapter ids, so we need to correct these before we can get rid of all the I2C_ALGO_* definitions. Note that this also fixes a bug in media/video/tvaudio.c: /* don't attach on saa7146 based cards, because dedicated drivers are used */ if ((adap->id & I2C_ALGO_SAA7146)) return 0; This test was plain broken, as it would succeed for many more adapters than just the saa7146: any those id would share at least one bit with the saa7146 id. We are really lucky that the few other adapters we want this driver to work with did not fulfill that condition. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-keywest.c | 1 - drivers/i2c/busses/scx200_acb.c | 2 +- drivers/media/common/saa7146_i2c.c | 2 +- drivers/media/dvb/b2c2/flexcop-i2c.c | 1 - drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | 1 - drivers/media/dvb/pluto2/pluto2.c | 1 - drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 1 - drivers/media/video/ir-kbd-i2c.c | 2 +- drivers/media/video/saa7134/saa7134-i2c.c | 2 +- drivers/media/video/tda9840.c | 2 +- drivers/media/video/tda9887.c | 2 +- drivers/media/video/tea6415c.c | 2 +- drivers/media/video/tea6420.c | 2 +- drivers/media/video/tvaudio.c | 4 ++-- drivers/video/aty/radeon_i2c.c | 2 +- drivers/video/nvidia/nv_i2c.c | 3 +-- drivers/video/riva/rivafb-i2c.c | 3 +-- drivers/video/savage/savagefb-i2c.c | 3 +-- include/linux/i2c-id.h | 7 +++++++ include/media/id.h | 5 ----- 20 files changed, 21 insertions(+), 27 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 5254d2db282c..e60ed6f49a62 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -619,7 +619,6 @@ create_iface(struct device_node *np, struct device *dev) sprintf(chan->adapter.name, "%s %d", np->parent->name, i); chan->iface = iface; chan->chan_no = i; - chan->adapter.id = I2C_ALGO_SMBUS; chan->adapter.algo = &keywest_algorithm; chan->adapter.algo_data = NULL; chan->adapter.client_register = NULL; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 46b9a7594c99..a1d580e05361 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -454,7 +454,7 @@ static int __init scx200_acb_create(int base, int index) i2c_set_adapdata(adapter, iface); snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index); adapter->owner = THIS_MODULE; - adapter->id = I2C_ALGO_SMBUS; + adapter->id = I2C_HW_SMBUS_SCX200; adapter->algo = &scx200_acb_algorithm; adapter->class = I2C_CLASS_HWMON; diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index e413ee7f267a..6284894505c6 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -410,7 +410,7 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c #endif i2c_adapter->algo = &saa7146_algo; i2c_adapter->algo_data = NULL; - i2c_adapter->id = I2C_ALGO_SAA7146; + i2c_adapter->id = I2C_HW_SAA7146; i2c_adapter->timeout = SAA7146_I2C_TIMEOUT; i2c_adapter->retries = SAA7146_I2C_RETRIES; } diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 848910ff3c9c..56495cb6cd02 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -190,7 +190,6 @@ int flexcop_i2c_init(struct flexcop_device *fc) fc->i2c_adap.class = I2C_CLASS_TV_DIGITAL; fc->i2c_adap.algo = &flexcop_algo; fc->i2c_adap.algo_data = NULL; - fc->i2c_adap.id = I2C_ALGO_BIT; if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0) return ret; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 9f0a8d90d146..da970947dfc7 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -27,7 +27,6 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) #endif d->i2c_adap.algo = d->props.i2c_algo; d->i2c_adap.algo_data = NULL; - d->i2c_adap.id = I2C_ALGO_BIT; i2c_set_adapdata(&d->i2c_adap, d); diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 706e0bcb5ede..85b437bbddcd 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -633,7 +633,6 @@ static int __devinit pluto2_probe(struct pci_dev *pdev, i2c_set_adapdata(&pluto->i2c_adap, pluto); strcpy(pluto->i2c_adap.name, DRIVER_NAME); pluto->i2c_adap.owner = THIS_MODULE; - pluto->i2c_adap.id = I2C_ALGO_BIT; pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL; pluto->i2c_adap.dev.parent = &pdev->dev; pluto->i2c_adap.algo_data = &pluto->i2c_bit; diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 11afec52f31f..7daf7b1598a0 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1523,7 +1523,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i #endif ttusb->i2c_adap.algo = &ttusb_dec_algo; ttusb->i2c_adap.algo_data = NULL; - ttusb->i2c_adap.id = I2C_ALGO_BIT; result = i2c_add_adapter(&ttusb->i2c_adap); if (result) { diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index c2f32d522668..feccf08bc0e3 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -432,7 +432,7 @@ static int ir_probe(struct i2c_adapter *adap) case I2C_HW_B_BT848: probe = probe_bttv; break; - case I2C_ALGO_SAA7134: + case I2C_HW_SAA7134: probe = probe_saa7134; break; } diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 0bb1073d94bd..238ac3fdeb4a 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -381,7 +381,7 @@ static struct i2c_adapter saa7134_adap_template = { .class = I2C_CLASS_TV_ANALOG, #endif I2C_DEVNAME("saa7134"), - .id = I2C_ALGO_SAA7134, + .id = I2C_HW_SAA7134, .algo = &saa7134_algo, .client_register = attach_inform, }; diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index c29bdfc3244e..c0594e09d63e 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -205,7 +205,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind) static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_ALGO_SAA7146) { + if (adapter->id != I2C_HW_SAA7146) { dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index f1b1bb5acf70..abb96ce464c7 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -620,7 +620,7 @@ static int tda9887_probe(struct i2c_adapter *adap) switch (adap->id) { case I2C_HW_B_BT848: case I2C_HW_B_RIVA: - case I2C_ALGO_SAA7134: + case I2C_HW_SAA7134: return i2c_probe(adap, &addr_data, tda9887_attach); break; } diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index b44db8a7b94d..8334d6ccd0a0 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -86,7 +86,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind) static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_ALGO_SAA7146) { + if (adapter->id != I2C_HW_SAA7146) { dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 48d4db7d507b..9d09d2d23c2e 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -135,7 +135,7 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if (adapter->id != I2C_ALGO_SAA7146) { + if (adapter->id != I2C_HW_SAA7146) { dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 9420b5f52915..f6aab89593ea 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1548,7 +1548,7 @@ static int chip_probe(struct i2c_adapter *adap) { /* don't attach on saa7146 based cards, because dedicated drivers are used */ - if ((adap->id & I2C_ALGO_SAA7146)) + if (adap->id == I2C_HW_SAA7146) return 0; #ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) @@ -1557,7 +1557,7 @@ static int chip_probe(struct i2c_adapter *adap) switch (adap->id) { case I2C_HW_B_BT848: case I2C_HW_B_RIVA: - case I2C_ALGO_SAA7134: + case I2C_HW_SAA7134: return i2c_probe(adap, &addr_data, chip_attach); } #endif diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 762244164c81..a9d0414e4655 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -75,7 +75,7 @@ static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name) strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; - chan->adapter.id = I2C_ALGO_ATI; + chan->adapter.id = I2C_HW_B_RADEON; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->rinfo->pdev->dev; chan->algo.setsda = radeon_gpio_setsda; diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index 3757c1407c19..1a91bffdda26 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -90,14 +90,13 @@ static int nvidia_gpio_getsda(void *data) return val; } -#define I2C_ALGO_NVIDIA 0x0e0000 static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name) { int rc; strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; - chan->adapter.id = I2C_ALGO_NVIDIA; + chan->adapter.id = I2C_HW_B_NVIDIA; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->par->pci_dev->dev; chan->algo.setsda = nvidia_gpio_setsda; diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c index da1334dfd51d..77151d8e0766 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/riva/rivafb-i2c.c @@ -92,14 +92,13 @@ static int riva_gpio_getsda(void* data) return val; } -#define I2C_ALGO_RIVA 0x0e0000 static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name) { int rc; strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; - chan->adapter.id = I2C_ALGO_RIVA; + chan->adapter.id = I2C_HW_B_RIVA; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->par->pdev->dev; chan->algo.setsda = riva_gpio_setsda; diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 024a0cecff15..847698b5cfe7 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c @@ -137,7 +137,6 @@ static int prosavage_gpio_getsda(void* data) return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN)); } -#define I2C_ALGO_SAVAGE 0x0f0000 static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, const char *name) { @@ -147,7 +146,7 @@ static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, if (add_bus && chan->par) { strcpy(chan->adapter.name, name); chan->adapter.owner = THIS_MODULE; - chan->adapter.id = I2C_ALGO_SAVAGE; + chan->adapter.id = I2C_HW_B_SAVAGE; chan->adapter.algo_data = &chan->algo; chan->adapter.dev.parent = &chan->par->pcidev->dev; chan->algo.udelay = 40; diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 5b72f664cc21..d044e738d383 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -245,6 +245,9 @@ #define I2C_HW_B_ZR36067 0x010019 /* Zoran-36057/36067 based boards */ #define I2C_HW_B_PCILYNX 0x01001a /* TI PCILynx I2C adapter */ #define I2C_HW_B_CX2388x 0x01001b /* connexant 2388x based tv cards */ +#define I2C_HW_B_NVIDIA 0x01001c /* nvidia framebuffer driver */ +#define I2C_HW_B_SAVAGE 0x01001d /* savage framebuffer driver */ +#define I2C_HW_B_RADEON 0x01001e /* radeon framebuffer driver */ /* --- PCF 8584 based algorithms */ #define I2C_HW_P_LP 0x020000 /* Parallel port interface */ @@ -317,4 +320,8 @@ /* --- Marvell mv64xxx i2c adapter */ #define I2C_HW_MV64XXX 0x190000 +/* --- Miscellaneous adapters */ +#define I2C_HW_SAA7146 0x060000 /* SAA7146 video decoder bus */ +#define I2C_HW_SAA7134 0x090000 /* SAA7134 video decoder bus */ + #endif /* LINUX_I2C_ID_H */ diff --git a/include/media/id.h b/include/media/id.h index a39a6423914b..801ddef301aa 100644 --- a/include/media/id.h +++ b/include/media/id.h @@ -34,8 +34,3 @@ #ifndef I2C_DRIVERID_SAA6752HS # define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8 #endif - -/* algorithms */ -#ifndef I2C_ALGO_SAA7134 -# define I2C_ALGO_SAA7134 0x090000 -#endif -- cgit v1.2.3-55-g7522 From fae91e72b79ba9a21f0ce7551a1fd7e8984c85a6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 15 Aug 2005 19:57:04 +0200 Subject: [PATCH] I2C: Drop I2C_DEVNAME and i2c_clientname I2C_DEVNAME and i2c_clientname were introduced in 2.5.68 [1] to help media/video driver authors who wanted their code to be compatible with both Linux 2.4 and 2.6. The cause of the incompatibility has gone since [2], so I think we can get rid of them, as they tend to make the code harder to read and longer to preprocess/compile for no more benefit. I'd hope nobody seriously attempts to keep media/video driver compatible across Linux trees anymore, BTW. [1] http://marc.theaimsgroup.com/?l=linux-kernel&m=104930186524598&w=2 [2] http://www.linuxhq.com/kernel/v2.6/0-test3/include/linux/i2c.h Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/media/video/bt832.c | 2 +- drivers/media/video/bttv-i2c.c | 8 ++--- drivers/media/video/cx88/cx88-i2c.c | 8 ++--- drivers/media/video/ir-kbd-i2c.c | 2 +- drivers/media/video/msp3400.c | 4 +-- drivers/media/video/ovcamchip/ovcamchip_core.c | 6 ++-- drivers/media/video/saa7134/saa6752hs.c | 2 +- drivers/media/video/saa7134/saa7134-i2c.c | 6 ++-- drivers/media/video/tda7432.c | 2 +- drivers/media/video/tda9840.c | 2 +- drivers/media/video/tda9875.c | 2 +- drivers/media/video/tda9887.c | 2 +- drivers/media/video/tea6415c.c | 2 +- drivers/media/video/tea6420.c | 2 +- drivers/media/video/tuner-core.c | 2 +- drivers/media/video/tvaudio.c | 41 ++++++++++++-------------- drivers/media/video/tvmixer.c | 8 ++--- drivers/media/video/zoran_card.c | 2 +- drivers/usb/media/w9968cf.c | 8 ++--- include/linux/i2c.h | 7 ----- 20 files changed, 53 insertions(+), 65 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/bt832.c b/drivers/media/video/bt832.c index 67ffed8a7fea..76c1b63ebdf2 100644 --- a/drivers/media/video/bt832.c +++ b/drivers/media/video/bt832.c @@ -241,7 +241,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("bt832"), + .name = "bt832", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index 1db95f75ac68..706dc48df962 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -109,7 +109,7 @@ static struct i2c_adapter bttv_i2c_adap_sw_template = { #ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, #endif - I2C_DEVNAME("bt848"), + .name = "bt848", .id = I2C_HW_B_BT848, .client_register = attach_inform, }; @@ -280,7 +280,7 @@ static struct i2c_adapter bttv_i2c_adap_hw_template = { #ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, #endif - I2C_DEVNAME("bt878"), + .name = "bt878", .id = I2C_HW_B_BT848 /* FIXME */, .algo = &bttv_algo, .client_register = attach_inform, @@ -296,7 +296,7 @@ static int attach_inform(struct i2c_client *client) if (bttv_debug) printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n", btv->c.nr,client->driver->name,client->addr, - i2c_clientname(client)); + client->name); if (!client->driver->command) return 0; @@ -324,7 +324,7 @@ void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) } static struct i2c_client bttv_i2c_client_template = { - I2C_DEVNAME("bttv internal"), + .name = "bttv internal", }; diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index a628a55299c6..7f598039e025 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -95,7 +95,7 @@ static int attach_inform(struct i2c_client *client) struct cx88_core *core = i2c_get_adapdata(client->adapter); dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", - client->driver->name,client->addr,i2c_clientname(client)); + client->driver->name, client->addr, client->name); if (!client->driver->command) return 0; @@ -128,7 +128,7 @@ static int detach_inform(struct i2c_client *client) { struct cx88_core *core = i2c_get_adapdata(client->adapter); - dprintk(1, "i2c detach [client=%s]\n", i2c_clientname(client)); + dprintk(1, "i2c detach [client=%s]\n", client->name); return 0; } @@ -152,7 +152,7 @@ static struct i2c_algo_bit_data cx8800_i2c_algo_template = { /* ----------------------------------------------------------------------- */ static struct i2c_adapter cx8800_i2c_adap_template = { - I2C_DEVNAME("cx2388x"), + .name = "cx2388x", .owner = THIS_MODULE, .id = I2C_HW_B_CX2388x, .client_register = attach_inform, @@ -160,7 +160,7 @@ static struct i2c_adapter cx8800_i2c_adap_template = { }; static struct i2c_client cx8800_i2c_client_template = { - I2C_DEVNAME("cx88xx internal"), + .name = "cx88xx internal", }; static char *i2c_devs[128] = { diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index feccf08bc0e3..1e273ff3f956 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -308,7 +308,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("unset"), + .name = "unset", .driver = &driver }; diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c index e956234abf24..ca02f6f14b00 100644 --- a/drivers/media/video/msp3400.c +++ b/drivers/media/video/msp3400.c @@ -1437,7 +1437,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("(unset)"), + .name = "(unset)", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; @@ -1509,7 +1509,7 @@ static int msp_attach(struct i2c_adapter *adap, int addr, int kind) } /* hello world :-) */ - printk(KERN_INFO "msp34xx: init: chip=%s",i2c_clientname(c)); + printk(KERN_INFO "msp34xx: init: chip=%s", c->name); if (HAVE_NICAM(msp)) printk(" +nicam"); if (HAVE_SIMPLE(msp)) diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c index b98c64ab7c58..2de34ebf0673 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -314,7 +314,7 @@ static int ovcamchip_attach(struct i2c_adapter *adap) } memcpy(c, &client_template, sizeof *c); c->adapter = adap; - strcpy(i2c_clientname(c), "OV????"); + strcpy(c->name, "OV????"); ov = kmalloc(sizeof *ov, GFP_KERNEL); if (!ov) { @@ -328,7 +328,7 @@ static int ovcamchip_attach(struct i2c_adapter *adap) if (rc < 0) goto error; - strcpy(i2c_clientname(c), chip_names[ov->subtype]); + strcpy(c->name, chip_names[ov->subtype]); PDEBUG(1, "Camera chip detection complete"); @@ -421,7 +421,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("(unset)"), + .name = "(unset)", .driver = &driver, }; diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 79d05ea1b69b..382911c6ef22 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -598,7 +598,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("saa6752hs"), + .name = "saa6752hs", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 238ac3fdeb4a..eae6b529713f 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -334,7 +334,7 @@ static int attach_inform(struct i2c_client *client) struct tuner_setup tun_setup; d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", - client->driver->name,client->addr,i2c_clientname(client)); + client->driver->name, client->addr, client->name); if (!client->driver->command) return 0; @@ -380,14 +380,14 @@ static struct i2c_adapter saa7134_adap_template = { #ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, #endif - I2C_DEVNAME("saa7134"), + .name = "saa7134", .id = I2C_HW_SAA7134, .algo = &saa7134_algo, .client_register = attach_inform, }; static struct i2c_client saa7134_client_template = { - I2C_DEVNAME("saa7134 internal"), + .name = "saa7134 internal", }; /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index bc6b6c0cea6d..255b6088ebf9 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -513,7 +513,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("tda7432"), + .name = "tda7432", .driver = &driver, }; diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index c0594e09d63e..1794686612c6 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -231,7 +231,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("tda9840"), + .name = "tda9840", .driver = &driver, }; diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 3eaf2e1211e5..7e3dcdb262b0 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -384,7 +384,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("tda9875"), + .name = "tda9875", .driver = &driver, }; diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index abb96ce464c7..d60fc562aecd 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -793,7 +793,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("tda9887"), + .name = "tda9887", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 8334d6ccd0a0..ee3688348b66 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -200,7 +200,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("tea6415c"), + .name = "tea6415c", .driver = &driver, }; diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 9d09d2d23c2e..17975c19da5e 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -177,7 +177,7 @@ static struct i2c_driver driver = { }; static struct i2c_client client_template = { - I2C_DEVNAME("tea6420"), + .name = "tea6420", .driver = &driver, }; diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index a155e99a263b..3b1893c2ae3b 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -709,7 +709,7 @@ static struct i2c_driver driver = { }, }; static struct i2c_client client_template = { - I2C_DEVNAME("(tuner unset)"), + .name = "(tuner unset)", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index f6aab89593ea..258724b2d6d2 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -162,24 +162,23 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) unsigned char buffer[2]; if (-1 == subaddr) { - dprintk("%s: chip_write: 0x%x\n", - i2c_clientname(&chip->c), val); + dprintk("%s: chip_write: 0x%x\n", chip->c.name, val); chip->shadow.bytes[1] = val; buffer[0] = val; if (1 != i2c_master_send(&chip->c,buffer,1)) { printk(KERN_WARNING "%s: I/O error (write 0x%x)\n", - i2c_clientname(&chip->c), val); + chip->c.name, val); return -1; } } else { dprintk("%s: chip_write: reg%d=0x%x\n", - i2c_clientname(&chip->c), subaddr, val); + chip->c.name, subaddr, val); chip->shadow.bytes[subaddr+1] = val; buffer[0] = subaddr; buffer[1] = val; if (2 != i2c_master_send(&chip->c,buffer,2)) { printk(KERN_WARNING "%s: I/O error (write reg%d=0x%x)\n", - i2c_clientname(&chip->c), subaddr, val); + chip->c.name, subaddr, val); return -1; } } @@ -203,11 +202,10 @@ static int chip_read(struct CHIPSTATE *chip) unsigned char buffer; if (1 != i2c_master_recv(&chip->c,&buffer,1)) { - printk(KERN_WARNING "%s: I/O error (read)\n", - i2c_clientname(&chip->c)); + printk(KERN_WARNING "%s: I/O error (read)\n", chip->c.name); return -1; } - dprintk("%s: chip_read: 0x%x\n",i2c_clientname(&chip->c),buffer); + dprintk("%s: chip_read: 0x%x\n", chip->c.name, buffer); return buffer; } @@ -222,12 +220,11 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) write[0] = subaddr; if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { - printk(KERN_WARNING "%s: I/O error (read2)\n", - i2c_clientname(&chip->c)); + printk(KERN_WARNING "%s: I/O error (read2)\n", chip->c.name); return -1; } dprintk("%s: chip_read2: reg%d=0x%x\n", - i2c_clientname(&chip->c),subaddr,read[0]); + chip->c.name, subaddr, read[0]); return read[0]; } @@ -240,7 +237,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) /* update our shadow register set; print bytes if (debug > 0) */ dprintk("%s: chip_cmd(%s): reg=%d, data:", - i2c_clientname(&chip->c),name,cmd->bytes[0]); + chip->c.name, name, cmd->bytes[0]); for (i = 1; i < cmd->count; i++) { dprintk(" 0x%x",cmd->bytes[i]); chip->shadow.bytes[i+cmd->bytes[0]] = cmd->bytes[i]; @@ -249,7 +246,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) /* send data to the chip */ if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { - printk(KERN_WARNING "%s: I/O error (%s)\n", i2c_clientname(&chip->c), name); + printk(KERN_WARNING "%s: I/O error (%s)\n", chip->c.name, name); return -1; } return 0; @@ -274,9 +271,9 @@ static int chip_thread(void *data) struct CHIPSTATE *chip = data; struct CHIPDESC *desc = chiplist + chip->type; - daemonize("%s",i2c_clientname(&chip->c)); + daemonize("%s", chip->c.name); allow_signal(SIGTERM); - dprintk("%s: thread started\n", i2c_clientname(&chip->c)); + dprintk("%s: thread started\n", chip->c.name); for (;;) { add_wait_queue(&chip->wq, &wait); @@ -288,7 +285,7 @@ static int chip_thread(void *data) try_to_freeze(); if (chip->done || signal_pending(current)) break; - dprintk("%s: thread wakeup\n", i2c_clientname(&chip->c)); + dprintk("%s: thread wakeup\n", chip->c.name); /* don't do anything for radio or if mode != auto */ if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) @@ -301,7 +298,7 @@ static int chip_thread(void *data) mod_timer(&chip->wt, jiffies+2*HZ); } - dprintk("%s: thread exiting\n", i2c_clientname(&chip->c)); + dprintk("%s: thread exiting\n", chip->c.name); complete_and_exit(&chip->texit, 0); return 0; } @@ -314,7 +311,7 @@ static void generic_checkmode(struct CHIPSTATE *chip) if (mode == chip->prevmode) return; - dprintk("%s: thread checkmode\n", i2c_clientname(&chip->c)); + dprintk("%s: thread checkmode\n", chip->c.name); chip->prevmode = mode; if (mode & VIDEO_SOUND_STEREO) @@ -1501,7 +1498,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); /* fill required data structures */ - strcpy(i2c_clientname(&chip->c),desc->name); + strcpy(chip->c.name, desc->name); chip->type = desc-chiplist; chip->shadow.count = desc->registers+1; chip->prevmode = -1; @@ -1538,7 +1535,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) chip->tpid = kernel_thread(chip_thread,(void *)chip,0); if (chip->tpid < 0) printk(KERN_WARNING "%s: kernel_thread() failed\n", - i2c_clientname(&chip->c)); + chip->c.name); wake_up_interruptible(&chip->wq); } return 0; @@ -1591,7 +1588,7 @@ static int chip_command(struct i2c_client *client, struct CHIPSTATE *chip = i2c_get_clientdata(client); struct CHIPDESC *desc = chiplist + chip->type; - dprintk("%s: chip_command 0x%x\n",i2c_clientname(&chip->c),cmd); + dprintk("%s: chip_command 0x%x\n", chip->c.name, cmd); switch (cmd) { case AUDC_SET_INPUT: @@ -1702,7 +1699,7 @@ static struct i2c_driver driver = { static struct i2c_client client_template = { - I2C_DEVNAME("(unset)"), + .name = "(unset)", .flags = I2C_CLIENT_ALLOW_USE, .driver = &driver, }; diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c index f0635b19de30..a43301a154af 100644 --- a/drivers/media/video/tvmixer.c +++ b/drivers/media/video/tvmixer.c @@ -91,7 +91,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm if (cmd == SOUND_MIXER_INFO) { mixer_info info; strlcpy(info.id, "tv card", sizeof(info.id)); - strlcpy(info.name, i2c_clientname(client), sizeof(info.name)); + strlcpy(info.name, client->name, sizeof(info.name)); info.modify_counter = 42 /* FIXME */; if (copy_to_user(argp, &info, sizeof(info))) return -EFAULT; @@ -100,7 +100,7 @@ static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cm if (cmd == SOUND_OLD_MIXER_INFO) { _old_mixer_info info; strlcpy(info.id, "tv card", sizeof(info.id)); - strlcpy(info.name, i2c_clientname(client), sizeof(info.name)); + strlcpy(info.name, client->name, sizeof(info.name)); if (copy_to_user(argp, &info, sizeof(info))) return -EFAULT; return 0; @@ -295,7 +295,7 @@ static int tvmixer_clients(struct i2c_client *client) devices[i].dev = NULL; devices[i].minor = -1; printk("tvmixer: %s unregistered (#1)\n", - i2c_clientname(client)); + client->name); return 0; } } @@ -354,7 +354,7 @@ static void __exit tvmixer_cleanup_module(void) if (devices[i].minor != -1) { unregister_sound_mixer(devices[i].minor); printk("tvmixer: %s unregistered (#2)\n", - i2c_clientname(devices[i].dev)); + devices[i].dev->name); } } } diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 25743085b2d5..eed2acea1779 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -737,7 +737,7 @@ static struct i2c_algo_bit_data zoran_i2c_bit_data_template = { }; static struct i2c_adapter zoran_i2c_adapter_template = { - I2C_DEVNAME("zr36057"), + .name = "zr36057", .id = I2C_HW_B_ZR36067, .algo = NULL, .client_register = zoran_i2c_client_register, diff --git a/drivers/usb/media/w9968cf.c b/drivers/usb/media/w9968cf.c index 83e8dd627154..f36c0b6c6e36 100644 --- a/drivers/usb/media/w9968cf.c +++ b/drivers/usb/media/w9968cf.c @@ -1523,7 +1523,6 @@ static u32 w9968cf_i2c_func(struct i2c_adapter* adap) static int w9968cf_i2c_attach_inform(struct i2c_client* client) { struct w9968cf_device* cam = i2c_get_adapdata(client->adapter); - const char* clientname = i2c_clientname(client); int id = client->driver->id, err = 0; if (id == I2C_DRIVERID_OVCAMCHIP) { @@ -1535,12 +1534,12 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client) } } else { DBG(4, "Rejected client [%s] with driver [%s]", - clientname, client->driver->name) + client->name, client->driver->name) return -EINVAL; } DBG(5, "I2C attach client [%s] with driver [%s]", - clientname, client->driver->name) + client->name, client->driver->name) return 0; } @@ -1549,12 +1548,11 @@ static int w9968cf_i2c_attach_inform(struct i2c_client* client) static int w9968cf_i2c_detach_inform(struct i2c_client* client) { struct w9968cf_device* cam = i2c_get_adapdata(client->adapter); - const char* clientname = i2c_clientname(client); if (cam->sensor_client == client) cam->sensor_client = NULL; - DBG(5, "I2C detach client [%s]", clientname) + DBG(5, "I2C detach client [%s]", client->name) return 0; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 233c153b12b1..1ead5195fde4 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -178,13 +178,6 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) dev_set_drvdata (&dev->dev, data); } -#define I2C_DEVNAME(str) .name = str - -static inline char *i2c_clientname(struct i2c_client *c) -{ - return &c->name[0]; -} - /* * The following structs are for those who like to implement new bus drivers: * i2c_algorithm is the interface to a class of hardware solutions which can -- cgit v1.2.3-55-g7522 From d013a068a5675ecd8e71f585a44e7af0798a4307 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Tue, 6 Sep 2005 15:17:07 -0700 Subject: [PATCH] meye: use dma-mapping constants Use the DMA_32BIT_MASK constant from dma-mapping.h when calling pci_set_dma_mask() or pci_set_consistent_dma_mask() This patch includes dma-mapping.h explicitly because it caused errors on some architectures otherwise. See http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for details Signed-off-by: Tobias Klauser Signed-off-by: Stelian Pop Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/meye.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media/video') diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index fe194012bccf..3f2a882bc20a 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "meye.h" #include @@ -121,7 +122,7 @@ static int ptable_alloc(void) memset(meye.mchip_ptable, 0, sizeof(meye.mchip_ptable)); /* give only 32 bit DMA addresses */ - if (dma_set_mask(&meye.mchip_dev->dev, 0xffffffff)) + if (dma_set_mask(&meye.mchip_dev->dev, DMA_32BIT_MASK)) return -1; meye.mchip_ptable_toc = dma_alloc_coherent(&meye.mchip_dev->dev, -- cgit v1.2.3-55-g7522 From 9c45817f41af987277353e463c78a1c6beb37da2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 6 Sep 2005 15:17:47 -0700 Subject: [PATCH] Remove non-arch consumers of asm/segment.h asm/segment.h varies greatly on different architectures but is clearly deprecated. Removing all non-architecture consumers will make it easier for us to get ride of asm/segment.h all together. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hisax.h | 1 - drivers/media/video/adv7170.c | 1 - drivers/media/video/adv7175.c | 1 - drivers/media/video/bt819.c | 1 - drivers/media/video/bt856.c | 1 - drivers/media/video/saa7111.c | 1 - drivers/media/video/saa7114.c | 1 - drivers/media/video/saa7185.c | 1 - drivers/serial/68328serial.c | 1 - drivers/serial/crisv10.c | 1 - drivers/serial/icom.c | 1 - drivers/serial/mcfserial.c | 1 - drivers/video/q40fb.c | 1 - include/linux/isdn.h | 1 - sound/oss/os.h | 3 --- 15 files changed, 17 deletions(-) (limited to 'drivers/media/video') diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 17cf7663c582..6eb96cba4d29 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 52e32f05d625..1ca2b67aedfb 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index b5ed9544bdea..173bca1e0295 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index c6cfa7c48b04..3ee0afca76a7 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index c13d28658868..8eb871d0e85b 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index f18df53d98ff..fe8a5e453969 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index e0c70f54f073..d9f50e2f7b92 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index e93412f4407c..132aa7943c16 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 9097f2f7b12a..2efb317153ce 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c index 5690594b257b..40d3e7139cfe 100644 --- a/drivers/serial/crisv10.c +++ b/drivers/serial/crisv10.c @@ -446,7 +446,6 @@ static char *serial_version = "$Revision: 1.25 $"; #include #include #include -#include #include #include diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c index 79f8df4d66b7..eb31125c6a30 100644 --- a/drivers/serial/icom.c +++ b/drivers/serial/icom.c @@ -56,7 +56,6 @@ #include #include -#include #include #include #include diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index 8c40167778de..43b03c55f453 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c index 71b69da0c40d..162012bb9264 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/q40fb.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 862083eb58ab..53eaee96065b 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -150,7 +150,6 @@ typedef struct { #include #include #include -#include #include #include #include diff --git a/sound/oss/os.h b/sound/oss/os.h index d6b96297835c..80dce329cc3a 100644 --- a/sound/oss/os.h +++ b/sound/oss/os.h @@ -19,9 +19,6 @@ #include #include #include -#ifdef __alpha__ -#include -#endif #include #include #include -- cgit v1.2.3-55-g7522 From d203a7eca85101f0a8ce1dc139ee91196142da36 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 6 Sep 2005 15:19:37 -0700 Subject: [PATCH] Indycam / VINO drivers Rewrite of the Indycam / VINO video v4l2 drivers for the SGI Indy. Signed-off-by: Ralf Baechle Signed-off-by: Mikael Nousiainen Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Makefile | 2 +- drivers/media/video/indycam.c | 412 ++++ drivers/media/video/indycam.h | 112 ++ drivers/media/video/saa7191.c | 512 +++++ drivers/media/video/saa7191.h | 139 ++ drivers/media/video/vino.c | 4301 +++++++++++++++++++++++++++++++++++++++-- drivers/media/video/vino.h | 61 +- 7 files changed, 5333 insertions(+), 206 deletions(-) create mode 100644 drivers/media/video/indycam.c create mode 100644 drivers/media/video/indycam.h create mode 100644 drivers/media/video/saa7191.c create mode 100644 drivers/media/video/saa7191.h (limited to 'drivers/media/video') diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 810e7aac0a53..3e6f5347da21 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_VIDEO_ZORAN_LML33R10) += saa7114.o adv7170.o zr36060.o obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o videocodec.o obj-$(CONFIG_VIDEO_PMS) += pms.o obj-$(CONFIG_VIDEO_PLANB) += planb.o -obj-$(CONFIG_VIDEO_VINO) += vino.o +obj-$(CONFIG_VIDEO_VINO) += vino.o saa7191.o indycam.o obj-$(CONFIG_VIDEO_STRADIS) += stradis.o obj-$(CONFIG_VIDEO_CPIA) += cpia.o obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c new file mode 100644 index 000000000000..b2b0384cd4b9 --- /dev/null +++ b/drivers/media/video/indycam.c @@ -0,0 +1,412 @@ +/* + * indycam.c - Silicon Graphics IndyCam digital camera driver + * + * Copyright (C) 2003 Ladislav Michl + * Copyright (C) 2004,2005 Mikael Nousiainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +/* IndyCam decodes stream of photons into digital image representation ;-) */ +#include +#include + +#include "indycam.h" + +//#define INDYCAM_DEBUG + +#define INDYCAM_MODULE_VERSION "0.0.3" + +MODULE_DESCRIPTION("SGI IndyCam driver"); +MODULE_VERSION(INDYCAM_MODULE_VERSION); +MODULE_AUTHOR("Mikael Nousiainen "); +MODULE_LICENSE("GPL"); + +#ifdef INDYCAM_DEBUG +#define dprintk(x...) printk("IndyCam: " x); +#define indycam_regdump(client) indycam_regdump_debug(client) +#else +#define dprintk(x...) +#define indycam_regdump(client) +#endif + +#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO) + +struct indycam { + struct i2c_client *client; + int version; +}; + +static struct i2c_driver i2c_driver_indycam; + +static const unsigned char initseq[] = { + INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ + INDYCAM_SHUTTER_DEFAULT, /* INDYCAM_SHUTTER */ + INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */ + 0x00, /* INDYCAM_BRIGHTNESS (read-only) */ + INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */ + INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */ + INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */ + INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */ +}; + +/* IndyCam register handling */ + +static int indycam_read_reg(struct i2c_client *client, unsigned char reg, + unsigned char *value) +{ + int ret; + + if (reg == INDYCAM_RESET) { + dprintk("indycam_read_reg(): " + "skipping write-only register %d\n", reg); + *value = 0; + return 0; + } + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) { + printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, " + "register = 0x%02x\n", reg); + return ret; + } + + *value = (unsigned char)ret; + + return 0; +} + +static int indycam_write_reg(struct i2c_client *client, unsigned char reg, + unsigned char value) +{ + int err; + + if ((reg == INDYCAM_BRIGHTNESS) + || (reg == INDYCAM_VERSION)) { + dprintk("indycam_write_reg(): " + "skipping read-only register %d\n", reg); + return 0; + } + + dprintk("Writing Reg %d = 0x%02x\n", reg, value); + err = i2c_smbus_write_byte_data(client, reg, value); + if (err) { + printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, " + "register = 0x%02x, value = 0x%02x\n", reg, value); + } + return err; +} + +static int indycam_write_block(struct i2c_client *client, unsigned char reg, + unsigned char length, unsigned char *data) +{ + unsigned char i; + int err; + + for (i = reg; i < length; i++) { + err = indycam_write_reg(client, reg + i, data[i]); + if (err) + return err; + } + + return 0; +} + +/* Helper functions */ + +#ifdef INDYCAM_DEBUG +static void indycam_regdump_debug(struct i2c_client *client) +{ + int i; + unsigned char val; + + for (i = 0; i < 9; i++) { + indycam_read_reg(client, i, &val); + dprintk("Reg %d = 0x%02x\n", i, val); + } +} +#endif + +static int indycam_get_controls(struct i2c_client *client, + struct indycam_control *ctrl) +{ + unsigned char ctrl_reg; + + indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg); + ctrl->agc = (ctrl_reg & INDYCAM_CONTROL_AGCENA) + ? INDYCAM_VALUE_ENABLED + : INDYCAM_VALUE_DISABLED; + ctrl->awb = (ctrl_reg & INDYCAM_CONTROL_AWBCTL) + ? INDYCAM_VALUE_ENABLED + : INDYCAM_VALUE_DISABLED; + indycam_read_reg(client, INDYCAM_SHUTTER, + (unsigned char *)&ctrl->shutter); + indycam_read_reg(client, INDYCAM_GAIN, + (unsigned char *)&ctrl->gain); + indycam_read_reg(client, INDYCAM_RED_BALANCE, + (unsigned char *)&ctrl->red_balance); + indycam_read_reg(client, INDYCAM_BLUE_BALANCE, + (unsigned char *)&ctrl->blue_balance); + indycam_read_reg(client, INDYCAM_RED_SATURATION, + (unsigned char *)&ctrl->red_saturation); + indycam_read_reg(client, INDYCAM_BLUE_SATURATION, + (unsigned char *)&ctrl->blue_saturation); + indycam_read_reg(client, INDYCAM_GAMMA, + (unsigned char *)&ctrl->gamma); + + return 0; +} + +static int indycam_set_controls(struct i2c_client *client, + struct indycam_control *ctrl) +{ + unsigned char ctrl_reg; + + indycam_read_reg(client, INDYCAM_CONTROL, &ctrl_reg); + if (ctrl->agc != INDYCAM_VALUE_UNCHANGED) { + if (ctrl->agc) + ctrl_reg |= INDYCAM_CONTROL_AGCENA; + else + ctrl_reg &= ~INDYCAM_CONTROL_AGCENA; + } + if (ctrl->awb != INDYCAM_VALUE_UNCHANGED) { + if (ctrl->awb) + ctrl_reg |= INDYCAM_CONTROL_AWBCTL; + else + ctrl_reg &= ~INDYCAM_CONTROL_AWBCTL; + } + indycam_write_reg(client, INDYCAM_CONTROL, ctrl_reg); + + if (ctrl->shutter >= 0) + indycam_write_reg(client, INDYCAM_SHUTTER, ctrl->shutter); + if (ctrl->gain >= 0) + indycam_write_reg(client, INDYCAM_GAIN, ctrl->gain); + if (ctrl->red_balance >= 0) + indycam_write_reg(client, INDYCAM_RED_BALANCE, + ctrl->red_balance); + if (ctrl->blue_balance >= 0) + indycam_write_reg(client, INDYCAM_BLUE_BALANCE, + ctrl->blue_balance); + if (ctrl->red_saturation >= 0) + indycam_write_reg(client, INDYCAM_RED_SATURATION, + ctrl->red_saturation); + if (ctrl->blue_saturation >= 0) + indycam_write_reg(client, INDYCAM_BLUE_SATURATION, + ctrl->blue_saturation); + if (ctrl->gamma >= 0) + indycam_write_reg(client, INDYCAM_GAMMA, ctrl->gamma); + + return 0; +} + +/* I2C-interface */ + +static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) +{ + int err = 0; + struct indycam *camera; + struct i2c_client *client; + + printk(KERN_INFO "SGI IndyCam driver version %s\n", + INDYCAM_MODULE_VERSION); + + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (!client) + return -ENOMEM; + camera = kmalloc(sizeof(struct indycam), GFP_KERNEL); + if (!camera) { + err = -ENOMEM; + goto out_free_client; + } + + memset(client, 0, sizeof(struct i2c_client)); + memset(camera, 0, sizeof(struct indycam)); + + client->addr = addr; + client->adapter = adap; + client->driver = &i2c_driver_indycam; + client->flags = 0; + strcpy(client->name, "IndyCam client"); + i2c_set_clientdata(client, camera); + + camera->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_camera; + + camera->version = i2c_smbus_read_byte_data(client, INDYCAM_VERSION); + if (camera->version != CAMERA_VERSION_INDY && + camera->version != CAMERA_VERSION_MOOSE) { + err = -ENODEV; + goto out_detach_client; + } + printk(KERN_INFO "IndyCam v%d.%d detected\n", + INDYCAM_VERSION_MAJOR(camera->version), + INDYCAM_VERSION_MINOR(camera->version)); + + indycam_regdump(client); + + // initialize + err = indycam_write_block(client, 0, sizeof(initseq), + (unsigned char *)&initseq); + if (err) { + printk(KERN_ERR "IndyCam initalization failed\n"); + err = -EIO; + goto out_detach_client; + } + + indycam_regdump(client); + + // white balance + err = indycam_write_reg(client, INDYCAM_CONTROL, + INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); + if (err) { + printk(KERN_ERR "IndyCam white balance " + "initialization failed\n"); + err = -EIO; + goto out_detach_client; + } + + indycam_regdump(client); + + printk(KERN_INFO "IndyCam initialized\n"); + + return 0; + +out_detach_client: + i2c_detach_client(client); +out_free_camera: + kfree(camera); +out_free_client: + kfree(client); + return err; +} + +static int indycam_probe(struct i2c_adapter *adap) +{ + /* Indy specific crap */ + if (adap->id == VINO_ADAPTER) + return indycam_attach(adap, INDYCAM_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; +} + +static int indycam_detach(struct i2c_client *client) +{ + struct indycam *camera = i2c_get_clientdata(client); + + i2c_detach_client(client); + kfree(camera); + kfree(client); + return 0; +} + +static int indycam_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + // struct indycam *camera = i2c_get_clientdata(client); + + /* The old video_decoder interface just isn't enough, + * so we'll use some custom commands. */ + switch (cmd) { + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_NTSC; + cap->inputs = 1; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: { + int *iarg = arg; + + *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC | + DECODER_STATUS_COLOR; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_NTSC: + break; + default: + return -EINVAL; + } + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; + + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + // struct video_picture *pic = arg; + /* TODO: convert values for indycam_set_controls() */ + break; + } + case DECODER_INDYCAM_GET_CONTROLS: { + struct indycam_control *ctrl = arg; + indycam_get_controls(client, ctrl); + } + case DECODER_INDYCAM_SET_CONTROLS: { + struct indycam_control *ctrl = arg; + indycam_set_controls(client, ctrl); + } + default: + return -EINVAL; + } + + return 0; +} + +static struct i2c_driver i2c_driver_indycam = { + .owner = THIS_MODULE, + .name = "indycam", + .id = I2C_DRIVERID_INDYCAM, + .flags = I2C_DF_NOTIFY, + .attach_adapter = indycam_probe, + .detach_client = indycam_detach, + .command = indycam_command, +}; + +static int __init indycam_init(void) +{ + return i2c_add_driver(&i2c_driver_indycam); +} + +static void __exit indycam_exit(void) +{ + i2c_del_driver(&i2c_driver_indycam); +} + +module_init(indycam_init); +module_exit(indycam_exit); diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h new file mode 100644 index 000000000000..d9ddb6b79a03 --- /dev/null +++ b/drivers/media/video/indycam.h @@ -0,0 +1,112 @@ +/* + * indycam.h - Silicon Graphics IndyCam digital camera driver + * + * Copyright (C) 2003 Ladislav Michl + * Copyright (C) 2004,2005 Mikael Nousiainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _INDYCAM_H_ +#define _INDYCAM_H_ + +/* I2C address for the Guinness Camera */ +#define INDYCAM_ADDR 0x56 + +/* Camera version */ +#define CAMERA_VERSION_INDY 0x10 /* v1.0 */ +#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */ +#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4) +#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f) + +/* Register bus addresses */ +#define INDYCAM_CONTROL 0x00 +#define INDYCAM_SHUTTER 0x01 +#define INDYCAM_GAIN 0x02 +#define INDYCAM_BRIGHTNESS 0x03 /* read-only */ +#define INDYCAM_RED_BALANCE 0x04 +#define INDYCAM_BLUE_BALANCE 0x05 +#define INDYCAM_RED_SATURATION 0x06 +#define INDYCAM_BLUE_SATURATION 0x07 +#define INDYCAM_GAMMA 0x08 +#define INDYCAM_VERSION 0x0e /* read-only */ +#define INDYCAM_RESET 0x0f /* write-only */ + +#define INDYCAM_LED 0x46 +#define INDYCAM_ORIENTATION 0x47 +#define INDYCAM_BUTTON 0x48 + +/* Field definitions of registers */ +#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */ +#define INDYCAM_CONTROL_AWBCTL (1<<1) /* automatic white balance */ + /* 2-3 are reserved */ +#define INDYCAM_CONTROL_EVNFLD (1<<4) /* read-only */ + +#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */ +#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */ +#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */ +#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */ +#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */ +#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */ +#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */ +#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */ +#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */ + +#define INDYCAM_LED_ACTIVE 0x10 +#define INDYCAM_LED_INACTIVE 0x30 +#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40 +#define INDYCAM_BUTTON_RELEASED 0x10 + +#define INDYCAM_SHUTTER_MIN 0x00 +#define INDYCAM_SHUTTER_MAX 0xff +#define INDYCAM_GAIN_MIN 0x00 +#define INDYCAM_GAIN_MAX 0xff +#define INDYCAM_RED_BALANCE_MIN 0x00 /* the effect is the opposite? */ +#define INDYCAM_RED_BALANCE_MAX 0xff +#define INDYCAM_BLUE_BALANCE_MIN 0x00 /* the effect is the opposite? */ +#define INDYCAM_BLUE_BALANCE_MAX 0xff +#define INDYCAM_RED_SATURATION_MIN 0x00 +#define INDYCAM_RED_SATURATION_MAX 0xff +#define INDYCAM_BLUE_SATURATION_MIN 0x00 +#define INDYCAM_BLUE_SATURATION_MAX 0xff +#define INDYCAM_GAMMA_MIN 0x00 +#define INDYCAM_GAMMA_MAX 0xff + +/* Driver interface definitions */ + +#define INDYCAM_VALUE_ENABLED 1 +#define INDYCAM_VALUE_DISABLED 0 +#define INDYCAM_VALUE_UNCHANGED -1 + +/* When setting controls, a value of -1 leaves the control unchanged. */ +struct indycam_control { + int agc; /* boolean */ + int awb; /* boolean */ + int shutter; + int gain; + int red_balance; + int blue_balance; + int red_saturation; + int blue_saturation; + int gamma; +}; + +#define DECODER_INDYCAM_GET_CONTROLS _IOR('d', 193, struct indycam_control) +#define DECODER_INDYCAM_SET_CONTROLS _IOW('d', 194, struct indycam_control) + +/* Default values for controls */ + +#define INDYCAM_AGC_DEFAULT INDYCAM_VALUE_ENABLED +#define INDYCAM_AWB_DEFAULT INDYCAM_VALUE_ENABLED + +#define INDYCAM_SHUTTER_DEFAULT INDYCAM_SHUTTER_60 +#define INDYCAM_GAIN_DEFAULT 0x80 +#define INDYCAM_RED_BALANCE_DEFAULT 0x18 +#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4 +#define INDYCAM_RED_SATURATION_DEFAULT 0x80 +#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0 +#define INDYCAM_GAMMA_DEFAULT 0x80 + +#endif diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c new file mode 100644 index 000000000000..454f5c1199b4 --- /dev/null +++ b/drivers/media/video/saa7191.c @@ -0,0 +1,512 @@ +/* + * saa7191.c - Philips SAA7191 video decoder driver + * + * Copyright (C) 2003 Ladislav Michl + * Copyright (C) 2004,2005 Mikael Nousiainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "saa7191.h" + +#define SAA7191_MODULE_VERSION "0.0.3" + +MODULE_DESCRIPTION("Philips SAA7191 video decoder driver"); +MODULE_VERSION(SAA7191_MODULE_VERSION); +MODULE_AUTHOR("Mikael Nousiainen "); +MODULE_LICENSE("GPL"); + +#define VINO_ADAPTER (I2C_ALGO_SGI | I2C_HW_SGI_VINO) + +struct saa7191 { + struct i2c_client *client; + + /* the register values are stored here as the actual + * I2C-registers are write-only */ + unsigned char reg[25]; + + unsigned char norm; + unsigned char input; +}; + +static struct i2c_driver i2c_driver_saa7191; + +static const unsigned char initseq[] = { + 0, /* Subaddress */ + 0x50, /* SAA7191_REG_IDEL */ + 0x30, /* SAA7191_REG_HSYB */ + 0x00, /* SAA7191_REG_HSYS */ + 0xe8, /* SAA7191_REG_HCLB */ + 0xb6, /* SAA7191_REG_HCLS */ + 0xf4, /* SAA7191_REG_HPHI */ + 0x01, /* SAA7191_REG_LUMA - chrominance trap active (CVBS) */ + 0x00, /* SAA7191_REG_HUEC */ + 0xf8, /* SAA7191_REG_CKTQ */ + 0xf8, /* SAA7191_REG_CKTS */ + 0x90, /* SAA7191_REG_PLSE */ + 0x90, /* SAA7191_REG_SESE */ + 0x00, /* SAA7191_REG_GAIN */ + 0x0c, /* SAA7191_REG_STDC - not SECAM, slow time constant */ + 0x78, /* SAA7191_REG_IOCK - chrominance from CVBS, GPSW1 & 2 off */ + 0x99, /* SAA7191_REG_CTL3 - automatic field detection */ + 0x00, /* SAA7191_REG_CTL4 */ + 0x2c, /* SAA7191_REG_CHCV */ + 0x00, /* unused */ + 0x00, /* unused */ + 0x34, /* SAA7191_REG_HS6B */ + 0x0a, /* SAA7191_REG_HS6S */ + 0xf4, /* SAA7191_REG_HC6B */ + 0xce, /* SAA7191_REG_HC6S */ + 0xf4, /* SAA7191_REG_HP6I */ +}; + +/* SAA7191 register handling */ + +static unsigned char saa7191_read_reg(struct i2c_client *client, + unsigned char reg) +{ + return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg]; +} + +static int saa7191_read_status(struct i2c_client *client, + unsigned char *value) +{ + int ret; + + ret = i2c_master_recv(client, value, 1); + if (ret < 0) { + printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed"); + return ret; + } + + return 0; +} + + +static int saa7191_write_reg(struct i2c_client *client, unsigned char reg, + unsigned char value) +{ + + ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value; + return i2c_smbus_write_byte_data(client, reg, value); +} + +/* the first byte of data must be the first subaddress number (register) */ +static int saa7191_write_block(struct i2c_client *client, + unsigned char length, unsigned char *data) +{ + int i; + int ret; + + struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client); + for (i = 0; i < (length - 1); i++) { + decoder->reg[data[0] + i] = data[i + 1]; + } + + ret = i2c_master_send(client, data, length); + if (ret < 0) { + printk(KERN_ERR "SAA7191: saa7191_write_block(): " + "write failed"); + return ret; + } + + return 0; +} + +/* Helper functions */ + +static int saa7191_set_input(struct i2c_client *client, int input) +{ + unsigned char luma = saa7191_read_reg(client, SAA7191_REG_LUMA); + unsigned char iock = saa7191_read_reg(client, SAA7191_REG_IOCK); + int err; + + switch (input) { + case SAA7191_INPUT_COMPOSITE: /* Set Composite input */ + iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1 + | SAA7191_IOCK_GPSW2); + /* Chrominance trap active */ + luma &= ~SAA7191_LUMA_BYPS; + break; + case SAA7191_INPUT_SVIDEO: /* Set S-Video input */ + iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2; + /* Chrominance trap bypassed */ + luma |= SAA7191_LUMA_BYPS; + break; + default: + return -EINVAL; + } + + err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma); + if (err) + return -EIO; + err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock); + if (err) + return -EIO; + + return 0; +} + +static int saa7191_set_norm(struct i2c_client *client, int norm) +{ + struct saa7191 *decoder = i2c_get_clientdata(client); + unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC); + unsigned char ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3); + unsigned char chcv = saa7191_read_reg(client, SAA7191_REG_CHCV); + int err; + + switch(norm) { + case SAA7191_NORM_AUTO: { + unsigned char status; + + // does status depend on current norm ? + if (saa7191_read_status(client, &status)) + return -EIO; + + stdc &= ~SAA7191_STDC_SECS; + ctl3 &= ~SAA7191_CTL3_FSEL; + ctl3 |= SAA7191_CTL3_AUFD; + chcv = (status & SAA7191_STATUS_FIDT) + ? SAA7191_CHCV_NTSC : SAA7191_CHCV_PAL; + break; + } + case SAA7191_NORM_PAL: + stdc &= ~SAA7191_STDC_SECS; + ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); + chcv = SAA7191_CHCV_PAL; + break; + case SAA7191_NORM_NTSC: + stdc &= ~SAA7191_STDC_SECS; + ctl3 &= ~SAA7191_CTL3_AUFD; + ctl3 |= SAA7191_CTL3_FSEL; + chcv = SAA7191_CHCV_NTSC; + break; + case SAA7191_NORM_SECAM: + stdc |= SAA7191_STDC_SECS; + ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL); + chcv = SAA7191_CHCV_PAL; + break; + default: + return -EINVAL; + } + + err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3); + if (err) + return -EIO; + err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); + if (err) + return -EIO; + err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv); + if (err) + return -EIO; + + decoder->norm = norm; + + return 0; +} + +static int saa7191_get_controls(struct i2c_client *client, + struct saa7191_control *ctrl) +{ + unsigned char hue = saa7191_read_reg(client, SAA7191_REG_HUEC); + unsigned char stdc = saa7191_read_reg(client, SAA7191_REG_STDC); + + if (hue < 0x80) { + hue += 0x80; + } else { + hue -= 0x80; + } + ctrl->hue = hue; + + ctrl->vtrc = (stdc & SAA7191_STDC_VTRC) + ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; + + return 0; +} + +static int saa7191_set_controls(struct i2c_client *client, + struct saa7191_control *ctrl) +{ + int err; + + if (ctrl->hue >= 0) { + unsigned char hue = ctrl->hue & 0xff; + if (hue < 0x80) { + hue += 0x80; + } else { + hue -= 0x80; + } + err = saa7191_write_reg(client, SAA7191_REG_HUEC, hue); + if (err) + return -EIO; + } + if (ctrl->vtrc >= 0) { + unsigned char stdc = + saa7191_read_reg(client, SAA7191_REG_STDC); + + if (ctrl->vtrc) { + stdc |= SAA7191_STDC_VTRC; + } else { + stdc &= ~SAA7191_STDC_VTRC; + } + + err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc); + if (err) + return -EIO; + } + + return 0; +} + +/* I2C-interface */ + +static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind) +{ + int err = 0; + struct saa7191 *decoder; + struct i2c_client *client; + + printk(KERN_INFO "Philips SAA7191 driver version %s\n", + SAA7191_MODULE_VERSION); + + client = kmalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return -ENOMEM; + decoder = kmalloc(sizeof(*decoder), GFP_KERNEL); + if (!decoder) { + err = -ENOMEM; + goto out_free_client; + } + + memset(client, 0, sizeof(struct i2c_client)); + memset(decoder, 0, sizeof(struct saa7191)); + + client->addr = addr; + client->adapter = adap; + client->driver = &i2c_driver_saa7191; + client->flags = 0; + strcpy(client->name, "saa7191 client"); + i2c_set_clientdata(client, decoder); + + decoder->client = client; + + err = i2c_attach_client(client); + if (err) + goto out_free_decoder; + + decoder->input = SAA7191_INPUT_COMPOSITE; + decoder->norm = SAA7191_NORM_AUTO; + + err = saa7191_write_block(client, sizeof(initseq), + (unsigned char *)initseq); + if (err) { + printk(KERN_ERR "SAA7191 initialization failed\n"); + goto out_detach_client; + } + + printk(KERN_INFO "SAA7191 initialized\n"); + + return 0; + +out_detach_client: + i2c_detach_client(client); +out_free_decoder: + kfree(decoder); +out_free_client: + kfree(client); + return err; +} + +static int saa7191_probe(struct i2c_adapter *adap) +{ + /* Always connected to VINO */ + if (adap->id == VINO_ADAPTER) + return saa7191_attach(adap, SAA7191_ADDR, 0); + /* Feel free to add probe here :-) */ + return -ENODEV; +} + +static int saa7191_detach(struct i2c_client *client) +{ + struct saa7191 *decoder = i2c_get_clientdata(client); + + i2c_detach_client(client); + kfree(decoder); + kfree(client); + return 0; +} + +static int saa7191_command(struct i2c_client *client, unsigned int cmd, + void *arg) +{ + struct saa7191 *decoder = i2c_get_clientdata(client); + + switch (cmd) { + case DECODER_GET_CAPABILITIES: { + struct video_decoder_capability *cap = arg; + + cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC | + VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO; + cap->inputs = (client->adapter->id == VINO_ADAPTER) ? 2 : 1; + cap->outputs = 1; + break; + } + case DECODER_GET_STATUS: { + int *iarg = arg; + unsigned char status; + int res = 0; + + if (saa7191_read_status(client, &status)) { + return -EIO; + } + if ((status & SAA7191_STATUS_HLCK) == 0) + res |= DECODER_STATUS_GOOD; + if (status & SAA7191_STATUS_CODE) + res |= DECODER_STATUS_COLOR; + switch (decoder->norm) { + case SAA7191_NORM_NTSC: + res |= DECODER_STATUS_NTSC; + break; + case SAA7191_NORM_PAL: + res |= DECODER_STATUS_PAL; + break; + case SAA7191_NORM_SECAM: + res |= DECODER_STATUS_SECAM; + break; + case SAA7191_NORM_AUTO: + default: + if (status & SAA7191_STATUS_FIDT) + res |= DECODER_STATUS_NTSC; + else + res |= DECODER_STATUS_PAL; + break; + } + *iarg = res; + break; + } + case DECODER_SET_NORM: { + int *iarg = arg; + + switch (*iarg) { + case VIDEO_MODE_AUTO: + return saa7191_set_norm(client, SAA7191_NORM_AUTO); + case VIDEO_MODE_PAL: + return saa7191_set_norm(client, SAA7191_NORM_PAL); + case VIDEO_MODE_NTSC: + return saa7191_set_norm(client, SAA7191_NORM_NTSC); + case VIDEO_MODE_SECAM: + return saa7191_set_norm(client, SAA7191_NORM_SECAM); + default: + return -EINVAL; + } + break; + } + case DECODER_SET_INPUT: { + int *iarg = arg; + + switch (client->adapter->id) { + case VINO_ADAPTER: + return saa7191_set_input(client, *iarg); + default: + if (*iarg != 0) + return -EINVAL; + } + break; + } + case DECODER_SET_OUTPUT: { + int *iarg = arg; + + /* not much choice of outputs */ + if (*iarg != 0) + return -EINVAL; + break; + } + case DECODER_ENABLE_OUTPUT: { + /* Always enabled */ + break; + } + case DECODER_SET_PICTURE: { + struct video_picture *pic = arg; + unsigned val; + int err; + + val = (pic->hue >> 8) - 0x80; + err = saa7191_write_reg(client, SAA7191_REG_HUEC, val); + if (err) + return -EIO; + break; + } + case DECODER_SAA7191_GET_STATUS: { + struct saa7191_status *status = arg; + unsigned char status_reg; + + if (saa7191_read_status(client, &status_reg)) + return -EIO; + status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0) + ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; + status->ntsc = (status_reg & SAA7191_STATUS_FIDT) + ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; + status->color = (status_reg & SAA7191_STATUS_CODE) + ? SAA7191_VALUE_ENABLED : SAA7191_VALUE_DISABLED; + + status->input = decoder->input; + status->norm = decoder->norm; + } + case DECODER_SAA7191_SET_NORM: { + int *norm = arg; + return saa7191_set_norm(client, *norm); + } + case DECODER_SAA7191_GET_CONTROLS: { + struct saa7191_control *ctrl = arg; + return saa7191_get_controls(client, ctrl); + } + case DECODER_SAA7191_SET_CONTROLS: { + struct saa7191_control *ctrl = arg; + return saa7191_set_controls(client, ctrl); + } + default: + return -EINVAL; + } + + return 0; +} + +static struct i2c_driver i2c_driver_saa7191 = { + .owner = THIS_MODULE, + .name = "saa7191", + .id = I2C_DRIVERID_SAA7191, + .flags = I2C_DF_NOTIFY, + .attach_adapter = saa7191_probe, + .detach_client = saa7191_detach, + .command = saa7191_command +}; + +static int saa7191_init(void) +{ + return i2c_add_driver(&i2c_driver_saa7191); +} + +static void saa7191_exit(void) +{ + i2c_del_driver(&i2c_driver_saa7191); +} + +module_init(saa7191_init); +module_exit(saa7191_exit); diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h new file mode 100644 index 000000000000..272045031435 --- /dev/null +++ b/drivers/media/video/saa7191.h @@ -0,0 +1,139 @@ +/* + * saa7191.h - Philips SAA7191 video decoder driver + * + * Copyright (C) 2003 Ladislav Michl + * Copyright (C) 2004,2005 Mikael Nousiainen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _SAA7191_H_ +#define _SAA7191_H_ + +/* Philips SAA7191 DMSD I2C bus address */ +#define SAA7191_ADDR 0x8a + +/* Register subaddresses. */ +#define SAA7191_REG_IDEL 0x00 +#define SAA7191_REG_HSYB 0x01 +#define SAA7191_REG_HSYS 0x02 +#define SAA7191_REG_HCLB 0x03 +#define SAA7191_REG_HCLS 0x04 +#define SAA7191_REG_HPHI 0x05 +#define SAA7191_REG_LUMA 0x06 +#define SAA7191_REG_HUEC 0x07 +#define SAA7191_REG_CKTQ 0x08 +#define SAA7191_REG_CKTS 0x09 +#define SAA7191_REG_PLSE 0x0a +#define SAA7191_REG_SESE 0x0b +#define SAA7191_REG_GAIN 0x0c +#define SAA7191_REG_STDC 0x0d +#define SAA7191_REG_IOCK 0x0e +#define SAA7191_REG_CTL3 0x0f +#define SAA7191_REG_CTL4 0x10 +#define SAA7191_REG_CHCV 0x11 +#define SAA7191_REG_HS6B 0x14 +#define SAA7191_REG_HS6S 0x15 +#define SAA7191_REG_HC6B 0x16 +#define SAA7191_REG_HC6S 0x17 +#define SAA7191_REG_HP6I 0x18 +#define SAA7191_REG_STATUS 0xff /* not really a subaddress */ + +/* Status Register definitions */ +#define SAA7191_STATUS_CODE 0x01 /* color detected flag */ +#define SAA7191_STATUS_FIDT 0x20 /* format type NTSC/PAL */ +#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked/locked */ +#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */ + +/* Luminance Control Register definitions */ +#define SAA7191_LUMA_BYPS 0x80 + +/* Chroma Gain Control Settings Register definitions */ +/* 0=automatic colour-killer enabled, 1=forced colour on */ +#define SAA7191_GAIN_COLO 0x80 + +/* Standard/Mode Control Register definitions */ +/* tv/vtr mode bit: 0=TV mode (slow time constant), + * 1=VTR mode (fast time constant) */ +#define SAA7191_STDC_VTRC 0x80 +/* SECAM mode bit: 0=other standards, 1=SECAM */ +#define SAA7191_STDC_SECS 0x01 +/* the bit fields above must be or'd with this value */ +#define SAA7191_STDC_VALUE 0x0c + +/* I/O and Clock Control Register definitions */ +/* horizontal clock PLL: 0=PLL closed, + * 1=PLL circuit open and horizontal freq fixed */ +#define SAA7191_IOCK_HPLL 0x80 +/* S-VHS bit (chrominance from CVBS or from chrominance input): + * 0=controlled by BYPS-bit, 1=from chrominance input */ +#define SAA7191_IOCK_CHRS 0x04 +/* general purpose switch 2 + * VINO-specific: 0=used with CVBS, 1=used with S-Video */ +#define SAA7191_IOCK_GPSW2 0x02 +/* general purpose switch 1 */ +/* VINO-specific: 0=always, 1=not used!*/ +#define SAA7191_IOCK_GPSW1 0x01 + +/* Miscellaneous Control #1 Register definitions */ +/* automatic field detection (50/60Hz standard) */ +#define SAA7191_CTL3_AUFD 0x80 +/* field select: (if AUFD=0) + * 0=50Hz (625 lines), 1=60Hz (525 lines) */ +#define SAA7191_CTL3_FSEL 0x40 +/* the bit fields above must be or'd with this value */ +#define SAA7191_CTL3_VALUE 0x19 + +/* Chrominance Gain Control Register definitions + * (nominal value for UV CCIR level) */ +#define SAA7191_CHCV_NTSC 0x2c +#define SAA7191_CHCV_PAL 0x59 + +/* Driver interface definitions */ +#define SAA7191_INPUT_COMPOSITE 0 +#define SAA7191_INPUT_SVIDEO 1 + +#define SAA7191_NORM_AUTO 0 +#define SAA7191_NORM_PAL 1 +#define SAA7191_NORM_NTSC 2 +#define SAA7191_NORM_SECAM 3 + +#define SAA7191_VALUE_ENABLED 1 +#define SAA7191_VALUE_DISABLED 0 +#define SAA7191_VALUE_UNCHANGED -1 + +struct saa7191_status { + /* 0=no signal, 1=signal active*/ + int signal; + /* 0=50hz (pal) signal, 1=60hz (ntsc) signal */ + int ntsc; + /* 0=no color detected, 1=color detected */ + int color; + + /* current SAA7191_INPUT_ */ + int input; + /* current SAA7191_NORM_ */ + int norm; +}; + +#define SAA7191_HUE_MIN 0x00 +#define SAA7191_HUE_MAX 0xff +#define SAA7191_HUE_DEFAULT 0x80 + +#define SAA7191_VTRC_MIN 0x00 +#define SAA7191_VTRC_MAX 0x01 +#define SAA7191_VTRC_DEFAULT 0x00 + +struct saa7191_control { + int hue; + int vtrc; +}; + +#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status) +#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int) +#define DECODER_SAA7191_GET_CONTROLS _IOR('d', 197, struct saa7191_control) +#define DECODER_SAA7191_SET_CONTROLS _IOW('d', 198, struct saa7191_control) + +#endif diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 76e8681d65c6..d8a0f763ca10 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -1,80 +1,606 @@ /* - * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys. + * Driver for the VINO (Video In No Out) system found in SGI Indys. * * This file is subject to the terms and conditions of the GNU General Public * License version 2 as published by the Free Software Foundation. * + * Copyright (C) 2004,2005 Mikael Nousiainen + * + * Based on the previous version of the driver for 2.4 kernels by: * Copyright (C) 2003 Ladislav Michl */ -#include +/* + * TODO: + * - remove "hacks" from memory allocation code and implement nopage() + * - check decimation, calculating and reporting image size when + * using decimation + * - check vino_acquire_input(), vino_set_input() and channel + * ownership handling + * - report VINO error-interrupts via ioctls ? + * - implement picture controls (all implemented?) + * - use macros for boolean values (?) + * - implement user mode buffers and overlay (?) + */ + #include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_KMOD +#include +#endif + #include #include -#include -#include -#include -#include +#include +#include +#include + #include #include #include -#include #include #include "vino.h" +#include "saa7191.h" +#include "indycam.h" -/* debugging? */ -#if 1 -#define DEBUG(x...) printk(x); +/* Uncomment the following line to get lots and lots of (mostly useless) + * debug info. + * Note that the debug output also slows down the driver significantly */ +// #define VINO_DEBUG + +#define VINO_MODULE_VERSION "0.0.3" +#define VINO_VERSION_CODE KERNEL_VERSION(0, 0, 3) + +MODULE_DESCRIPTION("SGI VINO Video4Linux2 driver"); +MODULE_VERSION(VINO_MODULE_VERSION); +MODULE_AUTHOR("Mikael Nousiainen "); +MODULE_LICENSE("GPL"); + +#define mem_map_reserve(p) set_bit(PG_reserved, &((p)->flags)) +#define mem_map_unreserve(p) clear_bit(PG_reserved, &((p)->flags)) + +#ifdef VINO_DEBUG +#define dprintk(x...) printk("VINO: " x); #else -#define DEBUG(x...) +#define dprintk(x...) #endif +#define VINO_NO_CHANNEL 0 +#define VINO_CHANNEL_A 1 +#define VINO_CHANNEL_B 2 + +#define VINO_PAL_WIDTH 768 +#define VINO_PAL_HEIGHT 576 +#define VINO_NTSC_WIDTH 640 +#define VINO_NTSC_HEIGHT 480 + +#define VINO_MIN_WIDTH 32 +#define VINO_MIN_HEIGHT 32 + +#define VINO_CLIPPING_START_ODD_D1 1 +#define VINO_CLIPPING_START_ODD_PAL 1 +#define VINO_CLIPPING_START_ODD_NTSC 1 + +#define VINO_CLIPPING_START_EVEN_D1 2 +#define VINO_CLIPPING_START_EVEN_PAL 2 +#define VINO_CLIPPING_START_EVEN_NTSC 2 + +#define VINO_INPUT_CHANNEL_COUNT 3 + +#define VINO_INPUT_NONE -1 +#define VINO_INPUT_COMPOSITE 0 +#define VINO_INPUT_SVIDEO 1 +#define VINO_INPUT_D1 2 + +#define VINO_PAGE_RATIO (PAGE_SIZE / VINO_PAGE_SIZE) + +#define VINO_FIFO_THRESHOLD_DEFAULT 512 + +/*#define VINO_FRAMEBUFFER_SIZE (VINO_PAL_WIDTH * VINO_PAL_HEIGHT * 4 \ + + 2 * PAGE_SIZE)*/ +#define VINO_FRAMEBUFFER_SIZE ((VINO_PAL_WIDTH \ + * VINO_PAL_HEIGHT * 4 \ + + 3 * PAGE_SIZE) & ~(PAGE_SIZE - 1)) + +#define VINO_FRAMEBUFFER_MAX_COUNT 8 + +#define VINO_FRAMEBUFFER_UNUSED 0 +#define VINO_FRAMEBUFFER_IN_USE 1 +#define VINO_FRAMEBUFFER_READY 2 + +#define VINO_QUEUE_ERROR -1 +#define VINO_QUEUE_MAGIC 0x20050125 + +#define VINO_MEMORY_NONE 0 +#define VINO_MEMORY_MMAP 1 +#define VINO_MEMORY_USERPTR 2 + +#define VINO_DUMMY_DESC_COUNT 4 +#define VINO_DESC_FETCH_DELAY 5 /* microseconds */ + +/* the number is the index for vino_data_formats */ +#define VINO_DATA_FMT_NONE -1 +#define VINO_DATA_FMT_GREY 0 +#define VINO_DATA_FMT_RGB332 1 +#define VINO_DATA_FMT_RGB32 2 +#define VINO_DATA_FMT_YUV 3 +//#define VINO_DATA_FMT_RGB24 4 + +#define VINO_DATA_FMT_COUNT 4 + +#define VINO_DATA_NORM_NONE -1 +#define VINO_DATA_NORM_NTSC 0 +#define VINO_DATA_NORM_PAL 1 +#define VINO_DATA_NORM_SECAM 2 +#define VINO_DATA_NORM_D1 3 +/* The following is a special entry that can be used to + * autodetect the norm. */ +#define VINO_DATA_NORM_AUTO 0xff + +#define VINO_DATA_NORM_COUNT 4 + +/* Internal data structure definitions */ + +struct vino_input { + char *name; + v4l2_std_id std; +}; + +struct vino_clipping { + unsigned int left, right, top, bottom; +}; + +struct vino_data_format { + /* the description */ + char *description; + /* bytes per pixel */ + unsigned int bpp; + /* V4L2 fourcc code */ + __u32 pixelformat; + /* V4L2 colorspace (duh!) */ + enum v4l2_colorspace colorspace; +}; + +struct vino_data_norm { + char *description; + unsigned int width, height; + struct vino_clipping odd; + struct vino_clipping even; + + v4l2_std_id std; + unsigned int fps_min, fps_max; + __u32 framelines; +}; + +struct vino_descriptor_table { + /* the number of PAGE_SIZE sized pages in the buffer */ + unsigned int page_count; + /* virtual (kmalloc'd) pointers to the actual data + * (in PAGE_SIZE chunks, used with mmap streaming) */ + unsigned long *virtual; + + /* cpu address for the VINO descriptor table + * (contains DMA addresses, VINO_PAGE_SIZE chunks) */ + unsigned long *dma_cpu; + /* dma address for the VINO descriptor table + * (contains DMA addresses, VINO_PAGE_SIZE chunks) */ + dma_addr_t dma; +}; + +struct vino_framebuffer { + /* identifier nubmer */ + unsigned int id; + /* the length of the whole buffer */ + unsigned int size; + /* the length of actual data in buffer */ + unsigned int data_size; + /* the data format */ + unsigned int data_format; + /* the state of buffer data */ + unsigned int state; + /* is the buffer mapped in user space? */ + unsigned int map_count; + /* memory offset for mmap() */ + unsigned int offset; + /* frame counter */ + unsigned int frame_counter; + /* timestamp (written when image capture finishes) */ + struct timeval timestamp; + + struct vino_descriptor_table desc_table; + + spinlock_t state_lock; +}; + +struct vino_framebuffer_fifo { + unsigned int length; + + unsigned int used; + unsigned int head; + unsigned int tail; + + unsigned int data[VINO_FRAMEBUFFER_MAX_COUNT]; +}; + +struct vino_framebuffer_queue { + unsigned int magic; + + /* VINO_MEMORY_NONE, VINO_MEMORY_MMAP or VINO_MEMORY_USERPTR */ + unsigned int type; + unsigned int length; + + /* data field of in and out contain index numbers for buffer */ + struct vino_framebuffer_fifo in; + struct vino_framebuffer_fifo out; + + struct vino_framebuffer *buffer[VINO_FRAMEBUFFER_MAX_COUNT]; -/* VINO ASIC registers */ -struct sgi_vino *vino; + spinlock_t queue_lock; + struct semaphore queue_sem; + wait_queue_head_t frame_wait_queue; +}; + +struct vino_channel_settings { + unsigned int channel; + + int input; + unsigned int data_format; + unsigned int data_norm; + struct vino_clipping clipping; + unsigned int decimation; + unsigned int line_size; + unsigned int alpha; + unsigned int fps; + unsigned int framert_reg; + + unsigned int fifo_threshold; + + struct vino_framebuffer_queue fb_queue; + + /* number of the current field */ + unsigned int field; + + /* read in progress */ + int reading; + /* streaming is active */ + int streaming; + /* the driver is currently processing the queue */ + int capturing; + + struct semaphore sem; + spinlock_t capture_lock; -static const char *vinostr = "VINO IndyCam/TV"; -static int threshold_a = 512; -static int threshold_b = 512; + unsigned int users; -struct vino_device { - struct video_device vdev; -#define VINO_CHAN_A 1 -#define VINO_CHAN_B 2 - int chan; + /* V4L support */ + struct video_device *v4l_device; }; struct vino_client { + /* the channel which owns this client: + * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */ + unsigned int owner; struct i2c_client *driver; - int owner; }; -struct vino_video { - struct vino_device chA; - struct vino_device chB; +struct vino_settings { + struct vino_channel_settings a; + struct vino_channel_settings b; struct vino_client decoder; struct vino_client camera; - struct semaphore input_lock; + /* a lock for vino register access */ + spinlock_t vino_lock; + /* a lock for channel input changes */ + spinlock_t input_lock; - /* Loaded into VINO descriptors to clear End Of Descriptors table - * interupt condition */ unsigned long dummy_page; - unsigned int dummy_buf[4] __attribute__((aligned(8))); + struct vino_descriptor_table dummy_desc_table; +}; + +/* Module parameters */ + +/* + * Using vino_pixel_conversion the ARGB32-format pixels supplied + * by the VINO chip can be converted to more common formats + * like RGBA32 (or probably RGB24 in the future). This way we + * can give out data that can be specified correctly with + * the V4L2-definitions. + * + * The pixel format is specified as RGBA32 when no conversion + * is used. + * + * Note that this only affects the 32-bit bit depth. + * + * Use non-zero value to enable conversion. + */ +static int vino_pixel_conversion = 0; +module_param_named(pixelconv, vino_pixel_conversion, int, 0); +MODULE_PARM_DESC(pixelconv, + "enable pixel conversion (non-zero value enables)"); + +/* Internal data structures */ + +static struct sgi_vino *vino; + +static struct vino_settings *vino_drvdata; + +static const char *vino_driver_name = "vino"; +static const char *vino_driver_description = "SGI VINO"; +static const char *vino_bus_name = "GIO64 bus"; +static const char *vino_v4l_device_name_a = "SGI VINO Channel A"; +static const char *vino_v4l_device_name_b = "SGI VINO Channel B"; + +static const struct vino_input vino_inputs[] = { + { + .name = "Composite", + .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, + },{ + .name = "S-Video", + .std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, + },{ + .name = "D1 (IndyCam)", + .std = V4L2_STD_NTSC, + } +}; + +static const struct vino_data_format vino_data_formats[] = { + { + .description = "8-bit greyscale", + .bpp = 1, + .pixelformat = V4L2_PIX_FMT_GREY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, + },{ + .description = "8-bit dithered RGB 3-3-2", + .bpp = 1, + .pixelformat = V4L2_PIX_FMT_RGB332, + .colorspace = V4L2_COLORSPACE_SRGB, + },{ + .description = "32-bit RGB", + .bpp = 4, + .pixelformat = V4L2_PIX_FMT_RGB32, + .colorspace = V4L2_COLORSPACE_SRGB, + },{ + .description = "YUV 4:2:2", + .bpp = 4, + .pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped? + .colorspace = V4L2_COLORSPACE_SMPTE170M, + }/*,{ + .description = "24-bit RGB", + .bpp = 3, + .pixelformat = V4L2_PIX_FMT_RGB24, + .colorspace = V4L2_COLORSPACE_SRGB, + }*/ +}; + +static const struct vino_data_norm vino_data_norms[] = { + { + .description = "NTSC", + .std = V4L2_STD_NTSC, + .fps_min = 6, + .fps_max = 30, + .framelines = 525, + .width = VINO_NTSC_WIDTH, + .height = VINO_NTSC_HEIGHT, + .odd = { + .top = VINO_CLIPPING_START_ODD_NTSC, + .left = 0, + .bottom = VINO_CLIPPING_START_ODD_NTSC + + VINO_NTSC_HEIGHT / 2 - 1, + .right = VINO_NTSC_WIDTH, + }, + .even = { + .top = VINO_CLIPPING_START_EVEN_NTSC, + .left = 0, + .bottom = VINO_CLIPPING_START_EVEN_NTSC + + VINO_NTSC_HEIGHT / 2 - 1, + .right = VINO_NTSC_WIDTH, + }, + },{ + .description = "PAL", + .std = V4L2_STD_PAL, + .fps_min = 5, + .fps_max = 25, + .framelines = 625, + .width = VINO_PAL_WIDTH, + .height = VINO_PAL_HEIGHT, + .odd = { + .top = VINO_CLIPPING_START_ODD_PAL, + .left = 0, + .bottom = VINO_CLIPPING_START_ODD_PAL + + VINO_PAL_HEIGHT / 2 - 1, + .right = VINO_PAL_WIDTH, + }, + .even = { + .top = VINO_CLIPPING_START_EVEN_PAL, + .left = 0, + .bottom = VINO_CLIPPING_START_EVEN_PAL + + VINO_PAL_HEIGHT / 2 - 1, + .right = VINO_PAL_WIDTH, + }, + },{ + .description = "SECAM", + .std = V4L2_STD_SECAM, + .fps_min = 5, + .fps_max = 25, + .framelines = 625, + .width = VINO_PAL_WIDTH, + .height = VINO_PAL_HEIGHT, + .odd = { + .top = VINO_CLIPPING_START_ODD_PAL, + .left = 0, + .bottom = VINO_CLIPPING_START_ODD_PAL + + VINO_PAL_HEIGHT / 2 - 1, + .right = VINO_PAL_WIDTH, + }, + .even = { + .top = VINO_CLIPPING_START_EVEN_PAL, + .left = 0, + .bottom = VINO_CLIPPING_START_EVEN_PAL + + VINO_PAL_HEIGHT / 2 - 1, + .right = VINO_PAL_WIDTH, + }, + },{ + .description = "NTSC (D1 input)", + .std = V4L2_STD_NTSC, + .fps_min = 6, + .fps_max = 30, + .framelines = 525, + .width = VINO_NTSC_WIDTH, + .height = VINO_NTSC_HEIGHT, + .odd = { + .top = VINO_CLIPPING_START_ODD_D1, + .left = 0, + .bottom = VINO_CLIPPING_START_ODD_D1 + + VINO_NTSC_HEIGHT / 2 - 1, + .right = VINO_NTSC_WIDTH, + }, + .even = { + .top = VINO_CLIPPING_START_EVEN_D1, + .left = 0, + .bottom = VINO_CLIPPING_START_EVEN_D1 + + VINO_NTSC_HEIGHT / 2 - 1, + .right = VINO_NTSC_WIDTH, + }, + } +}; + +#define VINO_INDYCAM_V4L2_CONTROL_COUNT 9 + +struct v4l2_queryctrl vino_indycam_v4l2_controls[] = { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Gain Control", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = INDYCAM_AGC_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_AUTO_WHITE_BALANCE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic White Balance", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = INDYCAM_AWB_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = INDYCAM_GAIN_MIN, + .maximum = INDYCAM_GAIN_MAX, + .step = 1, + .default_value = INDYCAM_GAIN_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red Saturation", + .minimum = INDYCAM_RED_SATURATION_MIN, + .maximum = INDYCAM_RED_SATURATION_MAX, + .step = 1, + .default_value = INDYCAM_RED_SATURATION_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE + 1, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue Saturation", + .minimum = INDYCAM_BLUE_SATURATION_MIN, + .maximum = INDYCAM_BLUE_SATURATION_MAX, + .step = 1, + .default_value = INDYCAM_BLUE_SATURATION_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_RED_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Red Balance", + .minimum = INDYCAM_RED_BALANCE_MIN, + .maximum = INDYCAM_RED_BALANCE_MAX, + .step = 1, + .default_value = INDYCAM_RED_BALANCE_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_BLUE_BALANCE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Blue Balance", + .minimum = INDYCAM_BLUE_BALANCE_MIN, + .maximum = INDYCAM_BLUE_BALANCE_MAX, + .step = 1, + .default_value = INDYCAM_BLUE_BALANCE_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Shutter Control", + .minimum = INDYCAM_SHUTTER_MIN, + .maximum = INDYCAM_SHUTTER_MAX, + .step = 1, + .default_value = INDYCAM_SHUTTER_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = INDYCAM_GAMMA_MIN, + .maximum = INDYCAM_GAMMA_MAX, + .step = 1, + .default_value = INDYCAM_GAMMA_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + } +}; + +#define VINO_SAA7191_V4L2_CONTROL_COUNT 2 + +struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = { + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = SAA7191_HUE_MIN, + .maximum = SAA7191_HUE_MAX, + .step = 1, + .default_value = SAA7191_HUE_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + },{ + .id = V4L2_CID_PRIVATE_BASE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "VTR Time Constant", + .minimum = SAA7191_VTRC_MIN, + .maximum = SAA7191_VTRC_MAX, + .step = 1, + .default_value = SAA7191_VTRC_DEFAULT, + .flags = 0, + .reserved = { 0, 0 }, + } }; -static struct vino_video *Vino; +/* VINO I2C bus functions */ unsigned i2c_vino_getctrl(void *data) { @@ -112,49 +638,49 @@ static struct i2c_algo_sgi_data i2c_sgi_vino_data = */ static int i2c_vino_client_reg(struct i2c_client *client) { - int res = 0; + int ret = 0; - down(&Vino->input_lock); + spin_lock(&vino_drvdata->input_lock); switch (client->driver->id) { case I2C_DRIVERID_SAA7191: - if (Vino->decoder.driver) - res = -EBUSY; + if (vino_drvdata->decoder.driver) + ret = -EBUSY; else - Vino->decoder.driver = client; + vino_drvdata->decoder.driver = client; break; case I2C_DRIVERID_INDYCAM: - if (Vino->camera.driver) - res = -EBUSY; + if (vino_drvdata->camera.driver) + ret = -EBUSY; else - Vino->camera.driver = client; + vino_drvdata->camera.driver = client; break; default: - res = -ENODEV; + ret = -ENODEV; } - up(&Vino->input_lock); + spin_unlock(&vino_drvdata->input_lock); - return res; + return ret; } static int i2c_vino_client_unreg(struct i2c_client *client) { - int res = 0; + int ret = 0; - down(&Vino->input_lock); - if (client == Vino->decoder.driver) { - if (Vino->decoder.owner) - res = -EBUSY; + spin_lock(&vino_drvdata->input_lock); + if (client == vino_drvdata->decoder.driver) { + if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL) + ret = -EBUSY; else - Vino->decoder.driver = NULL; - } else if (client == Vino->camera.driver) { - if (Vino->camera.owner) - res = -EBUSY; + vino_drvdata->decoder.driver = NULL; + } else if (client == vino_drvdata->camera.driver) { + if (vino_drvdata->camera.owner != VINO_NO_CHANNEL) + ret = -EBUSY; else - Vino->camera.driver = NULL; + vino_drvdata->camera.driver = NULL; } - up(&Vino->input_lock); + spin_unlock(&vino_drvdata->input_lock); - return res; + return ret; } static struct i2c_adapter vino_i2c_adapter = @@ -176,172 +702,3591 @@ static int vino_i2c_del_bus(void) return i2c_sgi_del_bus(&vino_i2c_adapter); } +static int i2c_camera_command(unsigned int cmd, void *arg) +{ + return vino_drvdata->camera.driver-> + driver->command(vino_drvdata->camera.driver, + cmd, arg); +} -static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static int i2c_decoder_command(unsigned int cmd, void *arg) { + return vino_drvdata->decoder.driver-> + driver->command(vino_drvdata->decoder.driver, + cmd, arg); } -static int vino_open(struct video_device *dev, int flags) +/* VINO framebuffer/DMA descriptor management */ + +static void vino_free_buffer_with_count(struct vino_framebuffer *fb, + unsigned int count) { - struct vino_device *videv = (struct vino_device *)dev; + unsigned int i; - return 0; + dprintk("vino_free_buffer_with_count(): count = %d\n", count); + + for (i = 0; i < count; i++) { + mem_map_unreserve(virt_to_page(fb->desc_table.virtual[i])); + dma_unmap_single(NULL, + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], + PAGE_SIZE, DMA_FROM_DEVICE); + free_page(fb->desc_table.virtual[i]); + } + + dma_free_coherent(NULL, + VINO_PAGE_RATIO * (fb->desc_table.page_count + 4) * + sizeof(dma_addr_t), (void *)fb->desc_table.dma_cpu, + fb->desc_table.dma); + kfree(fb->desc_table.virtual); + + memset(fb, 0, sizeof(struct vino_framebuffer)); +} + +static void vino_free_buffer(struct vino_framebuffer *fb) +{ + vino_free_buffer_with_count(fb, fb->desc_table.page_count); } -static void vino_close(struct video_device *dev) +static int vino_allocate_buffer(struct vino_framebuffer *fb, + unsigned int size) { - struct vino_device *videv = (struct vino_device *)dev; + unsigned int count, i, j; + int ret = 0; + + dprintk("vino_allocate_buffer():\n"); + + if (size < 1) + return -EINVAL; + + memset(fb, 0, sizeof(struct vino_framebuffer)); + + count = ((size / PAGE_SIZE) + 4) & ~3; + + dprintk("vino_allocate_buffer(): size = %d, count = %d\n", + size, count); + + /* allocate memory for table with virtual (page) addresses */ + fb->desc_table.virtual = (unsigned long *) + kmalloc(count * sizeof(unsigned long), GFP_KERNEL); + if (!fb->desc_table.virtual) + return -ENOMEM; + + /* allocate memory for table with dma addresses + * (has space for four extra descriptors) */ + fb->desc_table.dma_cpu = + dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) * + sizeof(dma_addr_t), &fb->desc_table.dma, + GFP_KERNEL | GFP_DMA); + if (!fb->desc_table.dma_cpu) { + ret = -ENOMEM; + goto out_free_virtual; + } + + /* allocate pages for the buffer and acquire the according + * dma addresses */ + for (i = 0; i < count; i++) { + dma_addr_t dma_data_addr; + + fb->desc_table.virtual[i] = + get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!fb->desc_table.virtual[i]) { + ret = -ENOBUFS; + break; + } + + dma_data_addr = + dma_map_single(NULL, + (void *)fb->desc_table.virtual[i], + PAGE_SIZE, DMA_FROM_DEVICE); + + for (j = 0; j < VINO_PAGE_RATIO; j++) { + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] = + dma_data_addr + VINO_PAGE_SIZE * j; + } + + mem_map_reserve(virt_to_page(fb->desc_table.virtual[i])); + } + + /* page_count needs to be set anyway, because the descriptor table has + * been allocated according to this number */ + fb->desc_table.page_count = count; + + if (ret) { + /* the descriptor with index i doesn't contain + * a valid address yet */ + vino_free_buffer_with_count(fb, i); + return ret; + } + + //fb->size = size; + fb->size = count * PAGE_SIZE; + fb->data_format = VINO_DATA_FMT_NONE; + + /* set the dma stop-bit for the last (count+1)th descriptor */ + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP; + return 0; + + out_free_virtual: + kfree(fb->desc_table.virtual); + return ret; } -static int vino_mmap(struct video_device *dev, const char *adr, - unsigned long size) +#if 0 +/* user buffers not fully implemented yet */ +static int vino_prepare_user_buffer(struct vino_framebuffer *fb, + void *user, + unsigned int size) { - struct vino_device *videv = (struct vino_device *)dev; + unsigned int count, i, j; + int ret = 0; + + dprintk("vino_prepare_user_buffer():\n"); + + if (size < 1) + return -EINVAL; + + memset(fb, 0, sizeof(struct vino_framebuffer)); + + count = ((size / PAGE_SIZE)) & ~3; + + dprintk("vino_prepare_user_buffer(): size = %d, count = %d\n", + size, count); + + /* allocate memory for table with virtual (page) addresses */ + fb->desc_table.virtual = (unsigned long *) + kmalloc(count * sizeof(unsigned long), GFP_KERNEL); + if (!fb->desc_table.virtual) + return -ENOMEM; + + /* allocate memory for table with dma addresses + * (has space for four extra descriptors) */ + fb->desc_table.dma_cpu = + dma_alloc_coherent(NULL, VINO_PAGE_RATIO * (count + 4) * + sizeof(dma_addr_t), &fb->desc_table.dma, + GFP_KERNEL | GFP_DMA); + if (!fb->desc_table.dma_cpu) { + ret = -ENOMEM; + goto out_free_virtual; + } + + /* allocate pages for the buffer and acquire the according + * dma addresses */ + for (i = 0; i < count; i++) { + dma_addr_t dma_data_addr; + + fb->desc_table.virtual[i] = + get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!fb->desc_table.virtual[i]) { + ret = -ENOBUFS; + break; + } + + dma_data_addr = + dma_map_single(NULL, + (void *)fb->desc_table.virtual[i], + PAGE_SIZE, DMA_FROM_DEVICE); + + for (j = 0; j < VINO_PAGE_RATIO; j++) { + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i + j] = + dma_data_addr + VINO_PAGE_SIZE * j; + } + + mem_map_reserve(virt_to_page(fb->desc_table.virtual[i])); + } - return -EINVAL; + /* page_count needs to be set anyway, because the descriptor table has + * been allocated according to this number */ + fb->desc_table.page_count = count; + + if (ret) { + /* the descriptor with index i doesn't contain + * a valid address yet */ + vino_free_buffer_with_count(fb, i); + return ret; + } + + //fb->size = size; + fb->size = count * PAGE_SIZE; + + /* set the dma stop-bit for the last (count+1)th descriptor */ + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * count] = VINO_DESC_STOP; + return 0; + + out_free_virtual: + kfree(fb->desc_table.virtual); + return ret; } +#endif -static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg) +static void vino_sync_buffer(struct vino_framebuffer *fb) { - struct vino_device *videv = (struct vino_device *)dev; + int i; + + dprintk("vino_sync_buffer():\n"); - return -EINVAL; + for (i = 0; i < fb->desc_table.page_count; i++) + dma_sync_single(NULL, + fb->desc_table.dma_cpu[VINO_PAGE_RATIO * i], + PAGE_SIZE, DMA_FROM_DEVICE); } -static const struct video_device vino_device = { - .owner = THIS_MODULE, - .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE, - .hardware = VID_HARDWARE_VINO, - .name = "VINO", - .open = vino_open, - .close = vino_close, - .ioctl = vino_ioctl, - .mmap = vino_mmap, -}; +/* Framebuffer fifo functions (need to be locked externally) */ -static int __init vino_init(void) +static void vino_fifo_init(struct vino_framebuffer_fifo *f, + unsigned int length) { - unsigned long rev; - int i, ret = 0; + f->length = 0; + f->used = 0; + f->head = 0; + f->tail = 0; - /* VINO is Indy specific beast */ - if (ip22_is_fullhouse()) - return -ENODEV; + if (length > VINO_FRAMEBUFFER_MAX_COUNT) + length = VINO_FRAMEBUFFER_MAX_COUNT; - /* - * VINO is in the EISA address space, so the sysid register will tell - * us if the EISA_PRESENT pin on MC has been pulled low. - * - * If EISA_PRESENT is not set we definitely don't have a VINO equiped - * system. - */ - if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { - printk(KERN_ERR "VINO not found\n"); - return -ENODEV; + f->length = length; +} + +/* returns true/false */ +static int vino_fifo_has_id(struct vino_framebuffer_fifo *f, unsigned int id) +{ + unsigned int i; + for (i = f->head; i == (f->tail - 1); i = (i + 1) % f->length) { + if (f->data[i] == id) + return 1; } - vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); - if (!vino) - return -EIO; + return 0; +} - /* Okay, once we know that VINO is present we'll read its revision - * safe way. One never knows... */ - if (get_dbe(rev, &(vino->rev_id))) { - printk(KERN_ERR "VINO: failed to read revision register\n"); - ret = -ENODEV; - goto out_unmap; +/* returns true/false */ +static int vino_fifo_full(struct vino_framebuffer_fifo *f) +{ + return (f->used == f->length); +} + +static unsigned int vino_fifo_get_used(struct vino_framebuffer_fifo *f) +{ + return f->used; +} + +static int vino_fifo_enqueue(struct vino_framebuffer_fifo *f, unsigned int id) +{ + if (id >= f->length) { + return VINO_QUEUE_ERROR; } - if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) { - printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev); - ret = -ENODEV; - goto out_unmap; + + if (vino_fifo_has_id(f, id)) { + return VINO_QUEUE_ERROR; } - printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev)); - Vino = (struct vino_video *) - kmalloc(sizeof(struct vino_video), GFP_KERNEL); - if (!Vino) { - ret = -ENOMEM; - goto out_unmap; + if (f->used < f->length) { + f->data[f->tail] = id; + f->tail = (f->tail + 1) % f->length; + f->used++; + } else { + return VINO_QUEUE_ERROR; } - Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); - if (!Vino->dummy_page) { - ret = -ENOMEM; - goto out_free_vino; + return 0; +} + +static int vino_fifo_peek(struct vino_framebuffer_fifo *f, unsigned int *id) +{ + if (f->used > 0) { + *id = f->data[f->head]; + } else { + return VINO_QUEUE_ERROR; } - for (i = 0; i < 4; i++) - Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page); - vino->control = 0; - /* prevent VINO from throwing spurious interrupts */ - vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf); - vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf); - udelay(5); - vino->intr_status = 0; - /* set threshold level */ - vino->a.fifo_thres = threshold_a; - vino->b.fifo_thres = threshold_b; + return 0; +} + +static int vino_fifo_dequeue(struct vino_framebuffer_fifo *f, unsigned int *id) +{ + if (f->used > 0) { + *id = f->data[f->head]; + f->head = (f->head + 1) % f->length; + f->used--; + } else { + return VINO_QUEUE_ERROR; + } + + return 0; +} - init_MUTEX(&Vino->input_lock); +/* Framebuffer queue functions */ - if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) { - printk(KERN_ERR "VINO: irq%02d registration failed\n", - SGI_VINO_IRQ); - ret = -EAGAIN; - goto out_free_page; +/* execute with queue_lock locked */ +static void vino_queue_free_with_count(struct vino_framebuffer_queue *q, + unsigned int length) +{ + unsigned int i; + + q->length = 0; + memset(&q->in, 0, sizeof(struct vino_framebuffer_fifo)); + memset(&q->out, 0, sizeof(struct vino_framebuffer_fifo)); + for (i = 0; i < length; i++) { + dprintk("vino_queue_free_with_count(): freeing buffer %d\n", + i); + vino_free_buffer(q->buffer[i]); + kfree(q->buffer[i]); } - ret = vino_i2c_add_bus(); - if (ret) { - printk(KERN_ERR "VINO: I2C bus registration failed\n"); - goto out_free_irq; + q->type = VINO_MEMORY_NONE; + q->magic = 0; +} + +static void vino_queue_free(struct vino_framebuffer_queue *q) +{ + dprintk("vino_queue_free():\n"); + + if (q->magic != VINO_QUEUE_MAGIC) + return; + if (q->type != VINO_MEMORY_MMAP) + return; + + down(&q->queue_sem); + + vino_queue_free_with_count(q, q->length); + + up(&q->queue_sem); +} + +static int vino_queue_init(struct vino_framebuffer_queue *q, + unsigned int *length) +{ + unsigned int i; + int ret = 0; + + dprintk("vino_queue_init(): length = %d\n", *length); + + if (q->magic == VINO_QUEUE_MAGIC) { + dprintk("vino_queue_init(): queue already initialized!\n"); + return -EINVAL; } - if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) { - printk("%s, chnl %d: device registration failed.\n", - Vino->chA.vdev.name, Vino->chA.chan); - ret = -EINVAL; - goto out_i2c_del_bus; + if (q->type != VINO_MEMORY_NONE) { + dprintk("vino_queue_init(): queue already initialized!\n"); + return -EINVAL; } - if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) { - printk("%s, chnl %d: device registration failed.\n", - Vino->chB.vdev.name, Vino->chB.chan); - ret = -EINVAL; - goto out_unregister_vdev; + + if (*length < 1) + return -EINVAL; + + down(&q->queue_sem); + + if (*length > VINO_FRAMEBUFFER_MAX_COUNT) + *length = VINO_FRAMEBUFFER_MAX_COUNT; + + q->length = 0; + + for (i = 0; i < *length; i++) { + dprintk("vino_queue_init(): allocating buffer %d\n", i); + q->buffer[i] = kmalloc(sizeof(struct vino_framebuffer), + GFP_KERNEL); + if (!q->buffer[i]) { + dprintk("vino_queue_init(): kmalloc() failed\n"); + ret = -ENOMEM; + break; + } + + ret = vino_allocate_buffer(q->buffer[i], + VINO_FRAMEBUFFER_SIZE); + if (ret) { + kfree(q->buffer[i]); + dprintk("vino_queue_init(): " + "vino_allocate_buffer() failed\n"); + break; + } + + q->buffer[i]->id = i; + if (i > 0) { + q->buffer[i]->offset = q->buffer[i - 1]->offset + + q->buffer[i - 1]->size; + } else { + q->buffer[i]->offset = 0; + } + + spin_lock_init(&q->buffer[i]->state_lock); + + dprintk("vino_queue_init(): buffer = %d, offset = %d, " + "size = %d\n", i, q->buffer[i]->offset, + q->buffer[i]->size); } - return 0; + if (ret) { + vino_queue_free_with_count(q, i); + *length = 0; + } else { + q->length = *length; + vino_fifo_init(&q->in, q->length); + vino_fifo_init(&q->out, q->length); + q->type = VINO_MEMORY_MMAP; + q->magic = VINO_QUEUE_MAGIC; + } -out_unregister_vdev: - video_unregister_device(&Vino->chA.vdev); -out_i2c_del_bus: - vino_i2c_del_bus(); -out_free_irq: - free_irq(SGI_VINO_IRQ, NULL); -out_free_page: - free_page(Vino->dummy_page); -out_free_vino: - kfree(Vino); -out_unmap: - iounmap(vino); + up(&q->queue_sem); return ret; } -static void __exit vino_exit(void) +static struct vino_framebuffer *vino_queue_add(struct + vino_framebuffer_queue *q, + unsigned int id) { - video_unregister_device(&Vino->chA.vdev); - video_unregister_device(&Vino->chB.vdev); - vino_i2c_del_bus(); - free_irq(SGI_VINO_IRQ, NULL); - free_page(Vino->dummy_page); - kfree(Vino); - iounmap(vino); + struct vino_framebuffer *ret = NULL; + unsigned int total; + unsigned long flags; + + dprintk("vino_queue_add(): id = %d\n", id); + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + if (id >= q->length) + goto out; + + /* not needed?: if (vino_fifo_full(&q->out)) { + goto out; + }*/ + /* check that outgoing queue isn't already full + * (or that it won't become full) */ + total = vino_fifo_get_used(&q->in) + + vino_fifo_get_used(&q->out); + if (total >= q->length) + goto out; + + if (vino_fifo_enqueue(&q->in, id)) + goto out; + + ret = q->buffer[id]; + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; } -module_init(vino_init); -module_exit(vino_exit); +static struct vino_framebuffer *vino_queue_transfer(struct + vino_framebuffer_queue *q) +{ + struct vino_framebuffer *ret = NULL; + struct vino_framebuffer *fb; + int id; + unsigned long flags; -MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)"); -MODULE_LICENSE("GPL"); + dprintk("vino_queue_transfer():\n"); + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + // now this actually removes an entry from the incoming queue + if (vino_fifo_dequeue(&q->in, &id)) { + goto out; + } + + dprintk("vino_queue_transfer(): id = %d\n", id); + fb = q->buffer[id]; + + // we have already checked that the outgoing queue is not full, but... + if (vino_fifo_enqueue(&q->out, id)) { + printk(KERN_ERR "vino_queue_transfer(): " + "outgoing queue is full, this shouldn't happen!\n"); + goto out; + } + + ret = fb; +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +/* returns true/false */ +static int vino_queue_incoming_contains(struct vino_framebuffer_queue *q, + unsigned int id) +{ + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + ret = vino_fifo_has_id(&q->in, id); + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +/* returns true/false */ +static int vino_queue_outgoing_contains(struct vino_framebuffer_queue *q, + unsigned int id) +{ + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + ret = vino_fifo_has_id(&q->out, id); + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static int vino_queue_get_incoming(struct vino_framebuffer_queue *q, + unsigned int *used) +{ + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return VINO_QUEUE_ERROR; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) { + ret = VINO_QUEUE_ERROR; + goto out; + } + + *used = vino_fifo_get_used(&q->in); + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static int vino_queue_get_outgoing(struct vino_framebuffer_queue *q, + unsigned int *used) +{ + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return VINO_QUEUE_ERROR; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) { + ret = VINO_QUEUE_ERROR; + goto out; + } + + *used = vino_fifo_get_used(&q->out); + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static int vino_queue_get_total(struct vino_framebuffer_queue *q, + unsigned int *total) +{ + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return VINO_QUEUE_ERROR; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) { + ret = VINO_QUEUE_ERROR; + goto out; + } + + *total = vino_fifo_get_used(&q->in) + + vino_fifo_get_used(&q->out); + +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static struct vino_framebuffer *vino_queue_peek(struct + vino_framebuffer_queue *q, + unsigned int *id) +{ + struct vino_framebuffer *ret = NULL; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + if (vino_fifo_peek(&q->in, id)) { + goto out; + } + + ret = q->buffer[*id]; +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static struct vino_framebuffer *vino_queue_remove(struct + vino_framebuffer_queue *q, + unsigned int *id) +{ + struct vino_framebuffer *ret = NULL; + unsigned long flags; + dprintk("vino_queue_remove():\n"); + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + if (vino_fifo_dequeue(&q->out, id)) { + goto out; + } + + dprintk("vino_queue_remove(): id = %d\n", *id); + ret = q->buffer[*id]; +out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static struct +vino_framebuffer *vino_queue_get_buffer(struct vino_framebuffer_queue *q, + unsigned int id) +{ + struct vino_framebuffer *ret = NULL; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + + if (q->length == 0) + goto out; + + if (id >= q->length) + goto out; + + ret = q->buffer[id]; + out: + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +static unsigned int vino_queue_get_length(struct vino_framebuffer_queue *q) +{ + unsigned int length = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return length; + } + + spin_lock_irqsave(&q->queue_lock, flags); + length = q->length; + spin_unlock_irqrestore(&q->queue_lock, flags); + + return length; +} + +static int vino_queue_has_mapped_buffers(struct vino_framebuffer_queue *q) +{ + unsigned int i; + int ret = 0; + unsigned long flags; + + if (q->magic != VINO_QUEUE_MAGIC) { + return ret; + } + + spin_lock_irqsave(&q->queue_lock, flags); + for (i = 0; i < q->length; i++) { + if (q->buffer[i]->map_count > 0) { + ret = 1; + break; + } + } + spin_unlock_irqrestore(&q->queue_lock, flags); + + return ret; +} + +/* VINO functions */ + +/* execute with input_lock locked */ +static void vino_update_line_size(struct vino_channel_settings *vcs) +{ + unsigned int w = vcs->clipping.right - vcs->clipping.left; + unsigned int d = vcs->decimation; + unsigned int bpp = vino_data_formats[vcs->data_format].bpp; + unsigned int lsize; + + dprintk("update_line_size(): before: w = %d, d = %d, " + "line_size = %d\n", w, d, vcs->line_size); + /* line size must be multiple of 8 bytes */ + lsize = (bpp * (w / d)) & ~7; + w = (lsize / bpp) * d; + + vcs->clipping.right = vcs->clipping.left + w; + vcs->line_size = lsize; + dprintk("update_line_size(): after: w = %d, d = %d, " + "line_size = %d\n", w, d, vcs->line_size); +} + +/* execute with input_lock locked */ +static void vino_set_clipping(struct vino_channel_settings *vcs, + unsigned int x, unsigned int y, + unsigned int w, unsigned int h) +{ + unsigned int maxwidth, maxheight; + unsigned int d; + + maxwidth = vino_data_norms[vcs->data_norm].width; + maxheight = vino_data_norms[vcs->data_norm].height; + d = vcs->decimation; + + y &= ~1; /* odd/even fields */ + + if (x > maxwidth) { + x = 0; + } + if (y > maxheight) { + y = 0; + } + + if (((w / d) < VINO_MIN_WIDTH) + || ((h / d) < VINO_MIN_HEIGHT)) { + w = VINO_MIN_WIDTH * d; + h = VINO_MIN_HEIGHT * d; + } + + if ((x + w) > maxwidth) { + w = maxwidth - x; + if ((w / d) < VINO_MIN_WIDTH) + x = maxwidth - VINO_MIN_WIDTH * d; + } + if ((y + h) > maxheight) { + h = maxheight - y; + if ((h / d) < VINO_MIN_HEIGHT) + y = maxheight - VINO_MIN_HEIGHT * d; + } + + vcs->clipping.left = x; + vcs->clipping.top = y; + vcs->clipping.right = x + w; + vcs->clipping.bottom = y + h; + + vino_update_line_size(vcs); + + dprintk("clipping %d, %d, %d, %d / %d - %d\n", + vcs->clipping.left, vcs->clipping.top, vcs->clipping.right, + vcs->clipping.bottom, vcs->decimation, vcs->line_size); +} + +/* execute with input_lock locked */ +static void vino_set_default_clipping(struct vino_channel_settings *vcs) +{ + vino_set_clipping(vcs, 0, 0, vino_data_norms[vcs->data_norm].width, + vino_data_norms[vcs->data_norm].height); +} + +/* execute with input_lock locked */ +static void vino_set_scaling(struct vino_channel_settings *vcs, + unsigned int w, unsigned int h) +{ + unsigned int x, y, curw, curh, d; + + x = vcs->clipping.left; + y = vcs->clipping.top; + curw = vcs->clipping.right - vcs->clipping.left; + curh = vcs->clipping.bottom - vcs->clipping.top; + + d = max(curw / w, curh / h); + + dprintk("scaling w: %d, h: %d, curw: %d, curh: %d, d: %d\n", + w, h, curw, curh, d); + + if (d < 1) { + d = 1; + } + if (d > 8) { + d = 8; + } + + vcs->decimation = d; + vino_set_clipping(vcs, x, y, w * d, h * d); + + dprintk("scaling %d, %d, %d, %d / %d - %d\n", vcs->clipping.left, + vcs->clipping.top, vcs->clipping.right, vcs->clipping.bottom, + vcs->decimation, vcs->line_size); +} + +/* execute with input_lock locked */ +static void vino_reset_scaling(struct vino_channel_settings *vcs) +{ + vino_set_scaling(vcs, vcs->clipping.right - vcs->clipping.left, + vcs->clipping.bottom - vcs->clipping.top); +} + +/* execute with input_lock locked */ +static void vino_set_framerate(struct vino_channel_settings *vcs, + unsigned int fps) +{ + unsigned int mask; + + switch (vcs->data_norm) { + case VINO_DATA_NORM_NTSC: + case VINO_DATA_NORM_D1: + fps = (unsigned int)(fps / 6) * 6; // FIXME: round! + + if (fps < vino_data_norms[vcs->data_norm].fps_min) + fps = vino_data_norms[vcs->data_norm].fps_min; + if (fps > vino_data_norms[vcs->data_norm].fps_max) + fps = vino_data_norms[vcs->data_norm].fps_max; + + switch (fps) { + case 6: + mask = 0x003; + break; + case 12: + mask = 0x0c3; + break; + case 18: + mask = 0x333; + break; + case 24: + mask = 0x3ff; + break; + case 30: + mask = 0xfff; + break; + default: + mask = VINO_FRAMERT_FULL; + } + vcs->framert_reg = VINO_FRAMERT_RT(mask); + break; + case VINO_DATA_NORM_PAL: + case VINO_DATA_NORM_SECAM: + fps = (unsigned int)(fps / 5) * 5; // FIXME: round! + + if (fps < vino_data_norms[vcs->data_norm].fps_min) + fps = vino_data_norms[vcs->data_norm].fps_min; + if (fps > vino_data_norms[vcs->data_norm].fps_max) + fps = vino_data_norms[vcs->data_norm].fps_max; + + switch (fps) { + case 5: + mask = 0x003; + break; + case 10: + mask = 0x0c3; + break; + case 15: + mask = 0x333; + break; + case 20: + mask = 0x0ff; + break; + case 25: + mask = 0x3ff; + break; + default: + mask = VINO_FRAMERT_FULL; + } + vcs->framert_reg = VINO_FRAMERT_RT(mask) | VINO_FRAMERT_PAL; + break; + } + + vcs->fps = fps; +} + +/* execute with input_lock locked */ +static void vino_set_default_framerate(struct vino_channel_settings *vcs) +{ + vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max); +} + +/* + * Prepare VINO for DMA transfer... + * (execute only with vino_lock and input_lock locked) + */ +static int vino_dma_setup(struct vino_channel_settings *vcs, + struct vino_framebuffer *fb) +{ + u32 ctrl, intr; + struct sgi_vino_channel *ch; + const struct vino_data_norm *norm; + + dprintk("vino_dma_setup():\n"); + + vcs->field = 0; + fb->frame_counter = 0; + + ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b; + norm = &vino_data_norms[vcs->data_norm]; + + ch->page_index = 0; + ch->line_count = 0; + + /* VINO line size register is set 8 bytes less than actual */ + ch->line_size = vcs->line_size - 8; + + /* let VINO know where to transfer data */ + ch->start_desc_tbl = fb->desc_table.dma; + ch->next_4_desc = fb->desc_table.dma; + + /* give vino time to fetch the first four descriptors, 5 usec + * should be more than enough time */ + udelay(VINO_DESC_FETCH_DELAY); + + /* set the alpha register */ + ch->alpha = vcs->alpha; + + /* set clipping registers */ + ch->clip_start = VINO_CLIP_ODD(norm->odd.top + vcs->clipping.top / 2) | + VINO_CLIP_EVEN(norm->even.top + + vcs->clipping.top / 2) | + VINO_CLIP_X(vcs->clipping.left); + ch->clip_end = VINO_CLIP_ODD(norm->odd.top + + vcs->clipping.bottom / 2 - 1) | + VINO_CLIP_EVEN(norm->even.top + + vcs->clipping.bottom / 2 - 1) | + VINO_CLIP_X(vcs->clipping.right); + /* FIXME: end-of-field bug workaround + VINO_CLIP_X(VINO_PAL_WIDTH); + */ + + /* set the size of actual content in the buffer (DECIMATION !) */ + fb->data_size = ((vcs->clipping.right - vcs->clipping.left) / + vcs->decimation) * + ((vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation) * + vino_data_formats[vcs->data_format].bpp; + + ch->frame_rate = vcs->framert_reg; + + ctrl = vino->control; + intr = vino->intr_status; + + if (vcs->channel == VINO_CHANNEL_A) { + /* All interrupt conditions for this channel was cleared + * so clear the interrupt status register and enable + * interrupts */ + intr &= ~VINO_INTSTAT_A; + ctrl |= VINO_CTRL_A_INT; + + /* enable synchronization */ + ctrl |= VINO_CTRL_A_SYNC_ENBL; + + /* enable frame assembly */ + ctrl |= VINO_CTRL_A_INTERLEAVE_ENBL; + + /* set decimation used */ + if (vcs->decimation < 2) + ctrl &= ~VINO_CTRL_A_DEC_ENBL; + else { + ctrl |= VINO_CTRL_A_DEC_ENBL; + ctrl &= ~VINO_CTRL_A_DEC_SCALE_MASK; + ctrl |= (vcs->decimation - 1) << + VINO_CTRL_A_DEC_SCALE_SHIFT; + } + + /* select input interface */ + if (vcs->input == VINO_INPUT_D1) + ctrl |= VINO_CTRL_A_SELECT; + else + ctrl &= ~VINO_CTRL_A_SELECT; + + /* palette */ + ctrl &= ~(VINO_CTRL_A_LUMA_ONLY | VINO_CTRL_A_RGB | + VINO_CTRL_A_DITHER); + } else { + intr &= ~VINO_INTSTAT_B; + ctrl |= VINO_CTRL_B_INT; + + ctrl |= VINO_CTRL_B_SYNC_ENBL; + ctrl |= VINO_CTRL_B_INTERLEAVE_ENBL; + + if (vcs->decimation < 2) + ctrl &= ~VINO_CTRL_B_DEC_ENBL; + else { + ctrl |= VINO_CTRL_B_DEC_ENBL; + ctrl &= ~VINO_CTRL_B_DEC_SCALE_MASK; + ctrl |= (vcs->decimation - 1) << + VINO_CTRL_B_DEC_SCALE_SHIFT; + + } + if (vcs->input == VINO_INPUT_D1) + ctrl |= VINO_CTRL_B_SELECT; + else + ctrl &= ~VINO_CTRL_B_SELECT; + + ctrl &= ~(VINO_CTRL_B_LUMA_ONLY | VINO_CTRL_B_RGB | + VINO_CTRL_B_DITHER); + } + + /* set palette */ + fb->data_format = vcs->data_format; + + switch (vcs->data_format) { + case VINO_DATA_FMT_GREY: + ctrl |= (vcs->channel == VINO_CHANNEL_A) ? + VINO_CTRL_A_LUMA_ONLY : VINO_CTRL_B_LUMA_ONLY; + break; + case VINO_DATA_FMT_RGB32: + ctrl |= (vcs->channel == VINO_CHANNEL_A) ? + VINO_CTRL_A_RGB : VINO_CTRL_B_RGB; + break; + case VINO_DATA_FMT_YUV: + /* nothing needs to be done */ + break; + case VINO_DATA_FMT_RGB332: + ctrl |= (vcs->channel == VINO_CHANNEL_A) ? + VINO_CTRL_A_RGB | VINO_CTRL_A_DITHER : + VINO_CTRL_B_RGB | VINO_CTRL_B_DITHER; + break; + } + + vino->intr_status = intr; + vino->control = ctrl; + + return 0; +} + +/* (execute only with vino_lock locked) */ +static void vino_dma_start(struct vino_channel_settings *vcs) +{ + u32 ctrl = vino->control; + + dprintk("vino_dma_start():\n"); + ctrl |= (vcs->channel == VINO_CHANNEL_A) ? + VINO_CTRL_A_DMA_ENBL : VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; +} + +/* (execute only with vino_lock locked) */ +static void vino_dma_stop(struct vino_channel_settings *vcs) +{ + u32 ctrl = vino->control; + + ctrl &= (vcs->channel == VINO_CHANNEL_A) ? + ~VINO_CTRL_A_DMA_ENBL : ~VINO_CTRL_B_DMA_ENBL; + vino->control = ctrl; + dprintk("vino_dma_stop():\n"); +} + +/* + * Load dummy page to descriptor registers. This prevents generating of + * spurious interrupts. (execute only with vino_lock locked) + */ +static void vino_clear_interrupt(struct vino_channel_settings *vcs) +{ + struct sgi_vino_channel *ch; + + ch = (vcs->channel == VINO_CHANNEL_A) ? &vino->a : &vino->b; + + ch->page_index = 0; + ch->line_count = 0; + + ch->start_desc_tbl = vino_drvdata->dummy_desc_table.dma; + ch->next_4_desc = vino_drvdata->dummy_desc_table.dma; + + udelay(VINO_DESC_FETCH_DELAY); + dprintk("channel %c clear interrupt condition\n", + (vcs->channel == VINO_CHANNEL_A) ? 'A':'B'); +} + +static int vino_capture(struct vino_channel_settings *vcs, + struct vino_framebuffer *fb) +{ + int err = 0; + unsigned long flags, flags2; + + spin_lock_irqsave(&fb->state_lock, flags); + + if (fb->state == VINO_FRAMEBUFFER_IN_USE) + err = -EBUSY; + fb->state = VINO_FRAMEBUFFER_IN_USE; + + spin_unlock_irqrestore(&fb->state_lock, flags); + + if (err) + return err; + + spin_lock_irqsave(&vino_drvdata->vino_lock, flags); + spin_lock_irqsave(&vino_drvdata->input_lock, flags2); + + vino_dma_setup(vcs, fb); + vino_dma_start(vcs); + + spin_unlock_irqrestore(&vino_drvdata->input_lock, flags2); + spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags); + + return err; +} + +static +struct vino_framebuffer *vino_capture_enqueue(struct + vino_channel_settings *vcs, + unsigned int index) +{ + struct vino_framebuffer *fb; + unsigned long flags; + + dprintk("vino_capture_enqueue():\n"); + + spin_lock_irqsave(&vcs->capture_lock, flags); + + fb = vino_queue_add(&vcs->fb_queue, index); + if (fb == NULL) { + dprintk("vino_capture_enqueue(): vino_queue_add() failed, " + "queue full?\n"); + goto out; + } +out: + spin_unlock_irqrestore(&vcs->capture_lock, flags); + + return fb; +} + +static int vino_capture_next(struct vino_channel_settings *vcs, int start) +{ + struct vino_framebuffer *fb; + unsigned int incoming, id; + int err = 0; + unsigned long flags, flags2; + + dprintk("vino_capture_next():\n"); + + spin_lock_irqsave(&vcs->capture_lock, flags); + + if (start) { + /* start capture only if capture isn't in progress already */ + if (vcs->capturing) { + spin_unlock_irqrestore(&vcs->capture_lock, flags); + return 0; + } + + } else { + /* capture next frame: + * stop capture if capturing is not set */ + if (!vcs->capturing) { + spin_unlock_irqrestore(&vcs->capture_lock, flags); + return 0; + } + } + + err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); + if (err) { + dprintk("vino_capture_next(): vino_queue_get_incoming() " + "failed\n"); + err = -EINVAL; + goto out; + } + if (incoming == 0) { + dprintk("vino_capture_next(): no buffers available\n"); + goto out; + } + + fb = vino_queue_peek(&vcs->fb_queue, &id); + if (fb == NULL) { + dprintk("vino_capture_next(): vino_queue_peek() failed\n"); + err = -EINVAL; + goto out; + } + + spin_lock_irqsave(&fb->state_lock, flags2); + fb->state = VINO_FRAMEBUFFER_UNUSED; + spin_unlock_irqrestore(&fb->state_lock, flags2); + + if (start) { + vcs->capturing = 1; + } + + spin_unlock_irqrestore(&vcs->capture_lock, flags); + + err = vino_capture(vcs, fb); + + return err; + +out: + vcs->capturing = 0; + spin_unlock_irqrestore(&vcs->capture_lock, flags); + + return err; +} + +static int vino_is_capturing(struct vino_channel_settings *vcs) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&vcs->capture_lock, flags); + + ret = vcs->capturing; + + spin_unlock_irqrestore(&vcs->capture_lock, flags); + + return ret; +} + +/* waits until a frame is captured */ +static int vino_wait_for_frame(struct vino_channel_settings *vcs) +{ + wait_queue_t wait; + int err = 0; + + dprintk("vino_wait_for_frame():\n"); + + init_waitqueue_entry(&wait, current); + /* add ourselves into wait queue */ + add_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); + /* and set current state */ + set_current_state(TASK_INTERRUPTIBLE); + + /* to ensure that schedule_timeout will return immediately + * if VINO interrupt was triggred meanwhile */ + schedule_timeout(HZ / 10); + + if (signal_pending(current)) + err = -EINTR; + + remove_wait_queue(&vcs->fb_queue.frame_wait_queue, &wait); + + dprintk("vino_wait_for_frame(): waiting for frame %s\n", + err ? "failed" : "ok"); + + return err; +} + +/* the function assumes that PAGE_SIZE % 4 == 0 */ +static void vino_convert_to_rgba(struct vino_framebuffer *fb) { + unsigned char *pageptr; + unsigned int page, i; + unsigned char a; + + for (page = 0; page < fb->desc_table.page_count; page++) { + pageptr = (unsigned char *)fb->desc_table.virtual[page]; + + for (i = 0; i < PAGE_SIZE; i += 4) { + a = pageptr[0]; + pageptr[0] = pageptr[3]; + pageptr[1] = pageptr[2]; + pageptr[2] = pageptr[1]; + pageptr[3] = a; + pageptr += 4; + } + } +} + +/* checks if the buffer is in correct state and syncs data */ +static int vino_check_buffer(struct vino_channel_settings *vcs, + struct vino_framebuffer *fb) +{ + int err = 0; + unsigned long flags; + + dprintk("vino_check_buffer():\n"); + + spin_lock_irqsave(&fb->state_lock, flags); + switch (fb->state) { + case VINO_FRAMEBUFFER_IN_USE: + err = -EIO; + break; + case VINO_FRAMEBUFFER_READY: + vino_sync_buffer(fb); + fb->state = VINO_FRAMEBUFFER_UNUSED; + break; + default: + err = -EINVAL; + } + spin_unlock_irqrestore(&fb->state_lock, flags); + + if (!err) { + if (vino_pixel_conversion + && (fb->data_format == VINO_DATA_FMT_RGB32)) { + vino_convert_to_rgba(fb); + } + } else if (err && (err != -EINVAL)) { + dprintk("vino_check_buffer(): buffer not ready\n"); + + spin_lock_irqsave(&vino_drvdata->vino_lock, flags); + vino_dma_stop(vcs); + vino_clear_interrupt(vcs); + spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags); + } + + return err; +} + +/* forcefully terminates capture */ +static void vino_capture_stop(struct vino_channel_settings *vcs) +{ + unsigned int incoming = 0, outgoing = 0, id; + unsigned long flags, flags2; + + dprintk("vino_capture_stop():\n"); + + spin_lock_irqsave(&vcs->capture_lock, flags); + /* unset capturing to stop queue processing */ + vcs->capturing = 0; + + spin_lock_irqsave(&vino_drvdata->vino_lock, flags2); + + vino_dma_stop(vcs); + vino_clear_interrupt(vcs); + + spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags2); + + /* remove all items from the queue */ + if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) { + dprintk("vino_capture_stop(): " + "vino_queue_get_incoming() failed\n"); + goto out; + } + while (incoming > 0) { + vino_queue_transfer(&vcs->fb_queue); + + if (vino_queue_get_incoming(&vcs->fb_queue, &incoming)) { + dprintk("vino_capture_stop(): " + "vino_queue_get_incoming() failed\n"); + goto out; + } + } + + if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { + dprintk("vino_capture_stop(): " + "vino_queue_get_outgoing() failed\n"); + goto out; + } + while (outgoing > 0) { + vino_queue_remove(&vcs->fb_queue, &id); + + if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { + dprintk("vino_capture_stop(): " + "vino_queue_get_outgoing() failed\n"); + goto out; + } + } + +out: + spin_unlock_irqrestore(&vcs->capture_lock, flags); +} + +static int vino_capture_failed(struct vino_channel_settings *vcs) +{ + struct vino_framebuffer *fb; + unsigned long flags; + unsigned int i; + int ret; + + dprintk("vino_capture_failed():\n"); + + spin_lock_irqsave(&vino_drvdata->vino_lock, flags); + + vino_dma_stop(vcs); + vino_clear_interrupt(vcs); + + spin_unlock_irqrestore(&vino_drvdata->vino_lock, flags); + + ret = vino_queue_get_incoming(&vcs->fb_queue, &i); + if (ret == VINO_QUEUE_ERROR) { + dprintk("vino_queue_get_incoming() failed\n"); + return -EINVAL; + } + if (i == 0) { + /* no buffers to process */ + return 0; + } + + fb = vino_queue_peek(&vcs->fb_queue, &i); + if (fb == NULL) { + dprintk("vino_queue_peek() failed\n"); + return -EINVAL; + } + + spin_lock_irqsave(&fb->state_lock, flags); + if (fb->state == VINO_FRAMEBUFFER_IN_USE) { + fb->state = VINO_FRAMEBUFFER_UNUSED; + vino_queue_transfer(&vcs->fb_queue); + vino_queue_remove(&vcs->fb_queue, &i); + /* we should actually discard the newest frame, + * but who cares ... */ + } + spin_unlock_irqrestore(&fb->state_lock, flags); + + return 0; +} + +static void vino_frame_done(struct vino_channel_settings *vcs, + unsigned int fc) +{ + struct vino_framebuffer *fb; + unsigned long flags; + + spin_lock_irqsave(&vcs->capture_lock, flags); + fb = vino_queue_transfer(&vcs->fb_queue); + if (!fb) { + spin_unlock_irqrestore(&vcs->capture_lock, flags); + dprintk("vino_frame_done(): vino_queue_transfer() failed!\n"); + return; + } + spin_unlock_irqrestore(&vcs->capture_lock, flags); + + fb->frame_counter = fc; + do_gettimeofday(&fb->timestamp); + + spin_lock_irqsave(&fb->state_lock, flags); + if (fb->state == VINO_FRAMEBUFFER_IN_USE) + fb->state = VINO_FRAMEBUFFER_READY; + spin_unlock_irqrestore(&fb->state_lock, flags); + + wake_up(&vcs->fb_queue.frame_wait_queue); + + vino_capture_next(vcs, 0); +} + +static irqreturn_t vino_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 intr; + unsigned int fc_a, fc_b; + int done_a = 0; + int done_b = 0; + + spin_lock(&vino_drvdata->vino_lock); + + intr = vino->intr_status; + fc_a = vino->a.field_counter / 2; + fc_b = vino->b.field_counter / 2; + + // TODO: handle error-interrupts in some special way ? + + if (intr & VINO_INTSTAT_A) { + if (intr & VINO_INTSTAT_A_EOF) { + vino_drvdata->a.field++; + if (vino_drvdata->a.field > 1) { + vino_dma_stop(&vino_drvdata->a); + vino_clear_interrupt(&vino_drvdata->a); + vino_drvdata->a.field = 0; + done_a = 1; + } + dprintk("intr: channel A end-of-field interrupt: " + "%04x\n", intr); + } else { + vino_dma_stop(&vino_drvdata->a); + vino_clear_interrupt(&vino_drvdata->a); + done_a = 1; + dprintk("channel A error interrupt: %04x\n", intr); + } + } + if (intr & VINO_INTSTAT_B) { + if (intr & VINO_INTSTAT_B_EOF) { + vino_drvdata->b.field++; + if (vino_drvdata->b.field > 1) { + vino_dma_stop(&vino_drvdata->b); + vino_clear_interrupt(&vino_drvdata->b); + vino_drvdata->b.field = 0; + done_b = 1; + } + dprintk("intr: channel B end-of-field interrupt: " + "%04x\n", intr); + } else { + vino_dma_stop(&vino_drvdata->b); + vino_clear_interrupt(&vino_drvdata->b); + done_b = 1; + dprintk("channel B error interrupt: %04x\n", intr); + } + } + + /* always remember to clear interrupt status */ + vino->intr_status = ~intr; + + spin_unlock(&vino_drvdata->vino_lock); + + if (done_a) { + vino_frame_done(&vino_drvdata->a, fc_a); + dprintk("channel A frame done, interrupt: %d\n", intr); + } + if (done_b) { + vino_frame_done(&vino_drvdata->b, fc_b); + dprintk("channel B frame done, interrupt: %d\n", intr); + } + + return IRQ_HANDLED; +} + +/* VINO video input management */ + +static int vino_get_saa7191_input(int input) +{ + switch (input) { + case VINO_INPUT_COMPOSITE: + return SAA7191_INPUT_COMPOSITE; + case VINO_INPUT_SVIDEO: + return SAA7191_INPUT_SVIDEO; + default: + printk(KERN_ERR "VINO: vino_get_saa7191_input(): " + "invalid input!\n"); + return -1; + } +} + +static int vino_get_saa7191_norm(int norm) +{ + switch (norm) { + case VINO_DATA_NORM_AUTO: + return SAA7191_NORM_AUTO; + case VINO_DATA_NORM_PAL: + return SAA7191_NORM_PAL; + case VINO_DATA_NORM_NTSC: + return SAA7191_NORM_NTSC; + case VINO_DATA_NORM_SECAM: + return SAA7191_NORM_SECAM; + default: + printk(KERN_ERR "VINO: vino_get_saa7191_norm(): " + "invalid norm!\n"); + return -1; + } +} + +/* execute with input_lock locked */ +static int vino_is_input_owner(struct vino_channel_settings *vcs) +{ + switch(vcs->input) { + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + return (vino_drvdata->decoder.owner == vcs->channel); + case VINO_INPUT_D1: + return (vino_drvdata->camera.owner == vcs->channel); + default: + return 0; + } +} + +static int vino_acquire_input(struct vino_channel_settings *vcs) +{ + int ret = 0; + + dprintk("vino_acquire_input():\n"); + + spin_lock(&vino_drvdata->input_lock); + + /* First try D1 and then SAA7191 */ + if (vino_drvdata->camera.driver + && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) { + if (i2c_use_client(vino_drvdata->camera.driver)) { + ret = -ENODEV; + goto out; + } + + vino_drvdata->camera.owner = vcs->channel; + vcs->input = VINO_INPUT_D1; + vcs->data_norm = VINO_DATA_NORM_D1; + } else if (vino_drvdata->decoder.driver + && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) { + int saa7191_input; + int saa7191_norm; + + if (i2c_use_client(vino_drvdata->decoder.driver)) { + ret = -ENODEV; + goto out; + } + + vino_drvdata->decoder.owner = vcs->channel; + vcs->input = VINO_INPUT_COMPOSITE; + vcs->data_norm = VINO_DATA_NORM_PAL; + + saa7191_input = vino_get_saa7191_input(vcs->input); + i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input); + + saa7191_norm = vino_get_saa7191_norm(vcs->data_norm); + i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm); + } else { + vcs->input = (vcs->channel == VINO_CHANNEL_A) ? + vino_drvdata->b.input : vino_drvdata->a.input; + vcs->data_norm = (vcs->channel == VINO_CHANNEL_A) ? + vino_drvdata->b.data_norm : vino_drvdata->a.data_norm; + } + + if (vcs->input == VINO_INPUT_NONE) { + ret = -ENODEV; + goto out; + } + + if (vino_is_input_owner(vcs)) { + vino_set_default_clipping(vcs); + vino_set_default_framerate(vcs); + } + + dprintk("vino_acquire_input(): %s\n", vino_inputs[vcs->input].name); + +out: + spin_unlock(&vino_drvdata->input_lock); + + return ret; +} + +static int vino_set_input(struct vino_channel_settings *vcs, int input) +{ + struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? + &vino_drvdata->b : &vino_drvdata->a; + int ret = 0; + + dprintk("vino_set_input():\n"); + + spin_lock(&vino_drvdata->input_lock); + + if (vcs->input == input) + goto out; + + switch(input) { + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + if (!vino_drvdata->decoder.driver) { + ret = -EINVAL; + goto out; + } + + if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) { + if (i2c_use_client(vino_drvdata->decoder.driver)) { + ret = -ENODEV; + goto out; + } + vino_drvdata->decoder.owner = vcs->channel; + } + + if (vino_drvdata->decoder.owner == vcs->channel) { + int saa7191_input; + int saa7191_norm; + + vcs->input = input; + vcs->data_norm = VINO_DATA_NORM_PAL; + + saa7191_input = vino_get_saa7191_input(vcs->input); + i2c_decoder_command(DECODER_SET_INPUT, &saa7191_input); + saa7191_norm = vino_get_saa7191_norm(vcs->data_norm); + i2c_decoder_command(DECODER_SAA7191_SET_NORM, + &saa7191_norm); + } else { + if (vcs2->input != input) { + ret = -EBUSY; + goto out; + } + + vcs->input = input; + vcs->data_norm = vcs2->data_norm; + } + + if (vino_drvdata->camera.owner == vcs->channel) { + /* Transfer the ownership or release the input */ + if (vcs2->input == VINO_INPUT_D1) { + vino_drvdata->camera.owner = vcs2->channel; + } else { + i2c_release_client(vino_drvdata-> + camera.driver); + vino_drvdata->camera.owner = VINO_NO_CHANNEL; + } + } + break; + case VINO_INPUT_D1: + if (!vino_drvdata->camera.driver) { + ret = -EINVAL; + goto out; + } + + if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) { + if (i2c_use_client(vino_drvdata->camera.driver)) { + ret = -ENODEV; + goto out; + } + vino_drvdata->camera.owner = vcs->channel; + } + + if (vino_drvdata->decoder.owner == vcs->channel) { + /* Transfer the ownership or release the input */ + if ((vcs2->input == VINO_INPUT_COMPOSITE) || + (vcs2->input == VINO_INPUT_SVIDEO)) { + vino_drvdata->decoder.owner = vcs2->channel; + } else { + i2c_release_client(vino_drvdata-> + decoder.driver); + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + } + } + + vcs->input = input; + vcs->data_norm = VINO_DATA_NORM_D1; + break; + default: + ret = -EINVAL; + goto out; + } + + vino_set_default_clipping(vcs); + vino_set_default_framerate(vcs); + + dprintk("vino_set_input(): %s\n", vino_inputs[vcs->input].name); + +out: + spin_unlock(&vino_drvdata->input_lock); + + return ret; +} + +static void vino_release_input(struct vino_channel_settings *vcs) +{ + struct vino_channel_settings *vcs2 = (vcs->channel == VINO_CHANNEL_A) ? + &vino_drvdata->b : &vino_drvdata->a; + + dprintk("vino_release_input():\n"); + + spin_lock(&vino_drvdata->input_lock); + + /* Release ownership of the channel + * and if the other channel takes input from + * the same source, transfer the ownership */ + if (vino_drvdata->camera.owner == vcs->channel) { + if (vcs2->input == VINO_INPUT_D1) { + vino_drvdata->camera.owner = vcs2->channel; + } else { + i2c_release_client(vino_drvdata->camera.driver); + vino_drvdata->camera.owner = VINO_NO_CHANNEL; + } + } else if (vino_drvdata->decoder.owner == vcs->channel) { + if ((vcs2->input == VINO_INPUT_COMPOSITE) || + (vcs2->input == VINO_INPUT_SVIDEO)) { + vino_drvdata->decoder.owner = vcs2->channel; + } else { + i2c_release_client(vino_drvdata->decoder.driver); + vino_drvdata->decoder.owner = VINO_NO_CHANNEL; + } + } + vcs->input = VINO_INPUT_NONE; + + spin_unlock(&vino_drvdata->input_lock); +} + +/* execute with input_lock locked */ +static int vino_set_data_norm(struct vino_channel_settings *vcs, + unsigned int data_norm) +{ + int saa7191_norm; + + switch (vcs->input) { + case VINO_INPUT_D1: + /* only one "norm" supported */ + if (data_norm != VINO_DATA_NORM_D1) + return -EINVAL; + break; + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + + saa7191_norm = vino_get_saa7191_norm(data_norm); + + i2c_decoder_command(DECODER_SAA7191_SET_NORM, &saa7191_norm); + vcs->data_norm = data_norm; + break; + default: + return -EINVAL; + } + + return 0; +} + +/* V4L2 helper functions */ + +static int vino_find_data_format(__u32 pixelformat) +{ + int i; + + for (i = 0; i < VINO_DATA_FMT_COUNT; i++) { + if (vino_data_formats[i].pixelformat == pixelformat) + return i; + } + + return VINO_DATA_FMT_NONE; +} + +static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index) +{ + int data_norm = VINO_DATA_NORM_NONE; + + spin_lock(&vino_drvdata->input_lock); + switch(vcs->input) { + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + if (index == 0) { + data_norm = VINO_DATA_NORM_PAL; + } else if (index == 1) { + data_norm = VINO_DATA_NORM_NTSC; + } else if (index == 2) { + data_norm = VINO_DATA_NORM_SECAM; + } + break; + case VINO_INPUT_D1: + if (index == 0) { + data_norm = VINO_DATA_NORM_D1; + } + break; + } + spin_unlock(&vino_drvdata->input_lock); + + return data_norm; +} + +static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index) +{ + int input = VINO_INPUT_NONE; + + spin_lock(&vino_drvdata->input_lock); + if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { + switch (index) { + case 0: + input = VINO_INPUT_COMPOSITE; + break; + case 1: + input = VINO_INPUT_SVIDEO; + break; + case 2: + input = VINO_INPUT_D1; + break; + } + } else if (vino_drvdata->decoder.driver) { + switch (index) { + case 0: + input = VINO_INPUT_COMPOSITE; + break; + case 1: + input = VINO_INPUT_SVIDEO; + break; + } + } else if (vino_drvdata->camera.driver) { + switch (index) { + case 0: + input = VINO_INPUT_D1; + break; + } + } + spin_unlock(&vino_drvdata->input_lock); + + return input; +} + +/* execute with input_lock locked */ +static __u32 vino_find_input_index(struct vino_channel_settings *vcs) +{ + __u32 index = 0; + // FIXME: detect when no inputs available + + if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) { + switch (vcs->input) { + case VINO_INPUT_COMPOSITE: + index = 0; + break; + case VINO_INPUT_SVIDEO: + index = 1; + break; + case VINO_INPUT_D1: + index = 2; + break; + } + } else if (vino_drvdata->decoder.driver) { + switch (vcs->input) { + case VINO_INPUT_COMPOSITE: + index = 0; + break; + case VINO_INPUT_SVIDEO: + index = 1; + break; + } + } else if (vino_drvdata->camera.driver) { + switch (vcs->input) { + case VINO_INPUT_D1: + index = 0; + break; + } + } + + return index; +} + +/* V4L2 ioctls */ + +static void vino_v4l2_querycap(struct v4l2_capability *cap) +{ + memset(cap, 0, sizeof(struct v4l2_capability)); + + strcpy(cap->driver, vino_driver_name); + strcpy(cap->card, vino_driver_description); + strcpy(cap->bus_info, vino_bus_name); + cap->version = VINO_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING; + // V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE +} + +static int vino_v4l2_enuminput(struct vino_channel_settings *vcs, + struct v4l2_input *i) +{ + __u32 index = i->index; + int input; + dprintk("requested index = %d\n", index); + + input = vino_enum_input(vcs, index); + if (input == VINO_INPUT_NONE) + return -EINVAL; + + memset(i, 0, sizeof(struct v4l2_input)); + + i->index = index; + i->type = V4L2_INPUT_TYPE_CAMERA; + i->std = vino_inputs[input].std; + strcpy(i->name, vino_inputs[input].name); + + if ((input == VINO_INPUT_COMPOSITE) + || (input == VINO_INPUT_SVIDEO)) { + struct saa7191_status status; + i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status); + i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL; + i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR; + } + + return 0; +} + +static int vino_v4l2_g_input(struct vino_channel_settings *vcs, + struct v4l2_input *i) +{ + __u32 index; + int input; + + spin_lock(&vino_drvdata->input_lock); + input = vcs->input; + index = vino_find_input_index(vcs); + spin_unlock(&vino_drvdata->input_lock); + + dprintk("input = %d\n", input); + + if (input == VINO_INPUT_NONE) { + return -EINVAL; + } + + memset(i, 0, sizeof(struct v4l2_input)); + + i->index = index; + i->type = V4L2_INPUT_TYPE_CAMERA; + i->std = vino_inputs[input].std; + strcpy(i->name, vino_inputs[input].name); + + return 0; +} + +static int vino_v4l2_s_input(struct vino_channel_settings *vcs, + struct v4l2_input *i) +{ + int input; + dprintk("requested input = %d\n", i->index); + + input = vino_enum_input(vcs, i->index); + if (input == VINO_INPUT_NONE) + return -EINVAL; + + return vino_set_input(vcs, input); +} + +static int vino_v4l2_enumstd(struct vino_channel_settings *vcs, + struct v4l2_standard *s) +{ + int index = s->index; + int data_norm = vino_enum_data_norm(vcs, index); + dprintk("standard index = %d\n", index); + + if (data_norm == VINO_DATA_NORM_NONE) + return -EINVAL; + + dprintk("standard name = %s\n", + vino_data_norms[data_norm].description); + + memset(s, 0, sizeof(struct v4l2_standard)); + s->index = index; + + s->id = vino_data_norms[data_norm].std; + s->frameperiod.numerator = 1; + s->frameperiod.denominator = + vino_data_norms[data_norm].fps_max; + s->framelines = + vino_data_norms[data_norm].framelines; + strcpy(s->name, + vino_data_norms[data_norm].description); + + return 0; +} + +static int vino_v4l2_g_std(struct vino_channel_settings *vcs, + v4l2_std_id *std) +{ + spin_lock(&vino_drvdata->input_lock); + dprintk("current standard = %d\n", vcs->data_norm); + *std = vino_data_norms[vcs->data_norm].std; + spin_unlock(&vino_drvdata->input_lock); + + return 0; +} + +static int vino_v4l2_s_std(struct vino_channel_settings *vcs, + v4l2_std_id *std) +{ + int ret = 0; + + spin_lock(&vino_drvdata->input_lock); + + /* check if the standard is valid for the current input */ + if (vino_is_input_owner(vcs) + && (vino_inputs[vcs->input].std & (*std))) { + dprintk("standard accepted\n"); + + /* change the video norm for SAA7191 + * and accept NTSC for D1 (do nothing) */ + + if (vcs->input == VINO_INPUT_D1) + goto out; + + if ((*std) & V4L2_STD_PAL) { + vino_set_data_norm(vcs, VINO_DATA_NORM_PAL); + vcs->data_norm = VINO_DATA_NORM_PAL; + } else if ((*std) & V4L2_STD_NTSC) { + vino_set_data_norm(vcs, VINO_DATA_NORM_NTSC); + vcs->data_norm = VINO_DATA_NORM_NTSC; + } else if ((*std) & V4L2_STD_SECAM) { + vino_set_data_norm(vcs, VINO_DATA_NORM_SECAM); + vcs->data_norm = VINO_DATA_NORM_SECAM; + } else { + ret = -EINVAL; + } + } else { + ret = -EINVAL; + } + +out: + spin_unlock(&vino_drvdata->input_lock); + + return ret; +} + +static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs, + struct v4l2_fmtdesc *fd) +{ + enum v4l2_buf_type type = fd->type; + int index = fd->index; + dprintk("format index = %d\n", index); + + switch (fd->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if ((fd->index < 0) || + (fd->index >= VINO_DATA_FMT_COUNT)) + return -EINVAL; + dprintk("format name = %s\n", + vino_data_formats[index].description); + + memset(fd, 0, sizeof(struct v4l2_fmtdesc)); + fd->index = index; + fd->type = type; + fd->pixelformat = vino_data_formats[index].pixelformat; + strcpy(fd->description, vino_data_formats[index].description); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs, + struct v4l2_format *f) +{ + struct vino_channel_settings tempvcs; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; + + dprintk("requested: w = %d, h = %d\n", + pf->width, pf->height); + + spin_lock(&vino_drvdata->input_lock); + memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings)); + spin_unlock(&vino_drvdata->input_lock); + + tempvcs.data_format = vino_find_data_format(pf->pixelformat); + if (tempvcs.data_format == VINO_DATA_FMT_NONE) { + tempvcs.data_format = VINO_DATA_FMT_RGB32; + pf->pixelformat = + vino_data_formats[tempvcs.data_format]. + pixelformat; + } + + /* data format must be set before clipping/scaling */ + vino_set_scaling(&tempvcs, pf->width, pf->height); + + dprintk("data format = %s\n", + vino_data_formats[tempvcs.data_format].description); + + pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) / + tempvcs.decimation; + pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; + + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = tempvcs.line_size; + pf->sizeimage = tempvcs.line_size * + (tempvcs.clipping.bottom - tempvcs.clipping.top) / + tempvcs.decimation; + pf->colorspace = + vino_data_formats[tempvcs.data_format].colorspace; + + pf->priv = 0; + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs, + struct v4l2_format *f) +{ + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; + spin_lock(&vino_drvdata->input_lock); + + pf->width = (vcs->clipping.right - vcs->clipping.left) / + vcs->decimation; + pf->height = (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->pixelformat = + vino_data_formats[vcs->data_format].pixelformat; + + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; + + pf->priv = 0; + + spin_unlock(&vino_drvdata->input_lock); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs, + struct v4l2_format *f) +{ + int data_format; + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_pix_format *pf = &f->fmt.pix; + spin_lock(&vino_drvdata->input_lock); + + if (!vino_is_input_owner(vcs)) { + spin_unlock(&vino_drvdata->input_lock); + return -EINVAL; + } + + data_format = vino_find_data_format(pf->pixelformat); + if (data_format == VINO_DATA_FMT_NONE) { + vcs->data_format = VINO_DATA_FMT_RGB32; + pf->pixelformat = + vino_data_formats[vcs->data_format]. + pixelformat; + } else { + vcs->data_format = data_format; + } + + /* data format must be set before clipping/scaling */ + vino_set_scaling(vcs, pf->width, pf->height); + + dprintk("data format = %s\n", + vino_data_formats[vcs->data_format].description); + + pf->width = vcs->clipping.right - vcs->clipping.left; + pf->height = vcs->clipping.bottom - vcs->clipping.top; + + pf->field = V4L2_FIELD_INTERLACED; + pf->bytesperline = vcs->line_size; + pf->sizeimage = vcs->line_size * + (vcs->clipping.bottom - vcs->clipping.top) / + vcs->decimation; + pf->colorspace = + vino_data_formats[vcs->data_format].colorspace; + + pf->priv = 0; + + spin_unlock(&vino_drvdata->input_lock); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_cropcap(struct vino_channel_settings *vcs, + struct v4l2_cropcap *ccap) +{ + const struct vino_data_norm *norm; + + switch (ccap->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + spin_lock(&vino_drvdata->input_lock); + norm = &vino_data_norms[vcs->data_norm]; + spin_unlock(&vino_drvdata->input_lock); + + ccap->bounds.left = 0; + ccap->bounds.top = 0; + ccap->bounds.width = norm->width; + ccap->bounds.height = norm->height; + memcpy(&ccap->defrect, &ccap->bounds, + sizeof(struct v4l2_rect)); + + ccap->pixelaspect.numerator = 1; + ccap->pixelaspect.denominator = 1; + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_g_crop(struct vino_channel_settings *vcs, + struct v4l2_crop *c) +{ + switch (c->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + spin_lock(&vino_drvdata->input_lock); + + c->c.left = vcs->clipping.left; + c->c.top = vcs->clipping.top; + c->c.width = vcs->clipping.right - vcs->clipping.left; + c->c.height = vcs->clipping.bottom - vcs->clipping.top; + + spin_unlock(&vino_drvdata->input_lock); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_s_crop(struct vino_channel_settings *vcs, + struct v4l2_crop *c) +{ + switch (c->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + spin_lock(&vino_drvdata->input_lock); + + if (!vino_is_input_owner(vcs)) { + spin_unlock(&vino_drvdata->input_lock); + return -EINVAL; + } + vino_set_clipping(vcs, c->c.left, c->c.top, + c->c.width, c->c.height); + + spin_unlock(&vino_drvdata->input_lock); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_g_parm(struct vino_channel_settings *vcs, + struct v4l2_streamparm *sp) +{ + switch (sp->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_captureparm *cp = &sp->parm.capture; + memset(cp, 0, sizeof(struct v4l2_captureparm)); + + cp->capability = V4L2_CAP_TIMEPERFRAME; + cp->timeperframe.numerator = 1; + + spin_lock(&vino_drvdata->input_lock); + cp->timeperframe.denominator = vcs->fps; + spin_unlock(&vino_drvdata->input_lock); + + // TODO: cp->readbuffers = xxx; + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_s_parm(struct vino_channel_settings *vcs, + struct v4l2_streamparm *sp) +{ + switch (sp->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct v4l2_captureparm *cp = &sp->parm.capture; + + spin_lock(&vino_drvdata->input_lock); + if (!vino_is_input_owner(vcs)) { + spin_unlock(&vino_drvdata->input_lock); + return -EINVAL; + } + + if ((cp->timeperframe.numerator == 0) || + (cp->timeperframe.denominator == 0)) { + /* reset framerate */ + vino_set_default_framerate(vcs); + } else { + vino_set_framerate(vcs, cp->timeperframe.denominator / + cp->timeperframe.numerator); + } + spin_unlock(&vino_drvdata->input_lock); + + // TODO: set buffers according to cp->readbuffers + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs, + struct v4l2_requestbuffers *rb) +{ + if (vcs->reading) + return -EBUSY; + + switch (rb->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + // TODO: check queue type + if (rb->memory != V4L2_MEMORY_MMAP) { + dprintk("type not mmap\n"); + return -EINVAL; + } + + if (vino_is_capturing(vcs)) { + dprintk("busy, capturing\n"); + return -EBUSY; + } + + dprintk("count = %d\n", rb->count); + if (rb->count > 0) { + if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) { + dprintk("busy, buffers still mapped\n"); + return -EBUSY; + } else { + vino_queue_free(&vcs->fb_queue); + vino_queue_init(&vcs->fb_queue, &rb->count); + } + } else { + vino_capture_stop(vcs); + vino_queue_free(&vcs->fb_queue); + } + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs, + struct vino_framebuffer *fb, + struct v4l2_buffer *b) +{ + if (vino_queue_outgoing_contains(&vcs->fb_queue, + fb->id)) { + b->flags &= ~V4L2_BUF_FLAG_QUEUED; + b->flags |= V4L2_BUF_FLAG_DONE; + } else if (vino_queue_incoming_contains(&vcs->fb_queue, + fb->id)) { + b->flags &= ~V4L2_BUF_FLAG_DONE; + b->flags |= V4L2_BUF_FLAG_QUEUED; + } else { + b->flags &= ~(V4L2_BUF_FLAG_DONE | + V4L2_BUF_FLAG_QUEUED); + } + + b->flags &= ~(V4L2_BUF_FLAG_TIMECODE); + + if (fb->map_count > 0) + b->flags |= V4L2_BUF_FLAG_MAPPED; + + b->index = fb->id; + b->memory = (vcs->fb_queue.type == VINO_MEMORY_MMAP) ? + V4L2_MEMORY_MMAP : V4L2_MEMORY_USERPTR; + b->m.offset = fb->offset; + b->bytesused = fb->data_size; + b->length = fb->size; + b->field = V4L2_FIELD_INTERLACED; + b->sequence = fb->frame_counter; + memcpy(&b->timestamp, &fb->timestamp, + sizeof(struct timeval)); + // b->input ? + + dprintk("buffer %d: length = %d, bytesused = %d, offset = %d\n", + fb->id, fb->size, fb->data_size, fb->offset); +} + +static int vino_v4l2_querybuf(struct vino_channel_settings *vcs, + struct v4l2_buffer *b) +{ + if (vcs->reading) + return -EBUSY; + + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; + + // TODO: check queue type + if (b->index >= vino_queue_get_length(&vcs->fb_queue)) { + dprintk("invalid index = %d\n", + b->index); + return -EINVAL; + } + + fb = vino_queue_get_buffer(&vcs->fb_queue, + b->index); + if (fb == NULL) { + dprintk("vino_queue_get_buffer() failed"); + return -EINVAL; + } + + vino_v4l2_get_buffer_status(vcs, fb, b); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_qbuf(struct vino_channel_settings *vcs, + struct v4l2_buffer *b) +{ + if (vcs->reading) + return -EBUSY; + + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; + int ret; + + // TODO: check queue type + if (b->memory != V4L2_MEMORY_MMAP) { + dprintk("type not mmap\n"); + return -EINVAL; + } + + fb = vino_capture_enqueue(vcs, b->index); + if (fb == NULL) + return -EINVAL; + + vino_v4l2_get_buffer_status(vcs, fb, b); + + if (vcs->streaming) { + ret = vino_capture_next(vcs, 1); + if (ret) + return ret; + } + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs, + struct v4l2_buffer *b, + unsigned int nonblocking) +{ + if (vcs->reading) + return -EBUSY; + + switch (b->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: { + struct vino_framebuffer *fb; + unsigned int incoming, outgoing; + int err; + + // TODO: check queue type + + err = vino_queue_get_incoming(&vcs->fb_queue, &incoming); + if (err) { + dprintk("vino_queue_get_incoming() failed\n"); + return -EIO; + } + err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing); + if (err) { + dprintk("vino_queue_get_outgoing() failed\n"); + return -EIO; + } + + dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing); + + if (outgoing == 0) { + if (incoming == 0) { + dprintk("no incoming or outgoing buffers\n"); + return -EINVAL; + } + if (nonblocking) { + dprintk("non-blocking I/O was selected and " + "there are no buffers to dequeue\n"); + return -EAGAIN; + } + + err = vino_wait_for_frame(vcs); + if (err) { + err = vino_wait_for_frame(vcs); + if (err) { + /* interrupted */ + vino_capture_failed(vcs); + return -EIO; + } + } + } + + fb = vino_queue_remove(&vcs->fb_queue, &b->index); + if (fb == NULL) { + dprintk("vino_queue_remove() failed\n"); + return -EINVAL; + } + + err = vino_check_buffer(vcs, fb); + if (err) + return -EIO; + + vino_v4l2_get_buffer_status(vcs, fb, b); + break; + } + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + default: + return -EINVAL; + } + + return 0; +} + +static int vino_v4l2_streamon(struct vino_channel_settings *vcs) +{ + unsigned int incoming; + int ret; + if (vcs->reading) + return -EBUSY; + + if (vcs->streaming) + return 0; + + // TODO: check queue type + + if (vino_queue_get_length(&vcs->fb_queue) < 1) { + dprintk("no buffers allocated\n"); + return -EINVAL; + } + + ret = vino_queue_get_incoming(&vcs->fb_queue, &incoming); + if (ret) { + dprintk("vino_queue_get_incoming() failed\n"); + return -EINVAL; + } + + vcs->streaming = 1; + + if (incoming > 0) { + ret = vino_capture_next(vcs, 1); + if (ret) { + vcs->streaming = 0; + + dprintk("couldn't start capture\n"); + return -EINVAL; + } + } + + return 0; +} + +static int vino_v4l2_streamoff(struct vino_channel_settings *vcs) +{ + if (vcs->reading) + return -EBUSY; + + if (!vcs->streaming) + return 0; + + vino_capture_stop(vcs); + vcs->streaming = 0; + + return 0; +} + +static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs, + struct v4l2_queryctrl *queryctrl) +{ + int i; + int err = 0; + + spin_lock(&vino_drvdata->input_lock); + + switch (vcs->input) { + case VINO_INPUT_D1: + for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { + if (vino_indycam_v4l2_controls[i].id == + queryctrl->id) { + memcpy(queryctrl, + &vino_indycam_v4l2_controls[i], + sizeof(struct v4l2_queryctrl)); + goto found; + } + } + + err = -EINVAL; + break; + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { + if (vino_saa7191_v4l2_controls[i].id == + queryctrl->id) { + memcpy(queryctrl, + &vino_saa7191_v4l2_controls[i], + sizeof(struct v4l2_queryctrl)); + goto found; + } + } + + err = -EINVAL; + break; + default: + err = -EINVAL; + } + + found: + spin_unlock(&vino_drvdata->input_lock); + + return err; +} + +static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs, + struct v4l2_control *control) +{ + struct indycam_control indycam_ctrl; + struct saa7191_control saa7191_ctrl; + int err = 0; + + spin_lock(&vino_drvdata->input_lock); + + switch (vcs->input) { + case VINO_INPUT_D1: + i2c_camera_command(DECODER_INDYCAM_GET_CONTROLS, + &indycam_ctrl); + + switch(control->id) { + case V4L2_CID_AUTOGAIN: + control->value = indycam_ctrl.agc; + break; + case V4L2_CID_AUTO_WHITE_BALANCE: + control->value = indycam_ctrl.awb; + break; + case V4L2_CID_GAIN: + control->value = indycam_ctrl.gain; + break; + case V4L2_CID_PRIVATE_BASE: + control->value = indycam_ctrl.red_saturation; + break; + case V4L2_CID_PRIVATE_BASE + 1: + control->value = indycam_ctrl.blue_saturation; + break; + case V4L2_CID_RED_BALANCE: + control->value = indycam_ctrl.red_balance; + break; + case V4L2_CID_BLUE_BALANCE: + control->value = indycam_ctrl.blue_balance; + break; + case V4L2_CID_EXPOSURE: + control->value = indycam_ctrl.shutter; + break; + case V4L2_CID_GAMMA: + control->value = indycam_ctrl.gamma; + break; + default: + err = -EINVAL; + } + break; + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + i2c_decoder_command(DECODER_SAA7191_GET_CONTROLS, + &saa7191_ctrl); + + switch(control->id) { + case V4L2_CID_HUE: + control->value = saa7191_ctrl.hue; + break; + case V4L2_CID_PRIVATE_BASE: + control->value = saa7191_ctrl.vtrc; + break; + default: + err = -EINVAL; + } + break; + default: + err = -EINVAL; + } + + spin_unlock(&vino_drvdata->input_lock); + + return err; +} + +static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs, + struct v4l2_control *control) +{ + struct indycam_control indycam_ctrl; + struct saa7191_control saa7191_ctrl; + int i; + int err = 0; + + spin_lock(&vino_drvdata->input_lock); + + switch (vcs->input) { + case VINO_INPUT_D1: + for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) { + if (vino_indycam_v4l2_controls[i].id == + control->id) { + if ((control->value >= + vino_indycam_v4l2_controls[i].minimum) + && (control->value <= + vino_indycam_v4l2_controls[i]. + maximum)) { + goto ok1; + } else { + err = -ERANGE; + goto error; + } + } + } + err = -EINVAL; + goto error; + +ok1: + indycam_ctrl.agc = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.awb = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.shutter = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.gain = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.red_balance = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.blue_balance = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.red_saturation = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.blue_saturation = INDYCAM_VALUE_UNCHANGED; + indycam_ctrl.gamma = INDYCAM_VALUE_UNCHANGED; + + switch(control->id) { + case V4L2_CID_AUTOGAIN: + indycam_ctrl.agc = control->value; + break; + case V4L2_CID_AUTO_WHITE_BALANCE: + indycam_ctrl.awb = control->value; + break; + case V4L2_CID_GAIN: + indycam_ctrl.gain = control->value; + break; + case V4L2_CID_PRIVATE_BASE: + indycam_ctrl.red_saturation = control->value; + break; + case V4L2_CID_PRIVATE_BASE + 1: + indycam_ctrl.blue_saturation = control->value; + break; + case V4L2_CID_RED_BALANCE: + indycam_ctrl.red_balance = control->value; + break; + case V4L2_CID_BLUE_BALANCE: + indycam_ctrl.blue_balance = control->value; + break; + case V4L2_CID_EXPOSURE: + indycam_ctrl.shutter = control->value; + break; + case V4L2_CID_GAMMA: + indycam_ctrl.gamma = control->value; + break; + default: + err = -EINVAL; + } + + if (!err) + i2c_camera_command(DECODER_INDYCAM_SET_CONTROLS, + &indycam_ctrl); + break; + case VINO_INPUT_COMPOSITE: + case VINO_INPUT_SVIDEO: + for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) { + if (vino_saa7191_v4l2_controls[i].id == + control->id) { + if ((control->value >= + vino_saa7191_v4l2_controls[i].minimum) + && (control->value <= + vino_saa7191_v4l2_controls[i]. + maximum)) { + goto ok2; + } else { + err = -ERANGE; + goto error; + } + } + } + err = -EINVAL; + goto error; + +ok2: + saa7191_ctrl.hue = SAA7191_VALUE_UNCHANGED; + saa7191_ctrl.vtrc = SAA7191_VALUE_UNCHANGED; + + switch(control->id) { + case V4L2_CID_HUE: + saa7191_ctrl.hue = control->value; + break; + case V4L2_CID_PRIVATE_BASE: + saa7191_ctrl.vtrc = control->value; + break; + default: + err = -EINVAL; + } + + if (!err) + i2c_decoder_command(DECODER_SAA7191_SET_CONTROLS, + &saa7191_ctrl); + break; + default: + err = -EINVAL; + } + +error: + spin_unlock(&vino_drvdata->input_lock); + + return err; +} + +/* File operations */ + +static int vino_open(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + int ret = 0; + dprintk("open(): channel = %c\n", + (vcs->channel == VINO_CHANNEL_A) ? 'A' : 'B'); + + down(&vcs->sem); + + if (vcs->users) { + dprintk("open(): driver busy\n"); + ret = -EBUSY; + goto out; + } + + ret = vino_acquire_input(vcs); + if (ret) { + dprintk("open(): vino_acquire_input() failed\n"); + goto out; + } + + vcs->users++; + + out: + up(&vcs->sem); + + dprintk("open(): %s!\n", ret ? "failed" : "complete"); + + return ret; +} + +static int vino_close(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + dprintk("close():\n"); + + down(&vcs->sem); + + vcs->users--; + + if (!vcs->users) { + vino_release_input(vcs); + + /* stop DMA and free buffers */ + vino_capture_stop(vcs); + vino_queue_free(&vcs->fb_queue); + } + + up(&vcs->sem); + + return 0; +} + +static void vino_vm_open(struct vm_area_struct *vma) +{ + struct vino_framebuffer *fb = vma->vm_private_data; + + fb->map_count++; + dprintk("vino_vm_open(): count = %d\n", fb->map_count); +} + +static void vino_vm_close(struct vm_area_struct *vma) +{ + struct vino_framebuffer *fb = vma->vm_private_data; + + fb->map_count--; + dprintk("vino_vm_close(): count = %d\n", fb->map_count); +} + +static struct vm_operations_struct vino_vm_ops = { + .open = vino_vm_open, + .close = vino_vm_close, +}; + +static int vino_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + + struct vino_framebuffer *fb = NULL; + unsigned int i, length; + int ret = 0; + + dprintk("mmap():\n"); + + // TODO: reject mmap if already mapped + + if (down_interruptible(&vcs->sem)) + return -EINTR; + + if (vcs->reading) { + ret = -EBUSY; + goto out; + } + + // TODO: check queue type + + if (!(vma->vm_flags & VM_WRITE)) { + dprintk("mmap(): app bug: PROT_WRITE please\n"); + ret = -EINVAL; + goto out; + } + if (!(vma->vm_flags & VM_SHARED)) { + dprintk("mmap(): app bug: MAP_SHARED please\n"); + ret = -EINVAL; + goto out; + } + + /* find the correct buffer using offset */ + length = vino_queue_get_length(&vcs->fb_queue); + if (length == 0) { + dprintk("mmap(): queue not initialized\n"); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < length; i++) { + fb = vino_queue_get_buffer(&vcs->fb_queue, i); + if (fb == NULL) { + dprintk("mmap(): vino_queue_get_buffer() failed\n"); + ret = -EINVAL; + goto out; + } + + if (fb->offset == offset) + goto found; + } + + dprintk("mmap(): invalid offset = %lu\n", offset); + ret = -EINVAL; + goto out; + +found: + dprintk("mmap(): buffer = %d\n", i); + + if (size > (fb->desc_table.page_count * PAGE_SIZE)) { + dprintk("mmap(): failed: size = %lu > %lu\n", + size, fb->desc_table.page_count * PAGE_SIZE); + ret = -EINVAL; + goto out; + } + + for (i = 0; i < fb->desc_table.page_count; i++) { + unsigned long pfn = + virt_to_phys((void *)fb->desc_table.virtual[i]) >> + PAGE_SHIFT; + + if (size < PAGE_SIZE) + break; + + // protection was: PAGE_READONLY + if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, + vma->vm_page_prot)) { + dprintk("mmap(): remap_pfn_range() failed\n"); + ret = -EAGAIN; + goto out; + } + + start += PAGE_SIZE; + size -= PAGE_SIZE; + } + + fb->map_count = 1; + + vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED; + vma->vm_flags &= ~VM_IO; + vma->vm_private_data = fb; + vma->vm_file = file; + vma->vm_ops = &vino_vm_ops; + +out: + up(&vcs->sem); + + return ret; +} + +static unsigned int vino_poll(struct file *file, poll_table *pt) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + unsigned int outgoing; + unsigned int ret = 0; + + // lock mutex (?) + // TODO: this has to be corrected for different read modes + + dprintk("poll():\n"); + + if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { + dprintk("poll(): vino_queue_get_outgoing() failed\n"); + ret = POLLERR; + goto error; + } + if (outgoing > 0) + goto over; + + poll_wait(file, &vcs->fb_queue.frame_wait_queue, pt); + + if (vino_queue_get_outgoing(&vcs->fb_queue, &outgoing)) { + dprintk("poll(): vino_queue_get_outgoing() failed\n"); + ret = POLLERR; + goto error; + } + +over: + dprintk("poll(): data %savailable\n", + (outgoing > 0) ? "" : "not "); + if (outgoing > 0) { + ret = POLLIN | POLLRDNORM; + } + +error: + + return ret; +} + +static int vino_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + + switch (_IOC_TYPE(cmd)) { + case 'v': + dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd); + break; + case 'V': + dprintk("ioctl(): V4L2 %s (0x%08x)\n", + v4l2_ioctl_names[_IOC_NR(cmd)], cmd); + break; + default: + dprintk("ioctl(): unsupported command 0x%08x\n", cmd); + } + + switch (cmd) { + /* TODO: V4L1 interface (use compatibility layer?) */ + /* V4L2 interface */ + case VIDIOC_QUERYCAP: { + vino_v4l2_querycap(arg); + break; + } + case VIDIOC_ENUMINPUT: { + return vino_v4l2_enuminput(vcs, arg); + } + case VIDIOC_G_INPUT: { + return vino_v4l2_g_input(vcs, arg); + } + case VIDIOC_S_INPUT: { + return vino_v4l2_s_input(vcs, arg); + } + case VIDIOC_ENUMSTD: { + return vino_v4l2_enumstd(vcs, arg); + } + case VIDIOC_G_STD: { + return vino_v4l2_g_std(vcs, arg); + } + case VIDIOC_S_STD: { + return vino_v4l2_s_std(vcs, arg); + } + case VIDIOC_ENUM_FMT: { + return vino_v4l2_enum_fmt(vcs, arg); + } + case VIDIOC_TRY_FMT: { + return vino_v4l2_try_fmt(vcs, arg); + } + case VIDIOC_G_FMT: { + return vino_v4l2_g_fmt(vcs, arg); + } + case VIDIOC_S_FMT: { + return vino_v4l2_s_fmt(vcs, arg); + } + case VIDIOC_CROPCAP: { + return vino_v4l2_cropcap(vcs, arg); + } + case VIDIOC_G_CROP: { + return vino_v4l2_g_crop(vcs, arg); + } + case VIDIOC_S_CROP: { + return vino_v4l2_s_crop(vcs, arg); + } + case VIDIOC_G_PARM: { + return vino_v4l2_g_parm(vcs, arg); + } + case VIDIOC_S_PARM: { + return vino_v4l2_s_parm(vcs, arg); + } + case VIDIOC_REQBUFS: { + return vino_v4l2_reqbufs(vcs, arg); + } + case VIDIOC_QUERYBUF: { + return vino_v4l2_querybuf(vcs, arg); + } + case VIDIOC_QBUF: { + return vino_v4l2_qbuf(vcs, arg); + } + case VIDIOC_DQBUF: { + return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK); + } + case VIDIOC_STREAMON: { + return vino_v4l2_streamon(vcs); + } + case VIDIOC_STREAMOFF: { + return vino_v4l2_streamoff(vcs); + } + case VIDIOC_QUERYCTRL: { + return vino_v4l2_queryctrl(vcs, arg); + } + case VIDIOC_G_CTRL: { + return vino_v4l2_g_ctrl(vcs, arg); + } + case VIDIOC_S_CTRL: { + return vino_v4l2_s_ctrl(vcs, arg); + } + default: + return -ENOIOCTLCMD; + } + + return 0; +} + +static int vino_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct video_device *dev = video_devdata(file); + struct vino_channel_settings *vcs = video_get_drvdata(dev); + int ret; + + if (down_interruptible(&vcs->sem)) + return -EINTR; + + ret = video_usercopy(inode, file, cmd, arg, vino_do_ioctl); + + up(&vcs->sem); + + return ret; +} + +/* Initialization and cleanup */ + +// __initdata +static int vino_init_stage = 0; + +static struct file_operations vino_fops = { + .owner = THIS_MODULE, + .open = vino_open, + .release = vino_close, + .ioctl = vino_ioctl, + .mmap = vino_mmap, + .poll = vino_poll, + .llseek = no_llseek, +}; + +static struct video_device v4l_device_template = { + .name = "NOT SET", + //.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE | + // VID_TYPE_CLIPPING | VID_TYPE_SCALES, VID_TYPE_OVERLAY + .hardware = VID_HARDWARE_VINO, + .fops = &vino_fops, + .minor = -1, +}; + +static void vino_module_cleanup(int stage) +{ + switch(stage) { + case 10: + video_unregister_device(vino_drvdata->b.v4l_device); + vino_drvdata->b.v4l_device = NULL; + case 9: + video_unregister_device(vino_drvdata->a.v4l_device); + vino_drvdata->a.v4l_device = NULL; + case 8: + vino_i2c_del_bus(); + case 7: + free_irq(SGI_VINO_IRQ, NULL); + case 6: + if (vino_drvdata->b.v4l_device) { + video_device_release(vino_drvdata->b.v4l_device); + vino_drvdata->b.v4l_device = NULL; + } + case 5: + if (vino_drvdata->a.v4l_device) { + video_device_release(vino_drvdata->a.v4l_device); + vino_drvdata->a.v4l_device = NULL; + } + case 4: + /* all entries in dma_cpu dummy table have the same address */ + dma_unmap_single(NULL, + vino_drvdata->dummy_desc_table.dma_cpu[0], + PAGE_SIZE, DMA_FROM_DEVICE); + dma_free_coherent(NULL, VINO_DUMMY_DESC_COUNT + * sizeof(dma_addr_t), + (void *)vino_drvdata-> + dummy_desc_table.dma_cpu, + vino_drvdata->dummy_desc_table.dma); + case 3: + free_page(vino_drvdata->dummy_page); + case 2: + kfree(vino_drvdata); + case 1: + iounmap(vino); + case 0: + break; + default: + dprintk("vino_module_cleanup(): invalid cleanup stage = %d\n", + stage); + } +} + +static int vino_probe(void) +{ + unsigned long rev_id; + + if (ip22_is_fullhouse()) { + printk(KERN_ERR "VINO doesn't exist in IP22 Fullhouse\n"); + return -ENODEV; + } + + if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) { + printk(KERN_ERR "VINO is not found (EISA BUS not present)\n"); + return -ENODEV; + } + + vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino)); + if (!vino) { + printk(KERN_ERR "VINO: ioremap() failed\n"); + return -EIO; + } + vino_init_stage++; + + if (get_dbe(rev_id, &(vino->rev_id))) { + printk(KERN_ERR "Failed to read VINO revision register\n"); + vino_module_cleanup(vino_init_stage); + return -ENODEV; + } + + if (VINO_ID_VALUE(rev_id) != VINO_CHIP_ID) { + printk(KERN_ERR "Unknown VINO chip ID (Rev/ID: 0x%02lx)\n", + rev_id); + vino_module_cleanup(vino_init_stage); + return -ENODEV; + } + + printk(KERN_INFO "VINO with chip ID %ld, revision %ld found\n", + VINO_ID_VALUE(rev_id), VINO_REV_NUM(rev_id)); + + return 0; +} + +static int vino_init(void) +{ + dma_addr_t dma_dummy_address; + int i; + + vino_drvdata = (struct vino_settings *) + kmalloc(sizeof(struct vino_settings), GFP_KERNEL); + if (!vino_drvdata) { + vino_module_cleanup(vino_init_stage); + return -ENOMEM; + } + memset(vino_drvdata, 0, sizeof(struct vino_settings)); + vino_init_stage++; + + /* create a dummy dma descriptor */ + vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!vino_drvdata->dummy_page) { + vino_module_cleanup(vino_init_stage); + return -ENOMEM; + } + vino_init_stage++; + + // TODO: use page_count in dummy_desc_table + + vino_drvdata->dummy_desc_table.dma_cpu = + dma_alloc_coherent(NULL, + VINO_DUMMY_DESC_COUNT * sizeof(dma_addr_t), + &vino_drvdata->dummy_desc_table.dma, + GFP_KERNEL | GFP_DMA); + if (!vino_drvdata->dummy_desc_table.dma_cpu) { + vino_module_cleanup(vino_init_stage); + return -ENOMEM; + } + vino_init_stage++; + + dma_dummy_address = dma_map_single(NULL, + (void *)vino_drvdata->dummy_page, + PAGE_SIZE, DMA_FROM_DEVICE); + for (i = 0; i < VINO_DUMMY_DESC_COUNT; i++) { + vino_drvdata->dummy_desc_table.dma_cpu[i] = dma_dummy_address; + } + + /* initialize VINO */ + + vino->control = 0; + vino->a.next_4_desc = vino_drvdata->dummy_desc_table.dma; + vino->b.next_4_desc = vino_drvdata->dummy_desc_table.dma; + udelay(VINO_DESC_FETCH_DELAY); + + vino->intr_status = 0; + + vino->a.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT; + vino->b.fifo_thres = VINO_FIFO_THRESHOLD_DEFAULT; + + return 0; +} + +static int vino_init_channel_settings(struct vino_channel_settings *vcs, + unsigned int channel, const char *name) +{ + vcs->channel = channel; + vcs->input = VINO_INPUT_NONE; + vcs->alpha = 0; + vcs->users = 0; + vcs->data_format = VINO_DATA_FMT_GREY; + vcs->data_norm = VINO_DATA_NORM_NTSC; + vcs->decimation = 1; + vino_set_default_clipping(vcs); + vino_set_default_framerate(vcs); + + vcs->capturing = 0; + + init_MUTEX(&vcs->sem); + spin_lock_init(&vcs->capture_lock); + + init_MUTEX(&vcs->fb_queue.queue_sem); + spin_lock_init(&vcs->fb_queue.queue_lock); + init_waitqueue_head(&vcs->fb_queue.frame_wait_queue); + + vcs->v4l_device = video_device_alloc(); + if (!vcs->v4l_device) { + vino_module_cleanup(vino_init_stage); + return -ENOMEM; + } + vino_init_stage++; + + memcpy(vcs->v4l_device, &v4l_device_template, + sizeof(struct video_device)); + strcpy(vcs->v4l_device->name, name); + vcs->v4l_device->release = video_device_release; + + video_set_drvdata(vcs->v4l_device, vcs); + + return 0; +} + +static int __init vino_module_init(void) +{ + int ret; + + printk(KERN_INFO "SGI VINO driver version %s\n", + VINO_MODULE_VERSION); + + ret = vino_probe(); + if (ret) + return ret; + + ret = vino_init(); + if (ret) + return ret; + + /* initialize data structures */ + + spin_lock_init(&vino_drvdata->vino_lock); + spin_lock_init(&vino_drvdata->input_lock); + + ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A, + vino_v4l_device_name_a); + if (ret) + return ret; + + ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B, + vino_v4l_device_name_b); + if (ret) + return ret; + + /* initialize hardware and register V4L devices */ + + ret = request_irq(SGI_VINO_IRQ, vino_interrupt, 0, + vino_driver_description, NULL); + if (ret) { + printk(KERN_ERR "VINO: requesting IRQ %02d failed\n", + SGI_VINO_IRQ); + vino_module_cleanup(vino_init_stage); + return -EAGAIN; + } + vino_init_stage++; + + ret = vino_i2c_add_bus(); + if (ret) { + printk(KERN_ERR "VINO I2C bus registration failed\n"); + vino_module_cleanup(vino_init_stage); + return ret; + } + vino_init_stage++; + + ret = video_register_device(vino_drvdata->a.v4l_device, + VFL_TYPE_GRABBER, -1); + if (ret < 0) { + printk(KERN_ERR "VINO channel A Video4Linux-device " + "registration failed\n"); + vino_module_cleanup(vino_init_stage); + return -EINVAL; + } + vino_init_stage++; + + ret = video_register_device(vino_drvdata->b.v4l_device, + VFL_TYPE_GRABBER, -1); + if (ret < 0) { + printk(KERN_ERR "VINO channel B Video4Linux-device " + "registration failed\n"); + vino_module_cleanup(vino_init_stage); + return -EINVAL; + } + vino_init_stage++; + +#if defined(CONFIG_KMOD) && defined(MODULE) + request_module("saa7191"); + request_module("indycam"); +#endif + + dprintk("init complete!\n"); + + return 0; +} + +static void __exit vino_module_exit(void) +{ + dprintk("exiting, stage = %d ...\n", vino_init_stage); + vino_module_cleanup(vino_init_stage); + dprintk("cleanup complete, exit!\n"); +} + +module_init(vino_module_init); +module_exit(vino_module_exit); diff --git a/drivers/media/video/vino.h b/drivers/media/video/vino.h index d2fce472f35a..de2d615ae7c9 100644 --- a/drivers/media/video/vino.h +++ b/drivers/media/video/vino.h @@ -1,13 +1,19 @@ /* + * Driver for the VINO (Video In No Out) system found in SGI Indys. + * + * This file is subject to the terms and conditions of the GNU General Public + * License version 2 as published by the Free Software Foundation. + * * Copyright (C) 1999 Ulf Karlsson * Copyright (C) 2003 Ladislav Michl */ -#ifndef VINO_H -#define VINO_H +#ifndef _VINO_H_ +#define _VINO_H_ #define VINO_BASE 0x00080000 /* Vino is in the EISA address space, * but it is not an EISA bus card */ +#define VINO_PAGE_SIZE 4096 struct sgi_vino_channel { u32 _pad_alpha; @@ -21,8 +27,9 @@ struct sgi_vino_channel { u32 _pad_clip_end; volatile u32 clip_end; +#define VINO_FRAMERT_FULL 0xfff #define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */ -#define VINO_FRAMERT_RT(x) (((x) & 0x1fff) << 1) /* bits 1:12 */ +#define VINO_FRAMERT_RT(x) (((x) & 0xfff) << 1) /* bits 1:12 */ u32 _pad_frame_rate; volatile u32 frame_rate; @@ -67,18 +74,18 @@ struct sgi_vino { volatile u32 rev_id; #define VINO_CTRL_LITTLE_ENDIAN (1<<0) -#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */ -#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */ -#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */ -#define VINO_CTRL_A_INT (VINO_CTRL_A_FIELD_TRANS_INT | \ - VINO_CTRL_A_FIFO_OF_INT | \ - VINO_CTRL_A_END_DESC_TBL_INT) -#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */ -#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */ -#define VINO_CTRL_B_END_DESC_TBL_INT (1<<6) /* End of desc table int */ -#define VINO_CTRL_B_INT (VINO_CTRL_B_FIELD_TRANS_INT | \ - VINO_CTRL_B_FIFO_OF_INT | \ - VINO_CTRL_B_END_DESC_TBL_INT) +#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */ +#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */ +#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */ +#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \ + VINO_CTRL_A_FIFO_INT | \ + VINO_CTRL_A_EOD_INT) +#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */ +#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */ +#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */ +#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \ + VINO_CTRL_B_FIFO_INT | \ + VINO_CTRL_B_EOD_INT) #define VINO_CTRL_A_DMA_ENBL (1<<7) #define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8) #define VINO_CTRL_A_SYNC_ENBL (1<<9) @@ -104,18 +111,18 @@ struct sgi_vino { u32 _pad_control; volatile u32 control; -#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */ -#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */ -#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */ -#define VINO_INTSTAT_A (VINO_INTSTAT_A_FIELD_TRANS | \ - VINO_INTSTAT_A_FIFO_OF | \ - VINO_INTSTAT_A_END_DESC_TBL) -#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */ -#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */ -#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */ -#define VINO_INTSTAT_B (VINO_INTSTAT_B_FIELD_TRANS | \ - VINO_INTSTAT_B_FIFO_OF | \ - VINO_INTSTAT_B_END_DESC_TBL) +#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */ +#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */ +#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */ +#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \ + VINO_INTSTAT_A_FIFO | \ + VINO_INTSTAT_A_EOD) +#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */ +#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */ +#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */ +#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \ + VINO_INTSTAT_B_FIFO | \ + VINO_INTSTAT_B_EOD) u32 _pad_intr_status; volatile u32 intr_status; -- cgit v1.2.3-55-g7522