From e308a5d806c852f56590ffdd3834d0df0cbed8d7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Jul 2008 00:13:44 -0700 Subject: netdev: Add netdev->addr_list_lock protection. Add netif_addr_{lock,unlock}{,_bh}() helpers. Use them to protect operations that operate on or read the network device unicast and multicast address lists. Also use them in cases where the code simply wants to block calls into the driver's ->set_rx_mode() and ->set_multicast_list() methods. Signed-off-by: David S. Miller --- drivers/media/dvb/dvb-core/dvb_net.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index c2334aef4143..809d18c663bc 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1134,6 +1134,7 @@ static void wq_set_multicast_list (struct work_struct *work) dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; netif_tx_lock_bh(dev); + netif_addr_lock(dev); if (dev->flags & IFF_PROMISC) { dprintk("%s: promiscuous mode\n", dev->name); @@ -1158,6 +1159,7 @@ static void wq_set_multicast_list (struct work_struct *work) } } + netif_addr_unlock(dev); netif_tx_unlock_bh(dev); dvb_net_feed_start(dev); } -- cgit v1.2.3 From b9e40857682ecfc5bcd0356a23ff409883ffb982 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 15 Jul 2008 00:15:08 -0700 Subject: netdev: Do not use TX lock to protect address lists. Now that we have a specific lock to protect the network device unicast and multicast lists, remove extraneous grabs of the TX lock in cases where the code only needs address list protection. Signed-off-by: David S. Miller --- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 2 -- drivers/media/dvb/dvb-core/dvb_net.c | 6 ++-- drivers/net/bonding/bond_main.c | 24 ++++++---------- drivers/net/sfc/efx.c | 6 ++-- drivers/net/wireless/libertas/main.c | 6 ++-- net/core/dev.c | 38 ++++++++------------------ net/core/dev_mcast.c | 32 +++++++--------------- net/mac80211/main.c | 12 +++----- net/mac80211/mlme.c | 6 ++-- 9 files changed, 42 insertions(+), 90 deletions(-) (limited to 'drivers/media') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 261ab7150431..cd2fb955040f 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -774,7 +774,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) ipoib_mcast_stop_thread(dev, 0); local_irq_save(flags); - netif_tx_lock(dev); netif_addr_lock(dev); spin_lock(&priv->lock); @@ -853,7 +852,6 @@ void ipoib_mcast_restart_task(struct work_struct *work) spin_unlock(&priv->lock); netif_addr_unlock(dev); - netif_tx_unlock(dev); local_irq_restore(flags); /* We have to cancel outside of the spinlock */ diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 809d18c663bc..c2c033722a93 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1133,8 +1133,7 @@ static void wq_set_multicast_list (struct work_struct *work) dvb_net_feed_stop(dev); priv->rx_mode = RX_MODE_UNI; - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); if (dev->flags & IFF_PROMISC) { dprintk("%s: promiscuous mode\n", dev->name); @@ -1159,8 +1158,7 @@ static void wq_set_multicast_list (struct work_struct *work) } } - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); dvb_net_feed_start(dev); } diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ea71abd6f728..fd87dbe7999a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1567,14 +1567,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) goto err_close; } - netif_tx_lock_bh(bond_dev); - netif_addr_lock(bond_dev); + netif_addr_lock_bh(bond_dev); /* upload master's mc_list to new slave */ for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) { dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0); } - netif_addr_unlock(bond_dev); - netif_tx_unlock_bh(bond_dev); + netif_addr_unlock_bh(bond_dev); } if (bond->params.mode == BOND_MODE_8023AD) { @@ -1938,11 +1936,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } /* flush master's mc_list from slave */ - netif_tx_lock_bh(bond_dev); - netif_addr_lock(bond_dev); + netif_addr_lock_bh(bond_dev); bond_mc_list_flush(bond_dev, slave_dev); - netif_addr_unlock(bond_dev); - netif_tx_unlock_bh(bond_dev); + netif_addr_unlock_bh(bond_dev); } netdev_set_master(slave_dev, NULL); @@ -2063,11 +2059,9 @@ static int bond_release_all(struct net_device *bond_dev) } /* flush master's mc_list from slave */ - netif_tx_lock_bh(bond_dev); - netif_addr_lock(bond_dev); + netif_addr_lock_bh(bond_dev); bond_mc_list_flush(bond_dev, slave_dev); - netif_addr_unlock(bond_dev); - netif_tx_unlock_bh(bond_dev); + netif_addr_unlock_bh(bond_dev); } netdev_set_master(slave_dev, NULL); @@ -4679,11 +4673,9 @@ static void bond_free_all(void) struct net_device *bond_dev = bond->dev; bond_work_cancel_all(bond); - netif_tx_lock_bh(bond_dev); - netif_addr_lock(bond_dev); + netif_addr_lock_bh(bond_dev); bond_mc_list_destroy(bond); - netif_addr_unlock(bond_dev); - netif_tx_unlock_bh(bond_dev); + netif_addr_unlock_bh(bond_dev); /* Release the bonded slaves */ bond_release_all(bond_dev); bond_destroy(bond); diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index e1257e556e48..7b2015f9e469 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -696,10 +696,8 @@ static void efx_stop_port(struct efx_nic *efx) /* Serialise against efx_set_multicast_list() */ if (efx_dev_registered(efx)) { - netif_tx_lock_bh(efx->net_dev); - netif_addr_lock(efx->net_dev); - netif_addr_unlock(efx->net_dev); - netif_tx_unlock_bh(efx->net_dev); + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); } } diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 42e9b2771eab..14d5d61cec4c 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -593,8 +593,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST)) return nr_addrs; - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { lbs_deb_net("mcast address %s:%s skipped\n", dev->name, @@ -609,8 +608,7 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd, print_mac(mac, mc_list->dmi_addr)); i++; } - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); if (mc_list) return -EOVERFLOW; diff --git a/net/core/dev.c b/net/core/dev.c index ef1502d71f25..9b49f74a9820 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2981,11 +2981,9 @@ void __dev_set_rx_mode(struct net_device *dev) void dev_set_rx_mode(struct net_device *dev) { - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); __dev_set_rx_mode(dev); - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); } int __dev_addr_delete(struct dev_addr_list **list, int *count, @@ -3063,13 +3061,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen) ASSERT_RTNL(); - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); if (!err) __dev_set_rx_mode(dev); - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_delete); @@ -3091,13 +3087,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen) ASSERT_RTNL(); - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); if (!err) __dev_set_rx_mode(dev); - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); return err; } EXPORT_SYMBOL(dev_unicast_add); @@ -3164,14 +3158,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) { int err = 0; - netif_tx_lock_bh(to); - netif_addr_lock(to); + netif_addr_lock_bh(to); err = __dev_addr_sync(&to->uc_list, &to->uc_count, &from->uc_list, &from->uc_count); if (!err) __dev_set_rx_mode(to); - netif_addr_unlock(to); - netif_tx_unlock_bh(to); + netif_addr_unlock_bh(to); return err; } EXPORT_SYMBOL(dev_unicast_sync); @@ -3187,9 +3179,7 @@ EXPORT_SYMBOL(dev_unicast_sync); */ void dev_unicast_unsync(struct net_device *to, struct net_device *from) { - netif_tx_lock_bh(from); - netif_addr_lock(from); - netif_tx_lock_bh(to); + netif_addr_lock_bh(from); netif_addr_lock(to); __dev_addr_unsync(&to->uc_list, &to->uc_count, @@ -3197,9 +3187,7 @@ void dev_unicast_unsync(struct net_device *to, struct net_device *from) __dev_set_rx_mode(to); netif_addr_unlock(to); - netif_tx_unlock_bh(to); - netif_addr_unlock(from); - netif_tx_unlock_bh(from); + netif_addr_unlock_bh(from); } EXPORT_SYMBOL(dev_unicast_unsync); @@ -3219,8 +3207,7 @@ static void __dev_addr_discard(struct dev_addr_list **list) static void dev_addr_discard(struct net_device *dev) { - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); __dev_addr_discard(&dev->uc_list); dev->uc_count = 0; @@ -3228,8 +3215,7 @@ static void dev_addr_discard(struct net_device *dev) __dev_addr_discard(&dev->mc_list); dev->mc_count = 0; - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); } unsigned dev_get_flags(const struct net_device *dev) diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index b6b2a129971a..5402b3b38e0d 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -72,8 +72,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) { int err; - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, addr, alen, glbl); if (!err) { @@ -84,8 +83,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl) __dev_set_rx_mode(dev); } - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); return err; } @@ -97,13 +95,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl) { int err; - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); if (!err) __dev_set_rx_mode(dev); - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); return err; } @@ -123,14 +119,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) { int err = 0; - netif_tx_lock_bh(to); - netif_addr_lock(to); + netif_addr_lock_bh(to); err = __dev_addr_sync(&to->mc_list, &to->mc_count, &from->mc_list, &from->mc_count); if (!err) __dev_set_rx_mode(to); - netif_addr_unlock(to); - netif_tx_unlock_bh(to); + netif_addr_unlock_bh(to); return err; } @@ -149,9 +143,7 @@ EXPORT_SYMBOL(dev_mc_sync); */ void dev_mc_unsync(struct net_device *to, struct net_device *from) { - netif_tx_lock_bh(from); - netif_addr_lock(from); - netif_tx_lock_bh(to); + netif_addr_lock_bh(from); netif_addr_lock(to); __dev_addr_unsync(&to->mc_list, &to->mc_count, @@ -159,9 +151,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) __dev_set_rx_mode(to); netif_addr_unlock(to); - netif_tx_unlock_bh(to); - netif_addr_unlock(from); - netif_tx_unlock_bh(from); + netif_addr_unlock_bh(from); } EXPORT_SYMBOL(dev_mc_unsync); @@ -174,8 +164,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) return 0; - netif_tx_lock_bh(dev); - netif_addr_lock(dev); + netif_addr_lock_bh(dev); for (m = dev->mc_list; m; m = m->next) { int i; @@ -187,8 +176,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v) seq_putc(seq, '\n'); } - netif_addr_unlock(dev); - netif_tx_unlock_bh(dev); + netif_addr_unlock_bh(dev); return 0; } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 095b7d928d64..af0056e7e5b3 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -291,11 +291,9 @@ static int ieee80211_open(struct net_device *dev) if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) local->fif_other_bss++; - netif_tx_lock_bh(local->mdev); - netif_addr_lock(local->mdev); + netif_addr_lock_bh(local->mdev); ieee80211_configure_filter(local); - netif_addr_unlock(local->mdev); - netif_tx_unlock_bh(local->mdev); + netif_addr_unlock_bh(local->mdev); break; case IEEE80211_IF_TYPE_STA: case IEEE80211_IF_TYPE_IBSS: @@ -492,11 +490,9 @@ static int ieee80211_stop(struct net_device *dev) if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) local->fif_other_bss--; - netif_tx_lock_bh(local->mdev); - netif_addr_lock(local->mdev); + netif_addr_lock_bh(local->mdev); ieee80211_configure_filter(local); - netif_addr_unlock(local->mdev); - netif_tx_unlock_bh(local->mdev); + netif_addr_unlock_bh(local->mdev); break; case IEEE80211_IF_TYPE_MESH_POINT: case IEEE80211_IF_TYPE_STA: diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1232ba25e1e9..d7c371e36bf0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -4064,16 +4064,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev, local->scan_band = IEEE80211_BAND_2GHZ; local->scan_dev = dev; - netif_tx_lock_bh(local->mdev); - netif_addr_lock(local->mdev); + netif_addr_lock_bh(local->mdev); local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; local->ops->configure_filter(local_to_hw(local), FIF_BCN_PRBRESP_PROMISC, &local->filter_flags, local->mdev->mc_count, local->mdev->mc_list); - netif_addr_unlock(local->mdev); - netif_tx_unlock_bh(local->mdev); + netif_addr_unlock_bh(local->mdev); /* TODO: start scan as soon as all nullfunc frames are ACKed */ queue_delayed_work(local->hw.workqueue, &local->scan_work, -- cgit v1.2.3 From 5ad6b816e2227a7daf9569f1dbb8d7af90b387b2 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 15 Apr 2008 22:22:11 -0300 Subject: V4L/DVB (7586): radio: use get/put_unaligned_* helpers Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 77354ca6e8e9..5dd33197bbdd 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -521,8 +521,7 @@ static int si470x_get_register(struct si470x_device *radio, int regnr) retval = si470x_get_report(radio, (void *) &buf, sizeof(buf)); if (retval >= 0) - radio->registers[regnr] = be16_to_cpu(get_unaligned( - (unsigned short *) &buf[1])); + radio->registers[regnr] = get_unaligned_be16(&buf[1]); return (retval < 0) ? -EINVAL : 0; } @@ -537,8 +536,7 @@ static int si470x_set_register(struct si470x_device *radio, int regnr) int retval; buf[0] = REGISTER_REPORT(regnr); - put_unaligned(cpu_to_be16(radio->registers[regnr]), - (unsigned short *) &buf[1]); + put_unaligned_be16(radio->registers[regnr], &buf[1]); retval = si470x_set_report(radio, (void *) &buf, sizeof(buf)); @@ -561,9 +559,8 @@ static int si470x_get_all_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++) - radio->registers[regnr] = be16_to_cpu(get_unaligned( - (unsigned short *) - &buf[regnr * RADIO_REGISTER_SIZE + 1])); + radio->registers[regnr] = get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); return (retval < 0) ? -EINVAL : 0; } @@ -594,8 +591,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - be16_to_cpu(get_unaligned((unsigned short *) - &buf[regnr * RADIO_REGISTER_SIZE + 1])); + get_unaligned_be16(&buf[regnr * RADIO_REGISTER_SIZE + 1]); return (retval < 0) ? -EINVAL : 0; } @@ -843,7 +839,7 @@ static void si470x_rds(struct si470x_device *radio) }; /* Fill the V4L2 RDS buffer */ - put_unaligned(cpu_to_le16(rds), (unsigned short *) &tmpbuf); + put_unaligned_le16(rds, &tmpbuf); tmpbuf[2] = blocknum; /* offset name */ tmpbuf[2] |= blocknum << 3; /* received offset */ if (bler > max_rds_errors) -- cgit v1.2.3 From e9b59f6e2f6686016dfea7625e98fbef1e335c61 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 10 May 2008 04:35:24 -0300 Subject: V4L/DVB (7882): pvrusb2: make code static This patch makes the following needlessly global code static: - pvrusb2-devattr.c: struct pvr2_onair_creator_fe_props - pvrusb2-devattr.c: struct pvr2_onair_usb2_fe_props - pvrusb2-devattr.c: struct pvr2_73xxx_dvb_props - pvrusb2-devattr.c: struct pvr2_750xx_dvb_props - pvrusb2-devattr.c: struct pvr2_751xx_dvb_props - pvrusb2-hdw.c:pvr2_led_ctrl_hauppauge() Signed-off-by: Adrian Bunk Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 10 +++++----- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 5bf6d8fda1f9..241c60cf40eb 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -182,7 +182,7 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap) return 0; } -struct pvr2_dvb_props pvr2_onair_creator_fe_props = { +static struct pvr2_dvb_props pvr2_onair_creator_fe_props = { .frontend_attach = pvr2_lgdt3303_attach, .tuner_attach = pvr2_lgh06xf_attach, }; @@ -242,7 +242,7 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap) return 0; } -struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { +static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = { .frontend_attach = pvr2_lgdt3302_attach, .tuner_attach = pvr2_fcv1236d_attach, }; @@ -315,7 +315,7 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) return 0; } -struct pvr2_dvb_props pvr2_73xxx_dvb_props = { +static struct pvr2_dvb_props pvr2_73xxx_dvb_props = { .frontend_attach = pvr2_tda10048_attach, .tuner_attach = pvr2_73xxx_tda18271_8295_attach, }; @@ -418,12 +418,12 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap) return 0; } -struct pvr2_dvb_props pvr2_750xx_dvb_props = { +static struct pvr2_dvb_props pvr2_750xx_dvb_props = { .frontend_attach = pvr2_s5h1409_attach, .tuner_attach = pvr2_tda18271_8295_attach, }; -struct pvr2_dvb_props pvr2_751xx_dvb_props = { +static struct pvr2_dvb_props pvr2_751xx_dvb_props = { .frontend_attach = pvr2_s5h1411_attach, .tuner_attach = pvr2_tda18271_8295_attach, }; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 0a868888f389..37364b072e7b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -3421,7 +3421,7 @@ static void pvr2_hdw_cmd_modeswitch(struct pvr2_hdw *hdw,int digitalFl) } -void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) +static void pvr2_led_ctrl_hauppauge(struct pvr2_hdw *hdw, int onoff) { /* change some GPIO data * -- cgit v1.2.3 From 5a4f5da6552e6c55eff6fbddfee3eab908325c63 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 11 May 2008 16:37:50 -0300 Subject: V4L/DVB (7883): pvrusb2: make default frequency configurable via modprobe option The pvrusb2 driver initially sets the tuner to known broadcast frequencies in the Chicago area, to ease driver testing for the maintainer. This patch keeps those default frequencies, but allows them to be altered via modprobe option. This allows the same ease and convenience for testing multiple pvrusb2 devices one after another under other conditions and areas. For instance, the default initial frequency, 175.25 MHz, might not necessarily be valid on all cable television networks, but usually will be a valid NTSC broadcast channel. Signed-off-by: Michael Krufky Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 37364b072e7b..584716e0c171 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -67,6 +67,16 @@ MODULE_PARM_DESC(video_std,"specify initial video standard"); module_param_array(tolerance, int, NULL, 0444); MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); +/* US Broadcast channel 7 (175.25 MHz) */ +static int default_tv_freq = 175250000L; +/* 104.3 MHz, a usable FM station for my area */ +static int default_radio_freq = 104300000L; + +module_param_named(tv_freq, default_tv_freq, int, 0444); +MODULE_PARM_DESC(tv_freq, "specify initial television frequency"); +module_param_named(radio_freq, default_radio_freq, int, 0444); +MODULE_PARM_DESC(radio_freq, "specify initial radio frequency"); + #define PVR2_CTL_WRITE_ENDPOINT 0x01 #define PVR2_CTL_READ_ENDPOINT 0x81 @@ -1701,10 +1711,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) are, but I set them to something usable in the Chicago area just to make driver testing a little easier. */ - /* US Broadcast channel 7 (175.25 MHz) */ - hdw->freqValTelevision = 175250000L; - /* 104.3 MHz, a usable FM station for my area */ - hdw->freqValRadio = 104300000L; + hdw->freqValTelevision = default_tv_freq; + hdw->freqValRadio = default_radio_freq; // Do not use pvr2_reset_ctl_endpoints() here. It is not // thread-safe against the normal pvr2_send_request() mechanism. -- cgit v1.2.3 From 4cbeb3711481a7e563fe4c61888986c4aa1cb22e Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Mon, 12 May 2008 11:53:10 -0300 Subject: V4L/DVB (7886): ivtvfb: Use DMA for write() write() operations to the ivtv framebuffer will now attempt to use DMA if the amount of data to copy is >= 4096 bytes. This change effectively depreciates the need for the proprietary IVTVFB_IOC_DMA_FRAME ioctl since a write() of sufficient size will do the same thing. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 82 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 73be154f7f05..e8dbee443946 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -367,6 +367,87 @@ static int ivtvfb_prep_frame(struct ivtv *itv, int cmd, void __user *source, return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count); } +static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long p = *ppos; + void *dst; + int err = 0; + unsigned long total_size; + struct ivtv *itv = (struct ivtv *) info->par; + unsigned long dma_offset = + IVTV_DECODER_OFFSET + itv->osd_info->video_rbase; + unsigned long dma_size; + u16 lead = 0, tail = 0; + + if (info->state != FBINFO_STATE_RUNNING) + return -EPERM; + + total_size = info->screen_size; + + if (total_size == 0) + total_size = info->fix.smem_len; + + if (p > total_size) + return -EFBIG; + + if (count > total_size) { + err = -EFBIG; + count = total_size; + } + + if (count + p > total_size) { + if (!err) + err = -ENOSPC; + + count = total_size - p; + } + + dst = (void __force *) (info->screen_base + p); + + if (info->fbops->fb_sync) + info->fbops->fb_sync(info); + + if (!access_ok(VERIFY_READ, buf, count)) { + IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n", + (unsigned long)buf); + err = -EFAULT; + } + + if (!err) { + /* If transfer size > threshold and both src/dst + addresses are aligned, use DMA */ + if (count >= 4096 && ((u32)buf & 3) == ((u32)dst & 3)) { + /* Odd address = can't DMA. Align */ + if ((u32)dst & 3) { + lead = 4 - ((u32)dst & 3); + memcpy(dst, buf, lead); + buf += lead; + dst += lead; + } + /* DMA resolution is 32 bits */ + if ((count - lead) & 3) + tail = (count - lead) & 3; + /* DMA the data */ + dma_size = count - lead - tail; + err = ivtvfb_prep_dec_dma_to_device(itv, + p + lead + dma_offset, (void *)buf, dma_size); + dst += dma_size; + buf += dma_size; + /* Copy any leftover data */ + if (tail) + memcpy(dst, buf, tail); + } else { + memcpy(dst, buf, count); + } + } + + if (!err) + *ppos += count; + + return (err) ? err : count; +} + static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { DEFINE_WAIT(wait); @@ -824,6 +905,7 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info) static struct fb_ops ivtvfb_ops = { .owner = THIS_MODULE, + .fb_write = ivtvfb_write, .fb_check_var = ivtvfb_check_var, .fb_set_par = ivtvfb_set_par, .fb_setcolreg = ivtvfb_setcolreg, -- cgit v1.2.3 From 34cb61693e204897a6ae37d56a1e07d0cdd8cdbf Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 May 2008 09:21:06 -0300 Subject: V4L/DVB (7897): TCM825x: Include invertation of image mirroring in configuration Add invertation of image mirroring register bits to default configuration. This is useful when the camera module is e.g. mounted upside down. Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tcm825x.c | 6 ++++++ drivers/media/video/tcm825x.h | 1 + 2 files changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c index 8f0100f67a91..29991d1cf13e 100644 --- a/drivers/media/video/tcm825x.c +++ b/drivers/media/video/tcm825x.c @@ -523,6 +523,9 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, if (val < 0) return val; + if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP) + val ^= sensor->platform_data->is_upside_down(); + vc->value = val; return 0; } @@ -556,6 +559,9 @@ static int ioctl_s_ctrl(struct v4l2_int_device *s, if (lvc == NULL) return -EINVAL; + if (vc->id == V4L2_CID_HFLIP || vc->id == V4L2_CID_VFLIP) + val ^= sensor->platform_data->is_upside_down(); + val = val << lvc->start_bit; if (tcm825x_write_reg_mask(client, lvc->reg, val)) return -EIO; diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h index 966765b66b3a..770ebacfa344 100644 --- a/drivers/media/video/tcm825x.h +++ b/drivers/media/video/tcm825x.h @@ -182,6 +182,7 @@ struct tcm825x_platform_data { int (*needs_reset)(struct v4l2_int_device *s, void *buf, struct v4l2_pix_format *fmt); int (*ifparm)(struct v4l2_ifparm *p); + int (*is_upside_down)(void); }; /* Array of image sizes supported by TCM825X. These must be ordered from -- cgit v1.2.3 From 4388c3b4fe0362e8bb3fe3a09b312db929b8c730 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 17 May 2008 22:58:04 -0300 Subject: V4L/DVB (7912): TDA10023: make few parameters configurable - separate TDA10021 and TDA10023 attach - configurable Xtal settings - configurable input freq offset + baseband conversion type settings Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10023.c | 193 +++++++++++++++++++-------------- drivers/media/dvb/frontends/tda1002x.h | 31 ++++-- drivers/media/dvb/ttpci/budget-av.c | 12 +- 3 files changed, 145 insertions(+), 91 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index c6ff5b82ff80..2996b73cf4b4 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c @@ -38,75 +38,29 @@ #include "dvb_frontend.h" #include "tda1002x.h" +#define REG0_INIT_VAL 0x23 struct tda10023_state { struct i2c_adapter* i2c; /* configuration settings */ - const struct tda1002x_config* config; + const struct tda10023_config *config; struct dvb_frontend frontend; u8 pwm; u8 reg0; -}; + /* clock settings */ + u32 xtal; + u8 pll_m; + u8 pll_p; + u8 pll_n; + u32 sysclk; +}; #define dprintk(x...) static int verbose; -#define XTAL 28920000UL -#define PLL_M 8UL -#define PLL_P 4UL -#define PLL_N 1UL -#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000 - -static u8 tda10023_inittab[]={ - // reg mask val - 0x2a,0xff,0x02, // PLL3, Bypass, Power Down - 0xff,0x64,0x00, // Sleep 100ms - 0x2a,0xff,0x03, // PLL3, Bypass, Power Down - 0xff,0x64,0x00, // Sleep 100ms - 0x28,0xff,PLL_M-1, // PLL1 M=8 - 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2 - 0x00,0xff,0x23, // GPR FSAMPLING=1 - 0x2a,0xff,0x08, // PLL3 PSACLK=1 - 0xff,0x64,0x00, // Sleep 100ms - 0x1f,0xff,0x00, // RESET - 0xff,0x64,0x00, // Sleep 100ms - 0xe6,0x0c,0x04, // RSCFG_IND - 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1 - - 0x0e,0xff,0x82, // GAIN1 - 0x03,0x08,0x08, // CLKCONF DYN=1 - 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0 - 0x01,0xff,0x30, // AGCREF - 0x1e,0x84,0x84, // CONTROL SACLK_ON=1 - 0x1b,0xff,0xc8, // ADC TWOS=1 - 0x3b,0xff,0xff, // IFMAX - 0x3c,0xff,0x00, // IFMIN - 0x34,0xff,0x00, // PWMREF - 0x35,0xff,0xff, // TUNMAX - 0x36,0xff,0x00, // TUNMIN - 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77 - 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1 - 0x37,0xff,0xf6, // DELTAF_LSB - 0x38,0xff,0xff, // DELTAF_MSB - 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 - 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 - 0x04,0x10,0x00, // SWRAMP=1 - 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0 - 0x2b,0x01,0xa1, // INTS1 - 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? - 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0 - 0xc4,0xff,0x00, - 0xc3,0x30,0x00, - 0xb5,0xff,0x19, // ERAGC_THD - 0x00,0x03,0x01, // GPR, CLBS soft reset - 0x00,0x03,0x03, // GPR, CLBS soft reset - 0xff,0x64,0x00, // Sleep 100ms - 0xff,0xff,0xff -}; - static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) { u8 b0 [] = { reg }; @@ -219,30 +173,34 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) s16 SFIL=0; u16 NDEC = 0; - if (sr < (u32)(SYSCLK/98.40)) { + /* avoid floating point operations multiplying syscloc and divider + by 10 */ + u32 sysclk_x_10 = state->sysclk * 10; + + if (sr < (u32)(sysclk_x_10/984)) { NDEC=3; SFIL=1; - } else if (sr<(u32)(SYSCLK/64.0)) { + } else if (sr < (u32)(sysclk_x_10/640)) { NDEC=3; SFIL=0; - } else if (sr<(u32)(SYSCLK/49.2)) { + } else if (sr < (u32)(sysclk_x_10/492)) { NDEC=2; SFIL=1; - } else if (sr<(u32)(SYSCLK/32.0)) { + } else if (sr < (u32)(sysclk_x_10/320)) { NDEC=2; SFIL=0; - } else if (sr<(u32)(SYSCLK/24.6)) { + } else if (sr < (u32)(sysclk_x_10/246)) { NDEC=1; SFIL=1; - } else if (sr<(u32)(SYSCLK/16.0)) { + } else if (sr < (u32)(sysclk_x_10/160)) { NDEC=1; SFIL=0; - } else if (sr<(u32)(SYSCLK/12.3)) { + } else if (sr < (u32)(sysclk_x_10/123)) { NDEC=0; SFIL=1; } - BDRI=SYSCLK*16; + BDRI = (state->sysclk)*16; BDRI>>=NDEC; BDRI +=sr/2; BDRI /=sr; @@ -255,11 +213,12 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) BDRX=1<<(24+NDEC); BDRX*=sr; - do_div(BDRX,SYSCLK); // BDRX/=SYSCLK; + do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */ BDR=(s32)BDRX; } -// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC); + dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n", + sr, BDR, BDRI, NDEC); tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); tda10023_writereg (state, 0x0a, BDR&255); tda10023_writereg (state, 0x0b, (BDR>>8)&255); @@ -272,8 +231,63 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) static int tda10023_init (struct dvb_frontend *fe) { struct tda10023_state* state = fe->demodulator_priv; + u8 tda10023_inittab[] = { +/* reg mask val */ +/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */ +/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ +/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */ +/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ + /* PLL1 */ +/* 012 */ 0x28, 0xff, (state->pll_m-1), + /* PLL2 */ +/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1), + /* GPR FSAMPLING=1 */ +/* 018 */ 0x00, 0xff, REG0_INIT_VAL, +/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */ +/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ +/* 027 */ 0x1f, 0xff, 0x00, /* RESET */ +/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ +/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */ +/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */ + +/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */ +/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */ +/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 + PPWMTUN=0 PPWMIF=0 */ +/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */ +/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */ +/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */ +/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */ +/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */ +/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */ +/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */ +/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */ +/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */ +/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */ +/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */ +/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */ +/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */ +/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */ +/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */ +/* 093 */ 0x12, 0xff, 0xa1, /* INTP1 POCLKP=1 FEL=1 MFS=0 */ +/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */ +/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */ +/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */ +/* 105 */ 0xc4, 0xff, 0x00, +/* 108 */ 0xc3, 0x30, 0x00, +/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */ +/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */ +/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */ +/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ +/* 123 */ 0xff, 0xff, 0xff +}; + dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num); - dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num); + /* override default values if set in config */ + if (state->config->deltaf) { + tda10023_inittab[80] = (state->config->deltaf & 0xff); + tda10023_inittab[83] = (state->config->deltaf >> 8); + } tda10023_writetab(state, tda10023_inittab); @@ -460,12 +474,11 @@ static void tda10023_release(struct dvb_frontend* fe) static struct dvb_frontend_ops tda10023_ops; -struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, +struct dvb_frontend *tda10023_attach(const struct tda10023_config *config, + struct i2c_adapter *i2c, u8 pwm) { struct tda10023_state* state = NULL; - int i; /* allocate memory for the internal state */ state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); @@ -474,22 +487,40 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, /* setup the state */ state->config = config; state->i2c = i2c; - memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); - state->pwm = pwm; - for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) { - if (tda10023_inittab[i] == 0x00) { - state->reg0 = tda10023_inittab[i+2]; - break; - } - } - // Wakeup if in standby + /* wakeup if in standby */ tda10023_writereg (state, 0x00, 0x33); /* check if the demod is there */ if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; /* create dvb_frontend */ memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); + state->pwm = pwm; + state->reg0 = REG0_INIT_VAL; + if (state->config->xtal) { + state->xtal = state->config->xtal; + state->pll_m = state->config->pll_m; + state->pll_p = state->config->pll_p; + state->pll_n = state->config->pll_n; + } else { + /* set default values if not defined in config */ + state->xtal = 28920000; + state->pll_m = 8; + state->pll_p = 4; + state->pll_n = 1; + } + + /* calc sysclk */ + state->sysclk = (state->xtal * state->pll_m / \ + (state->pll_n * state->pll_p)); + + state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64; + state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4; + + dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n", + __func__, state->xtal, state->pll_m, state->pll_p, + state->pll_n); + state->frontend.demodulator_priv = state; return &state->frontend; @@ -504,10 +535,10 @@ static struct dvb_frontend_ops tda10023_ops = { .name = "Philips TDA10023 DVB-C", .type = FE_QAM, .frequency_stepsize = 62500, - .frequency_min = 47000000, + .frequency_min = 47000000, .frequency_max = 862000000, - .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */ - .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */ + .symbol_rate_min = 0, /* set in tda10023_attach */ + .symbol_rate_max = 0, /* set in tda10023_attach */ .caps = 0x400 | //FE_CAN_QAM_4 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 | diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h index 1bcc0d44b90b..4522b7ef53c9 100644 --- a/drivers/media/dvb/frontends/tda1002x.h +++ b/drivers/media/dvb/frontends/tda1002x.h @@ -26,11 +26,25 @@ #include -struct tda1002x_config -{ +struct tda1002x_config { + /* the demodulator's i2c address */ + u8 demod_address; + u8 invert; +}; + +struct tda10023_config { /* the demodulator's i2c address */ u8 demod_address; u8 invert; + + /* clock settings */ + u32 xtal; /* defaults: 28920000 */ + u8 pll_m; /* defaults: 8 */ + u8 pll_p; /* defaults: 4 */ + u8 pll_n; /* defaults: 1 */ + + /* input freq offset + baseband conversion type */ + u16 deltaf; }; #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) @@ -45,12 +59,15 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* } #endif // CONFIG_DVB_TDA10021 -#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm); +#if defined(CONFIG_DVB_TDA10023) || \ + (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) +extern struct dvb_frontend *tda10023_attach( + const struct tda10023_config *config, + struct i2c_adapter *i2c, u8 pwm); #else -static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm) +static inline struct dvb_frontend *tda10023_attach( + const struct tda1002x_config *config, + struct i2c_adapter *i2c, u8 pwm) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index b30a5288e484..b7d1f2f18d3a 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -667,6 +667,11 @@ static struct tda1002x_config philips_cu1216_config_altaddress = { .invert = 0, }; +static struct tda10023_config philips_cu1216_tda10023_config = { + .demod_address = 0x0c, + .invert = 1, +}; + static int philips_tu1216_tuner_init(struct dvb_frontend *fe) { struct budget *budget = (struct budget *) fe->dvb->priv; @@ -1019,9 +1024,10 @@ static void frontend_init(struct budget_av *budget_av) case SUBID_DVBC_KNC1_PLUS_MK3: budget_av->reinitialise_demod = 1; budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - fe = dvb_attach(tda10023_attach, &philips_cu1216_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); + fe = dvb_attach(tda10023_attach, + &philips_cu1216_tda10023_config, + &budget_av->budget.i2c_adap, + read_pwm(budget_av)); if (fe) { fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; } -- cgit v1.2.3 From 139dfeb2611ce92dec4c6b77297d209748340a21 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 17 May 2008 23:02:00 -0300 Subject: V4L/DVB (7913): DVB-PLL: add Samsung DTOS403IH102A tuner - add Samsung DTOS403IH102A tuner Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dvb-pll.c | 47 +++++++++++++++++++++++++++++++++++ drivers/media/dvb/frontends/dvb-pll.h | 1 + 2 files changed, 48 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index a054894ff481..ea058153ebfa 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -343,6 +343,52 @@ static struct dvb_pll_desc dvb_pll_opera1 = { } }; +static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) +{ + struct dvb_pll_priv *priv = fe->tuner_priv; + struct i2c_msg msg = { + .addr = priv->pll_i2c_address, + .flags = 0, + .buf = buf, + .len = 4 + }; + int result; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + result = i2c_transfer(priv->i2c, &msg, 1); + if (result != 1) + printk(KERN_ERR "%s: i2c_transfer failed:%d", + __func__, result); + + buf[2] = 0x9e; + buf[3] = 0x90; + + return; +} + +/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */ +static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = { + .name = "Samsung DTOS403IH102A", + .min = 44250000, + .max = 858000000, + .iffreq = 36125000, + .count = 8, + .set = samsung_dtos403ih102a_set, + .entries = { + { 135000000, 62500, 0xbe, 0x01 }, + { 177000000, 62500, 0xf6, 0x01 }, + { 370000000, 62500, 0xbe, 0x02 }, + { 450000000, 62500, 0xf6, 0x02 }, + { 466000000, 62500, 0xfe, 0x02 }, + { 538000000, 62500, 0xbe, 0x08 }, + { 826000000, 62500, 0xf6, 0x08 }, + { 999999999, 62500, 0xfe, 0x08 }, + } +}; + /* ----------------------------------------------------------- */ static struct dvb_pll_desc *pll_list[] = { @@ -360,6 +406,7 @@ static struct dvb_pll_desc *pll_list[] = { [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, [DVB_PLL_OPERA1] = &dvb_pll_opera1, + [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a, }; /* ----------------------------------------------------------- */ diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 872ca29e7cf3..05239f579ccf 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h @@ -22,6 +22,7 @@ #define DVB_PLL_SAMSUNG_TBMV 11 #define DVB_PLL_PHILIPS_SD1878_TDA8261 12 #define DVB_PLL_OPERA1 13 +#define DVB_PLL_SAMSUNG_DTOS403IH102A 14 /** * Attach a dvb-pll to the supplied frontend structure. -- cgit v1.2.3 From a51e34dd6080d8d5c9e95a4e0292cd4cb889a61b Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 17 May 2008 23:05:48 -0300 Subject: V4L/DVB (7914): Anysee: driver for Anysee DVB-T/C receiver - driver for Anysee DVB-T/C receiver Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 9 + drivers/media/dvb/dvb-usb/Makefile | 3 + drivers/media/dvb/dvb-usb/anysee.c | 555 ++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/anysee.h | 304 +++++++++++++++++ drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 + 5 files changed, 873 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/anysee.c create mode 100644 drivers/media/dvb/dvb-usb/anysee.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index f00a0eb40420..3f7b9b6326b3 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -241,3 +241,12 @@ config DVB_USB_AF9005_REMOTE Say Y here to support the default remote control decoding for the Afatech AF9005 based receiver. +config DVB_USB_ANYSEE + tristate "Anysee DVB-T/C USB2.0 support" + depends on DVB_USB + select DVB_MT352 if !DVB_FE_CUSTOMISE + select DVB_ZL10353 if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE + help + Say Y here to support the Anysee E30, Anysee E30 Plus or + Anysee E30 C Plus DVB USB2.0 receiver. diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index c6511a6c0ab8..44c11e45e564 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -61,6 +61,9 @@ obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o dvb-usb-af9005-remote-objs = af9005-remote.o obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o +dvb-usb-anysee-objs = anysee.o +obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c new file mode 100644 index 000000000000..dada92a14cf3 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -0,0 +1,555 @@ +/* + * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver + * + * Copyright (C) 2007 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * - add smart card reader support for Conditional Access (CA) + * + * Card reader in Anysee is nothing more than ISO 7816 card reader. + * There is no hardware CAM in any Anysee device sold. + * In my understanding it should be implemented by making own module + * for ISO 7816 card reader, like dvb_ca_en50221 is implented. This + * module registers serial interface that can be used to comminicate + * with any ISO 7816 smart card. + * + * Any help according to implement serial smart card reader support + * is highly welcome! + */ + +#include "anysee.h" +#include "tda1002x.h" +#include "mt352.h" +#include "mt352_priv.h" +#include "zl10353.h" + +/* debug */ +static int dvb_usb_anysee_debug; +module_param_named(debug, dvb_usb_anysee_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +struct mutex anysee_usb_mutex; + +static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, + u8 *rbuf, u8 rlen) +{ + struct anysee_state *state = d->priv; + int act_len, ret; + u8 buf[64]; + + if (slen > sizeof(buf)) + slen = sizeof(buf); + memcpy(&buf[0], sbuf, slen); + buf[60] = state->seq++; + + if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) + return -EAGAIN; + + /* We need receive one message more after dvb_usb_generic_rw due + to weird transaction flow, which is 1 x send + 2 x receive. */ + ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); + + if (!ret) { + /* receive 2nd answer */ + ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, + d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), + &act_len, 2000); + if (ret) + err("%s: recv bulk message failed: %d", __func__, ret); + else { + deb_xfer("<<< "); + debug_dump(buf, act_len, deb_xfer); + } + } + + /* read request, copy returned data to return buf */ + if (!ret && rbuf && rlen) + memcpy(rbuf, buf, rlen); + + mutex_unlock(&anysee_usb_mutex); + + return ret; +} + +static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val) +{ + u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01}; + int ret; + ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1); + deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val); + return ret; +} + +static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val) +{ + u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val}; + deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val); + return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); +} + +static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) +{ + u8 buf[] = {CMD_GET_HW_INFO}; + return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3); +} + +static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00}; + deb_info("%s: onoff:%02x\n", __func__, onoff); + return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0); +} + +static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval) +{ + u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval}; + deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval); + return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); +} + +static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) +{ + u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff}; + deb_info("%s: onoff:%02x\n", __func__, onoff); + return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); +} + +static int anysee_init(struct dvb_usb_device *d) +{ + int ret; + /* LED light */ + ret = anysee_led_ctrl(d, 0x01, 0x03); + if (ret) + return ret; + + /* enable IR */ + ret = anysee_ir_ctrl(d, 1); + if (ret) + return ret; + + return 0; +} + +/* I2C */ +static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, + int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int ret, inc, i = 0; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + while (i < num) { + if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + u8 buf[6]; + buf[0] = CMD_I2C_READ; + buf[1] = msg[i].addr + 1; + buf[2] = msg[i].buf[0]; + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x01; + ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf, + msg[i+1].len); + inc = 2; + } else { + u8 buf[4+msg[i].len]; + buf[0] = CMD_I2C_WRITE; + buf[1] = msg[i].addr; + buf[2] = msg[i].len; + buf[3] = 0x01; + memcpy(&buf[4], msg[i].buf, msg[i].len); + ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); + inc = 1; + } + if (ret) + return ret; + + i += inc; + } + + mutex_unlock(&d->i2c_mutex); + + return i; +} + +static u32 anysee_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm anysee_i2c_algo = { + .master_xfer = anysee_master_xfer, + .functionality = anysee_i2c_func, +}; + +static int anysee_mt352_demod_init(struct dvb_frontend *fe) +{ + static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; + static u8 reset [] = { RESET, 0x80 }; + static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; + static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; + static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; + static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; + + mt352_write(fe, clock_config, sizeof(clock_config)); + udelay(200); + mt352_write(fe, reset, sizeof(reset)); + mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); + + mt352_write(fe, agc_cfg, sizeof(agc_cfg)); + mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); + mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); + + return 0; +} + +/* Callbacks for DVB USB */ +static struct tda10023_config anysee_tda10023_config = { + .demod_address = 0x1a, + .invert = 0, + .xtal = 16000000, + .pll_m = 11, + .pll_p = 3, + .pll_n = 1, + .deltaf = 0xfed6, +}; + +static struct mt352_config anysee_mt352_config = { + .demod_address = 0x1e, + .demod_init = anysee_mt352_demod_init, +}; + +static struct zl10353_config anysee_zl10353_config = { + .demod_address = 0x1e, + .parallel_ts = 1, +}; + +static int anysee_frontend_attach(struct dvb_usb_adapter *adap) +{ + int ret; + struct anysee_state *state = adap->dev->priv; + u8 hw_info[3]; + u8 io_d; /* IO port D */ + + /* check which hardware we have + We must do this call two times to get reliable values (hw bug). */ + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + return ret; + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + return ret; + + /* Meaning of these info bytes are guessed. */ + info("firmware version:%d.%d.%d hardware id:%d", + 0, hw_info[1], hw_info[2], hw_info[0]); + + ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */ + if (ret) + return ret; + deb_info("%s: IO port D:%02x\n", __func__, io_d); + + /* Select demod using trial and error method. */ + + /* Try to attach demodulator in following order: + model demod hw firmware + 1. E30 MT352 02 0.2.1 + 2. E30 ZL10353 02 0.2.1 + 3. E30 Plus ZL10353 06 0.1.0 + 4. E30C Plus TDA10023 0a 0.1.0 + E30C Plus TDA10023 0f 0.1.2 (not working) + */ + + /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ + adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config, + &adap->dev->i2c_adap); + if (adap->fe != NULL) { + state->tuner = DVB_PLL_THOMSON_DTT7579; + return 0; + } + + /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ + adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, + &adap->dev->i2c_adap); + if (adap->fe != NULL) { + state->tuner = DVB_PLL_THOMSON_DTT7579; + return 0; + } + + /* connect demod on IO port D for TDA10023 & ZL10353 */ + ret = anysee_write_reg(adap->dev, 0xb0, 0x25); + if (ret) + return ret; + + /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ + adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, + &adap->dev->i2c_adap); + if (adap->fe != NULL) { + state->tuner = DVB_PLL_THOMSON_DTT7579; + return 0; + } + + /* known not working (E30C Plus v0.1.2) */ + if (hw_info[0] == 0x0f) { + info("this version of Anysee is not supported yet"); + /* return IO port D to init value for safe */ + ret = anysee_write_reg(adap->dev, 0xb0, io_d); + return -ENODEV; + } + + /* Philips TDA10023 DVB-C demod */ + adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, + &adap->dev->i2c_adap, 0x48); + if (adap->fe != NULL) { + state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; + return 0; + } + + /* return IO port D to init value for safe */ + ret = anysee_write_reg(adap->dev, 0xb0, io_d); + if (ret) + return ret; + + err("Unkown Anysee version: %02x %02x %02x. "\ + "Please report the .", + hw_info[0], hw_info[1], hw_info[2]); + + return -ENODEV; +} + +static int anysee_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct anysee_state *state = adap->dev->priv; + deb_info("%s: \n", __func__); + + switch (state->tuner) { + case DVB_PLL_THOMSON_DTT7579: + /* Thomson dtt7579 (not sure) PLL inside of: + Samsung DNOS404ZH102A NIM + Samsung DNOS404ZH103A NIM */ + dvb_attach(dvb_pll_attach, adap->fe, 0x61, + NULL, DVB_PLL_THOMSON_DTT7579); + break; + case DVB_PLL_SAMSUNG_DTOS403IH102A: + /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */ + dvb_attach(dvb_pll_attach, adap->fe, 0xc0, + &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + break; + } + + return 0; +} + +static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 buf[] = {CMD_GET_IR_CODE}; + struct dvb_usb_rc_key *keymap = d->props.rc_key_map; + u8 ircode[2]; + int i, ret; + + ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2); + if (ret) + return ret; + + *event = 0; + *state = REMOTE_NO_KEY_PRESSED; + + for (i = 0; i < d->props.rc_key_map_size; i++) { + if (keymap[i].custom == ircode[0] && + keymap[i].data == ircode[1]) { + *event = keymap[i].event; + *state = REMOTE_KEY_PRESSED; + return 0; + } + } + return 0; +} + +static struct dvb_usb_rc_key anysee_rc_keys[] = { + { 0x01, 0x00, KEY_0 }, + { 0x01, 0x01, KEY_1 }, + { 0x01, 0x02, KEY_2 }, + { 0x01, 0x03, KEY_3 }, + { 0x01, 0x04, KEY_4 }, + { 0x01, 0x05, KEY_5 }, + { 0x01, 0x06, KEY_6 }, + { 0x01, 0x07, KEY_7 }, + { 0x01, 0x08, KEY_8 }, + { 0x01, 0x09, KEY_9 }, + { 0x01, 0x0a, KEY_POWER }, + { 0x01, 0x0b, KEY_DOCUMENTS }, /* * */ + { 0x01, 0x19, KEY_FAVORITES }, + { 0x01, 0x20, KEY_SLEEP }, + { 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */ + { 0x01, 0x22, KEY_ZOOM }, + { 0x01, 0x47, KEY_TEXT }, + { 0x01, 0x16, KEY_TV }, /* TV / radio select */ + { 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */ + { 0x01, 0x1a, KEY_SUBTITLE }, + { 0x01, 0x1b, KEY_CAMERA }, /* screenshot */ + { 0x01, 0x42, KEY_MUTE }, + { 0x01, 0x0e, KEY_MENU }, + { 0x01, 0x0f, KEY_EPG }, + { 0x01, 0x17, KEY_INFO }, + { 0x01, 0x10, KEY_EXIT }, + { 0x01, 0x13, KEY_VOLUMEUP }, + { 0x01, 0x12, KEY_VOLUMEDOWN }, + { 0x01, 0x11, KEY_CHANNELUP }, + { 0x01, 0x14, KEY_CHANNELDOWN }, + { 0x01, 0x15, KEY_OK }, + { 0x01, 0x1d, KEY_RED }, + { 0x01, 0x1f, KEY_GREEN }, + { 0x01, 0x1c, KEY_YELLOW }, + { 0x01, 0x44, KEY_BLUE }, + { 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */ + { 0x01, 0x48, KEY_STOP }, + { 0x01, 0x50, KEY_PLAY }, + { 0x01, 0x51, KEY_PAUSE }, + { 0x01, 0x49, KEY_RECORD }, + { 0x01, 0x18, KEY_PREVIOUS }, /* |<< */ + { 0x01, 0x0d, KEY_NEXT }, /* >>| */ + { 0x01, 0x24, KEY_PROG1 }, /* F1 */ + { 0x01, 0x25, KEY_PROG2 }, /* F2 */ +}; + +/* DVB USB Driver stuff */ +static struct dvb_usb_device_properties anysee_properties; + +static int anysee_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct dvb_usb_device *d; + struct usb_host_interface *alt; + int ret; + + mutex_init(&anysee_usb_mutex); + + /* There is one interface with two alternate settings. + Alternate setting 0 is for bulk transfer. + Alternate setting 1 is for isochronous transfer. + We use bulk transfer (alternate setting 0). */ + if (intf->num_altsetting < 1) + return -ENODEV; + + ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d, + adapter_nr); + if (ret) + return ret; + + alt = usb_altnum_to_altsetting(intf, 0); + if (alt == NULL) { + deb_info("%s: no alt found!\n", __func__); + return -ENODEV; + } + + ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); + if (ret) + return ret; + + if (d) + ret = anysee_init(d); + + return ret; +} + +static struct usb_device_id anysee_table [] = { + { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, + { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, anysee_table); + +static struct dvb_usb_device_properties anysee_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = DEVICE_SPECIFIC, + + .size_of_priv = sizeof(struct anysee_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = anysee_streaming_ctrl, + .frontend_attach = anysee_frontend_attach, + .tuner_attach = anysee_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 512, + } + } + }, + } + }, + + .rc_key_map = anysee_rc_keys, + .rc_key_map_size = ARRAY_SIZE(anysee_rc_keys), + .rc_query = anysee_rc_query, + .rc_interval = 200, /* windows driver uses 500ms */ + + .i2c_algo = &anysee_i2c_algo, + + .generic_bulk_ctrl_endpoint = 1, + + .num_device_descs = 1, + .devices = { + { + .name = "Anysee DVB USB2.0", + .cold_ids = {NULL}, + .warm_ids = {&anysee_table[0], + &anysee_table[1], NULL}, + }, + } +}; + +static struct usb_driver anysee_driver = { + .name = "dvb_usb_anysee", + .probe = anysee_probe, + .disconnect = dvb_usb_device_exit, + .id_table = anysee_table, +}; + +/* module stuff */ +static int __init anysee_module_init(void) +{ + int ret; + + ret = usb_register(&anysee_driver); + if (ret) + err("%s: usb_register failed. Error number %d", __func__, ret); + + return ret; +} + +static void __exit anysee_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&anysee_driver); +} + +module_init(anysee_module_init); +module_exit(anysee_module_exit); + +MODULE_AUTHOR("Antti Palosaari "); +MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h new file mode 100644 index 000000000000..48da3949ef0b --- /dev/null +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -0,0 +1,304 @@ +/* + * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver + * + * Copyright (C) 2007 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * TODO: + * - add smart card reader support for Conditional Access (CA) + * + * Card reader in Anysee is nothing more than ISO 7816 card reader. + * There is no hardware CAM in any Anysee device sold. + * In my understanding it should be implemented by making own module + * for ISO 7816 card reader, like dvb_ca_en50221 is implented. This + * module registers serial interface that can be used to comminicate + * with any ISO 7816 smart card. + * + * Any help according to implement serial smart card reader support + * is highly welcome! + */ + +#ifndef _DVB_USB_ANYSEE_H_ +#define _DVB_USB_ANYSEE_H_ + +#define DVB_USB_LOG_PREFIX "anysee" +#include "dvb-usb.h" + +#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) +#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) +#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args) +#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args) +#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args) +#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args) + +enum cmd { + CMD_I2C_READ = 0x33, + CMD_I2C_WRITE = 0x31, + CMD_REG_READ = 0xb0, + CMD_REG_WRITE = 0xb1, + CMD_STREAMING_CTRL = 0x12, + CMD_LED_AND_IR_CTRL = 0x16, + CMD_GET_IR_CODE = 0x41, + CMD_GET_HW_INFO = 0x19, + CMD_SMARTCARD = 0x34, +}; + +struct anysee_state { + u8 tuner; + u8 seq; +}; + +#endif + +/*************************************************************************** + * USB API description (reverse engineered) + *************************************************************************** + +Transaction flow: +================= +BULK[00001] >>> REQUEST PACKET 64 bytes +BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY) +BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY) + +General reply packet(s) are always used if not own reply defined. + +============================================================================ +| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY) +============================================================================ +| 00 | reply data (if any) from previous transaction +| | Just same reply packet as returned during previous transaction. +| | Needed only if reply is missed in previous transaction. +| | Just skip normally. +---------------------------------------------------------------------------- +| 01-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY) +============================================================================ +| 00 | reply data (if any) +---------------------------------------------------------------------------- +| 01-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | I2C WRITE REQUEST PACKET +============================================================================ +| 00 | 0x31 I2C write command +---------------------------------------------------------------------------- +| 01 | i2c address +---------------------------------------------------------------------------- +| 02 | data length +| | 0x02 (for typical I2C reg / val pair) +---------------------------------------------------------------------------- +| 03 | 0x01 +---------------------------------------------------------------------------- +| 04- | data +---------------------------------------------------------------------------- +| -59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | I2C READ REQUEST PACKET +============================================================================ +| 00 | 0x33 I2C read command +---------------------------------------------------------------------------- +| 01 | i2c address + 1 +---------------------------------------------------------------------------- +| 02 | register +---------------------------------------------------------------------------- +| 03 | 0x00 +---------------------------------------------------------------------------- +| 04 | 0x00 +---------------------------------------------------------------------------- +| 05 | 0x01 +---------------------------------------------------------------------------- +| 06-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET +============================================================================ +| 00 | 0xb1 register write command +---------------------------------------------------------------------------- +| 01-02 | register +---------------------------------------------------------------------------- +| 03 | 0x01 +---------------------------------------------------------------------------- +| 04 | value +---------------------------------------------------------------------------- +| 05-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET +============================================================================ +| 00 | 0xb0 register read command +---------------------------------------------------------------------------- +| 01-02 | register +---------------------------------------------------------------------------- +| 03 | 0x01 +---------------------------------------------------------------------------- +| 04-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | LED CONTROL REQUEST PACKET +============================================================================ +| 00 | 0x16 LED and IR control command +---------------------------------------------------------------------------- +| 01 | 0x01 (LED) +---------------------------------------------------------------------------- +| 03 | 0x00 blink +| | 0x01 lights continuously +---------------------------------------------------------------------------- +| 04 | blink interval +| | 0x00 fastest (looks like LED lights continuously) +| | 0xff slowest +---------------------------------------------------------------------------- +| 05-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | IR CONTROL REQUEST PACKET +============================================================================ +| 00 | 0x16 LED and IR control command +---------------------------------------------------------------------------- +| 01 | 0x02 (IR) +---------------------------------------------------------------------------- +| 03 | 0x00 IR disabled +| | 0x01 IR enabled +---------------------------------------------------------------------------- +| 04-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | STREAMING CONTROL REQUEST PACKET +============================================================================ +| 00 | 0x12 streaming control command +---------------------------------------------------------------------------- +| 01 | 0x00 streaming disabled +| | 0x01 streaming enabled +---------------------------------------------------------------------------- +| 02 | 0x00 +---------------------------------------------------------------------------- +| 03-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | REMOTE CONTROL REQUEST PACKET +============================================================================ +| 00 | 0x41 remote control command +---------------------------------------------------------------------------- +| 01-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | REMOTE CONTROL REPLY PACKET +============================================================================ +| 00 | 0x00 code not received +| | 0x01 code received +---------------------------------------------------------------------------- +| 01 | remote control code +---------------------------------------------------------------------------- +| 02-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | GET HARDWARE INFO REQUEST PACKET +============================================================================ +| 00 | 0x19 get hardware info command +---------------------------------------------------------------------------- +| 01-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | GET HARDWARE INFO REPLY PACKET +============================================================================ +| 00 | hardware id +---------------------------------------------------------------------------- +| 01-02 | firmware version +---------------------------------------------------------------------------- +| 03-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +============================================================================ +| 00-63 | SMART CARD READER PACKET +============================================================================ +| 00 | 0x34 smart card reader command +---------------------------------------------------------------------------- +| xx | +---------------------------------------------------------------------------- +| xx-59 | don't care +---------------------------------------------------------------------------- +| 60 | packet sequence number +---------------------------------------------------------------------------- +| 61-63 | don't care +---------------------------------------------------------------------------- + +*/ diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 34245d1b7dd9..e6b43fb3a148 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -14,6 +14,7 @@ #define USB_VID_AFATECH 0x15a4 #define USB_VID_ALCOR_MICRO 0x058f #define USB_VID_ALINK 0x05e3 +#define USB_VID_AMT 0x1c73 #define USB_VID_ANCHOR 0x0547 #define USB_VID_ANSONIC 0x10b9 #define USB_VID_ANUBIS_ELECTRONIC 0x10fd @@ -57,6 +58,7 @@ #define USB_PID_AFATECH_AF9005 0x9020 #define USB_VID_ALINK_DTU 0xf170 #define USB_PID_ANSONIC_DVBT_USB 0x6000 +#define USB_PID_ANYSEE 0x861f #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 -- cgit v1.2.3 From 073204326d8f767e9702257c140ca1cf3071fd46 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 25 May 2008 00:25:08 -0300 Subject: V4L/DVB (7917): au8522.c shouldn't #include "dvb-pll.h" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/au8522.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c index 03900d241a76..f7b71657f0f6 100644 --- a/drivers/media/dvb/frontends/au8522.c +++ b/drivers/media/dvb/frontends/au8522.c @@ -26,7 +26,6 @@ #include #include #include "dvb_frontend.h" -#include "dvb-pll.h" #include "au8522.h" struct au8522_state { -- cgit v1.2.3 From bbe09cbe3f082b0af8fd83ccdf5ce1cf005da3eb Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 25 May 2008 13:27:57 -0300 Subject: V4L/DVB (7920): s5h1409.c shouldn't #include "dvb-pll.h" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/s5h1409.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c index b999ec424ff7..5ddb2dca305c 100644 --- a/drivers/media/dvb/frontends/s5h1409.c +++ b/drivers/media/dvb/frontends/s5h1409.c @@ -26,7 +26,6 @@ #include #include #include "dvb_frontend.h" -#include "dvb-pll.h" #include "s5h1409.h" struct s5h1409_state { -- cgit v1.2.3 From 54b6550e430aa8739dceb5ba0fe4325c0208d3a7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 25 May 2008 13:28:46 -0300 Subject: V4L/DVB (7921): s5h1411.c shouldn't #include "dvb-pll.h" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/s5h1411.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c index eb5bfc99d4e9..cff360ce1ba3 100644 --- a/drivers/media/dvb/frontends/s5h1411.c +++ b/drivers/media/dvb/frontends/s5h1411.c @@ -26,7 +26,6 @@ #include #include #include "dvb_frontend.h" -#include "dvb-pll.h" #include "s5h1411.h" struct s5h1411_state { -- cgit v1.2.3 From b4ac3c8d8de387366be11c7320693e0b14429a49 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 13 May 2008 18:27:15 -0300 Subject: V4L/DVB (7924): ivtv/cx18: snprintf fixes snprinf() takes the trailing \0 into account in its length calculations, so there is no need to subtract 1 to the buffer size. Signed-off-by: Jean Delvare Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 2 +- drivers/media/video/ivtv/ivtv-driver.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 2b810bb2a4c7..d9178843e8d2 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -614,7 +614,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, cx18_cards[cx18_cards_active] = cx; cx->dev = dev; cx->num = cx18_cards_active++; - snprintf(cx->name, sizeof(cx->name) - 1, "cx18-%d", cx->num); + snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); CX18_INFO("Initializing card #%d\n", cx->num); spin_unlock(&cx18_cards_lock); diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 797e636771da..bbe92d9dce36 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1019,7 +1019,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, ivtv_cards[ivtv_cards_active] = itv; itv->dev = dev; itv->num = ivtv_cards_active++; - snprintf(itv->name, sizeof(itv->name) - 1, "ivtv%d", itv->num); + snprintf(itv->name, sizeof(itv->name), "ivtv%d", itv->num); IVTV_INFO("Initializing card #%d\n", itv->num); spin_unlock(&ivtv_cards_lock); -- cgit v1.2.3 From d56eebfbdc11d1a3809d8bd793a118da5058ffa8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 20 May 2008 06:19:47 -0300 Subject: V4L/DVB (7926): ivtv: add support for the Buffalo PC-MV5L/PCI card. Thanks to Peter Brandt for doing the necessary tests to fill out the card definition! Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 37 ++++++++++++++++++++++++++++++++++ drivers/media/video/ivtv/ivtv-cards.h | 3 ++- drivers/media/video/ivtv/ivtv-driver.c | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index 4fb8faefe2ce..ba2b0cf4531b 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -1111,6 +1111,42 @@ static const struct ivtv_card ivtv_card_aver_m104 = { .i2c = &ivtv_i2c_std, }; +/* ------------------------------------------------------------------------- */ + +/* Buffalo PC-MV5L/PCI cards */ + +static const struct ivtv_card_pci_info ivtv_pci_buffalo[] = { + { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_MELCO, 0x052b }, + { 0, 0, 0 } +}; + +static const struct ivtv_card ivtv_card_buffalo = { + .type = IVTV_CARD_BUFFALO_MV5L, + .name = "Buffalo PC-MV5L/PCI", + .v4l2_capabilities = IVTV_CAP_ENCODER, + .hw_video = IVTV_HW_CX25840, + .hw_audio = IVTV_HW_CX25840, + .hw_audio_ctrl = IVTV_HW_CX25840, + .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER, + .video_inputs = { + { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 }, + { IVTV_CARD_INPUT_SVIDEO1, 1, + CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 }, + { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 }, + }, + .audio_inputs = { + { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, + { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, + }, + .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, + .xceive_pin = 12, + .tuners = { + { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, + }, + .pci_list = ivtv_pci_buffalo, + .i2c = &ivtv_i2c_std, +}; + static const struct ivtv_card *ivtv_card_list[] = { &ivtv_card_pvr250, &ivtv_card_pvr350, @@ -1137,6 +1173,7 @@ static const struct ivtv_card *ivtv_card_list[] = { &ivtv_card_aver_pvr150, &ivtv_card_aver_ezmaker, &ivtv_card_aver_m104, + &ivtv_card_buffalo, /* Variations of standard cards but with the same PCI IDs. These cards must come last in this list. */ diff --git a/drivers/media/video/ivtv/ivtv-cards.h b/drivers/media/video/ivtv/ivtv-cards.h index 748485dcebbd..381af1bceef8 100644 --- a/drivers/media/video/ivtv/ivtv-cards.h +++ b/drivers/media/video/ivtv/ivtv-cards.h @@ -49,7 +49,8 @@ #define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */ #define IVTV_CARD_AVER_EZMAKER 23 /* AVerMedia EZMaker PCI Deluxe */ #define IVTV_CARD_AVER_M104 24 /* AverMedia M104 miniPCI card */ -#define IVTV_CARD_LAST 24 +#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */ +#define IVTV_CARD_LAST 25 /* Variants of existing cards but with the same PCI IDs. The driver detects these based on other device information. diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index bbe92d9dce36..323dd68fa1c6 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -191,6 +191,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t23 = AverMedia PVR-150 Plus\n" "\t\t\t24 = AverMedia EZMaker PCI Deluxe\n" "\t\t\t25 = AverMedia M104 (not yet working)\n" + "\t\t\t26 = Buffalo PC-MV5L/PCI\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: BGH, DK, I, M, N, Nc, 60"); -- cgit v1.2.3 From 4451342db5b5b779add112c6b15d676f07c73b33 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 20 May 2008 06:24:04 -0300 Subject: V4L/DVB (7927): ivtv: simplify gpio initialization for XCeive tuners. Separate gpio_init field and xceive_pin and combine the two when the gpio is initialized. So there is no longer any need to set the xceive pin in the gpio_init values, simplifying the creation of a new card definition. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-cards.c | 6 ++---- drivers/media/video/ivtv/ivtv-gpio.c | 11 ++++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index ba2b0cf4531b..dc3fbb320684 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -923,7 +923,6 @@ static const struct ivtv_card ivtv_card_club3d = { { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, - .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */ .xceive_pin = 12, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, @@ -959,7 +958,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = { { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 }, }, /* enable line-in */ - .gpio_init = { .direction = 0xe400, .initial_value = 0x4400 }, + .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, .xceive_pin = 10, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, @@ -1102,7 +1101,7 @@ static const struct ivtv_card ivtv_card_aver_m104 = { }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 }, /* enable line-in + reset tuner */ - .gpio_init = { .direction = 0xe400, .initial_value = 0x4000 }, + .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, .xceive_pin = 10, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, @@ -1138,7 +1137,6 @@ static const struct ivtv_card ivtv_card_buffalo = { { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 }, { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, }, - .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, .xceive_pin = 12, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c index d8ac09f3cce6..bc22905ea20f 100644 --- a/drivers/media/video/ivtv/ivtv-gpio.c +++ b/drivers/media/video/ivtv/ivtv-gpio.c @@ -146,15 +146,20 @@ int ivtv_reset_tuner_gpio(void *dev, int cmd, int value) void ivtv_gpio_init(struct ivtv *itv) { - if (itv->card->gpio_init.direction == 0) + u16 pin = 0; + + if (itv->card->xceive_pin) + pin = 1 << itv->card->xceive_pin; + + if ((itv->card->gpio_init.direction | pin) == 0) return; IVTV_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n", read_reg(IVTV_REG_GPIO_DIR), read_reg(IVTV_REG_GPIO_OUT)); /* init output data then direction */ - write_reg(itv->card->gpio_init.initial_value, IVTV_REG_GPIO_OUT); - write_reg(itv->card->gpio_init.direction, IVTV_REG_GPIO_DIR); + write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT); + write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR); } static struct v4l2_queryctrl gpio_ctrl_mute = { -- cgit v1.2.3 From 64723b301846636accbfb1539ebda0835f683a72 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Sun, 25 May 2008 17:08:13 -0300 Subject: V4L/DVB (7936): pvrusb2: Remove svn Id keyword from all sources Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-audio.c | 1 - drivers/media/video/pvrusb2/pvrusb2-audio.h | 1 - drivers/media/video/pvrusb2/pvrusb2-context.c | 1 - drivers/media/video/pvrusb2/pvrusb2-context.h | 1 - drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 1 - drivers/media/video/pvrusb2/pvrusb2-ctrl.h | 1 - drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c | 1 - drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h | 1 - drivers/media/video/pvrusb2/pvrusb2-debug.h | 1 - drivers/media/video/pvrusb2/pvrusb2-debugifc.c | 1 - drivers/media/video/pvrusb2/pvrusb2-debugifc.h | 1 - drivers/media/video/pvrusb2/pvrusb2-devattr.c | 1 - drivers/media/video/pvrusb2/pvrusb2-devattr.h | 1 - drivers/media/video/pvrusb2/pvrusb2-eeprom.c | 1 - drivers/media/video/pvrusb2/pvrusb2-eeprom.h | 1 - drivers/media/video/pvrusb2/pvrusb2-encoder.c | 1 - drivers/media/video/pvrusb2/pvrusb2-encoder.h | 1 - drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 1 - drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 1 - drivers/media/video/pvrusb2/pvrusb2-hdw.c | 1 - drivers/media/video/pvrusb2/pvrusb2-hdw.h | 1 - drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c | 1 - drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c | 1 - drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h | 1 - drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 1 - drivers/media/video/pvrusb2/pvrusb2-i2c-core.h | 1 - drivers/media/video/pvrusb2/pvrusb2-io.c | 1 - drivers/media/video/pvrusb2/pvrusb2-io.h | 1 - drivers/media/video/pvrusb2/pvrusb2-ioread.c | 1 - drivers/media/video/pvrusb2/pvrusb2-ioread.h | 1 - drivers/media/video/pvrusb2/pvrusb2-main.c | 1 - drivers/media/video/pvrusb2/pvrusb2-std.c | 1 - drivers/media/video/pvrusb2/pvrusb2-std.h | 1 - drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 1 - drivers/media/video/pvrusb2/pvrusb2-sysfs.h | 1 - drivers/media/video/pvrusb2/pvrusb2-tuner.c | 1 - drivers/media/video/pvrusb2/pvrusb2-tuner.h | 1 - drivers/media/video/pvrusb2/pvrusb2-util.h | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.h | 1 - drivers/media/video/pvrusb2/pvrusb2-video-v4l.c | 1 - drivers/media/video/pvrusb2/pvrusb2-video-v4l.h | 1 - drivers/media/video/pvrusb2/pvrusb2-wm8775.c | 1 - drivers/media/video/pvrusb2/pvrusb2-wm8775.h | 1 - drivers/media/video/pvrusb2/pvrusb2.h | 1 - 45 files changed, 45 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c index 8d859ccd48ec..cdedaa55f152 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h index 536339b68843..ac54eed3721b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-audio.h +++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c index 73dcb1c57ae6..7c19ff72e6b3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/drivers/media/video/pvrusb2/pvrusb2-context.c @@ -1,5 +1,4 @@ /* - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h index 745e270233c2..61801291c2af 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h @@ -1,5 +1,4 @@ /* - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c index 91a42f2473a7..0764fbfffb73 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h index c1680053cd64..0371ae6e6e4e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c index 29d50597c88a..895859ec495a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h index 54b2844e7a71..66abf77f51fd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h +++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-debug.h b/drivers/media/video/pvrusb2/pvrusb2-debug.h index 707d2d9635d7..be79249f8628 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ b/drivers/media/video/pvrusb2/pvrusb2-debug.h @@ -1,5 +1,4 @@ /* - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c index b53121c78ff9..ca892fb78a5b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h index 990b02d35d36..e24ff59f8605 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h +++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 241c60cf40eb..5d036e7e3f07 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2007 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index d016f8b6c70b..e23ce1d2edd7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c index 5ef005947b04..299afa4fa969 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h index 84242975dea7..cca3216f94cc 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-eeprom.h +++ b/drivers/media/video/pvrusb2/pvrusb2-eeprom.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c index c46d367f7472..a1252d673b41 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.h b/drivers/media/video/pvrusb2/pvrusb2-encoder.h index 54caf2e3c428..232fefbcd1ac 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-encoder.h +++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index abaada31e66e..b58369e7f30b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2007 Michael Krufky * diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h index a3fe251d6fd9..657f861593b3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 584716e0c171..0808d589f413 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h index 20295e0c1995..c04956d304a7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c index 49773764383b..ccdb429fc7af 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c index c650e02ccd00..55f04a0b2047 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h index c838df6167f9..7fa38683b3b1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 793c89a8d672..9d3c18b24744 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h index bd0807b905bb..6ef7a1c0e935 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.c b/drivers/media/video/pvrusb2/pvrusb2-io.c index 7aff8b720064..20b6ae0bb40d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.c +++ b/drivers/media/video/pvrusb2/pvrusb2-io.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-io.h b/drivers/media/video/pvrusb2/pvrusb2-io.h index 42fcf8281a87..afb7e87c0394 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-io.h +++ b/drivers/media/video/pvrusb2/pvrusb2-io.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c index c572212c9f15..05a1376405e7 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/drivers/media/video/pvrusb2/pvrusb2-ioread.h index 1d362f833588..100e0780e1aa 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.h +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c index 332aced8a5a1..ad0d98c2ebb4 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-main.c +++ b/drivers/media/video/pvrusb2/pvrusb2-main.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.c b/drivers/media/video/pvrusb2/pvrusb2-std.c index fdc5a2b49ca8..ca9f83a85ca5 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-std.c +++ b/drivers/media/video/pvrusb2/pvrusb2-std.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-std.h b/drivers/media/video/pvrusb2/pvrusb2-std.h index 07c399375341..a35c53d0b320 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-std.h +++ b/drivers/media/video/pvrusb2/pvrusb2-std.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 0ff7a836a8a2..34a234c722c1 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h index ff9373b47f8f..6d875bfe7991 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.h +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c index 05e65ce2e3a9..07775d1aad4e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c +++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-tuner.h index 556f12aa9160..ef4afaf37b0a 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-tuner.h +++ b/drivers/media/video/pvrusb2/pvrusb2-tuner.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-util.h b/drivers/media/video/pvrusb2/pvrusb2-util.h index e53aee416f56..92b75544ee2e 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-util.h +++ b/drivers/media/video/pvrusb2/pvrusb2-util.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index e9b5d4e91327..0d72dc470fef 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h index 9a995e2d2256..34c011a7b107 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.h +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c index 2433a3160041..4059648c7056 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h index 2b917fda02e4..4ff5b892b303 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h +++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c index 66b4d36ef765..f6fcf0ac6118 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h index 8aaeff4e1e20..807090961255 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h +++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume diff --git a/drivers/media/video/pvrusb2/pvrusb2.h b/drivers/media/video/pvrusb2/pvrusb2.h index 1a9a4baf12b8..240de9b35661 100644 --- a/drivers/media/video/pvrusb2/pvrusb2.h +++ b/drivers/media/video/pvrusb2/pvrusb2.h @@ -1,6 +1,5 @@ /* * - * $Id$ * * Copyright (C) 2005 Mike Isely * Copyright (C) 2004 Aurelien Alleaume -- cgit v1.2.3 From 83ce57aa45a59e25146a32ee9f68edb7eecacd2b Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 26 May 2008 05:51:57 -0300 Subject: V4L/DVB (7937): pvrusb2: Change several embedded timer constants to defined values This is primarily a cosmetic change to make it easier to change some of the time constants used in the driver. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 0808d589f413..d4d57951cca2 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -39,6 +39,21 @@ #define TV_MIN_FREQ 55250000L #define TV_MAX_FREQ 850000000L +/* This defines a minimum interval that the decoder must remain quiet + before we are allowed to start it running. */ +#define TIME_MSEC_DECODER_WAIT 50 + +/* This defines a minimum interval that the encoder must remain quiet + before we are allowed to configure it. */ +#define TIME_MSEC_ENCODER_WAIT 50 + +/* This defines the minimum interval that the encoder must successfully run + before we consider that the encoder has run at least once since its + firmware has been loaded. This measurement is in important for cases + where we can't do something until we know that the encoder has been run + at least once. */ +#define TIME_MSEC_ENCODER_OK 250 + static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = NULL}; static DEFINE_MUTEX(pvr2_unit_mtx); @@ -3608,7 +3623,9 @@ static int state_eval_encoder_config(struct pvr2_hdw *hdw) the encoder. */ if (!hdw->state_encoder_waitok) { hdw->encoder_wait_timer.expires = - jiffies + (HZ*50/1000); + jiffies + + (HZ * TIME_MSEC_ENCODER_WAIT + / 1000); add_timer(&hdw->encoder_wait_timer); } } @@ -3732,7 +3749,7 @@ static int state_eval_encoder_run(struct pvr2_hdw *hdw) hdw->state_encoder_run = !0; if (!hdw->state_encoder_runok) { hdw->encoder_run_timer.expires = - jiffies + (HZ*250/1000); + jiffies + (HZ * TIME_MSEC_ENCODER_OK / 1000); add_timer(&hdw->encoder_run_timer); } } @@ -3807,7 +3824,9 @@ static int state_eval_decoder_run(struct pvr2_hdw *hdw) but before we did the pending check. */ if (!hdw->state_decoder_quiescent) { hdw->quiescent_timer.expires = - jiffies + (HZ*50/1000); + jiffies + + (HZ * TIME_MSEC_DECODER_WAIT + / 1000); add_timer(&hdw->quiescent_timer); } } -- cgit v1.2.3 From fa98e594220b86eb3632de478352e93ebf1201fa Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 26 May 2008 05:54:24 -0300 Subject: V4L/DVB (7938): pvrusb2: Increase enforced encoder wait delay to improve reliability The driver enforces a "quiet period" on the encoder in certain situations before attempting to operate it. This seems to help avoid video encoding errors / corruption. The quiet period was 50msec, but through experimentation it has been observed to improve further if the interval is increased to 100msec. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index d4d57951cca2..f30e13f6ee74 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -44,8 +44,10 @@ #define TIME_MSEC_DECODER_WAIT 50 /* This defines a minimum interval that the encoder must remain quiet - before we are allowed to configure it. */ -#define TIME_MSEC_ENCODER_WAIT 50 + before we are allowed to configure it. I had this originally set to + 50msec, but Martin Dauskardt reports that + things work better when it's set to 100msec. */ +#define TIME_MSEC_ENCODER_WAIT 100 /* This defines the minimum interval that the encoder must successfully run before we consider that the encoder has run at least once since its -- cgit v1.2.3 From f90fe7a3f7fcba0abd89ce0978628ef1d86ecbf9 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 26 May 2008 06:00:47 -0300 Subject: V4L/DVB (7939): pvrusb2: Remove sysfs interface hackery Back in the early days of the pvrusb2 driver, the kernel class mechanism in use for the sysfs interface had no means to pass per-attribute information to the show / store functions. This forced me to implement a horrible ugly thunking mechanism (i.e. infer the missing data through the use of dedicated cookie cutter bounce functions). However now we're using a better mechanism which also passes enough additional information to the show / store functions that we no longer need the hack. So eliminate all the crap. Yay! Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 460 +++++++--------------------- 1 file changed, 114 insertions(+), 346 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 34a234c722c1..46a8c39ba030 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c @@ -70,6 +70,7 @@ struct pvr2_sysfs_ctl_item { struct device_attribute attr_val; struct device_attribute attr_custom; struct pvr2_ctrl *cptr; + int ctl_id; struct pvr2_sysfs *chptr; struct pvr2_sysfs_ctl_item *item_next; struct attribute *attr_gen[7]; @@ -82,38 +83,29 @@ struct pvr2_sysfs_class { struct class class; }; -static ssize_t show_name(int id,struct device *class_dev,char *buf) +static ssize_t show_name(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; const char *name; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - name = pvr2_ctrl_get_desc(cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name); - + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name); + name = pvr2_ctrl_get_desc(cip->cptr); + pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s", + cip->chptr, cip->ctl_id, name); if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); + return scnprintf(buf, PAGE_SIZE, "%s\n", name); } -static ssize_t show_type(int id,struct device *class_dev,char *buf) +static ssize_t show_type(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; const char *name; enum pvr2_ctl_type tp; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - tp = pvr2_ctrl_get_type(cptr); + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type); + tp = pvr2_ctrl_get_type(cip->cptr); switch (tp) { case pvr2_ctl_int: name = "integer"; break; case pvr2_ctl_enum: name = "enum"; break; @@ -121,403 +113,178 @@ static ssize_t show_type(int id,struct device *class_dev,char *buf) case pvr2_ctl_bool: name = "boolean"; break; default: name = "?"; break; } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); - + pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s", + cip->chptr, cip->ctl_id, name); if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); + return scnprintf(buf, PAGE_SIZE, "%s\n", name); } -static ssize_t show_min(int id,struct device *class_dev,char *buf) +static ssize_t show_min(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; long val; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_min(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min); + val = pvr2_ctrl_get_min(cip->cptr); + pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld", + cip->chptr, cip->ctl_id, val); + return scnprintf(buf, PAGE_SIZE, "%ld\n", val); } -static ssize_t show_max(int id,struct device *class_dev,char *buf) +static ssize_t show_max(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; long val; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_max(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max); + val = pvr2_ctrl_get_max(cip->cptr); + pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld", + cip->chptr, cip->ctl_id, val); + return scnprintf(buf, PAGE_SIZE, "%ld\n", val); } -static ssize_t show_val_norm(int id,struct device *class_dev,char *buf) +static ssize_t show_val_norm(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; + struct pvr2_sysfs_ctl_item *cip; + int val; + int ret; unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); + ret = pvr2_ctrl_get_value(cip->cptr, &val); if (ret < 0) return ret; - - ret = pvr2_ctrl_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - + ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, + buf, PAGE_SIZE - 1, &cnt); pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); + cip->chptr, cip->ctl_id, cnt, buf, val); buf[cnt] = '\n'; return cnt+1; } -static ssize_t show_val_custom(int id,struct device *class_dev,char *buf) +static ssize_t show_val_custom(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; + struct pvr2_sysfs_ctl_item *cip; + int val; + int ret; unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); + ret = pvr2_ctrl_get_value(cip->cptr, &val); if (ret < 0) return ret; - - ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - + ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val, + buf, PAGE_SIZE - 1, &cnt); pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); + cip->chptr, cip->ctl_id, cnt, buf, val); buf[cnt] = '\n'; return cnt+1; } -static ssize_t show_enum(int id,struct device *class_dev,char *buf) +static ssize_t show_enum(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; long val; - unsigned int bcnt,ccnt,ecnt; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - ecnt = pvr2_ctrl_get_cnt(cptr); + unsigned int bcnt, ccnt, ecnt; + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum); + ecnt = pvr2_ctrl_get_cnt(cip->cptr); bcnt = 0; for (val = 0; val < ecnt; val++) { - pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); + pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt, + PAGE_SIZE - bcnt, &ccnt); if (!ccnt) continue; bcnt += ccnt; if (bcnt >= PAGE_SIZE) break; buf[bcnt] = '\n'; bcnt++; } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id); + pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)", + cip->chptr, cip->ctl_id); return bcnt; } -static ssize_t show_bits(int id,struct device *class_dev,char *buf) +static ssize_t show_bits(struct device *class_dev, + struct device_attribute *attr, + char *buf) { - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int valid_bits,msk; - unsigned int bcnt,ccnt; - - sfp = (struct pvr2_sysfs *)class_dev->driver_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - valid_bits = pvr2_ctrl_get_mask(cptr); + struct pvr2_sysfs_ctl_item *cip; + int valid_bits, msk; + unsigned int bcnt, ccnt; + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits); + valid_bits = pvr2_ctrl_get_mask(cip->cptr); bcnt = 0; for (msk = 1; valid_bits; msk <<= 1) { if (!(msk & valid_bits)) continue; valid_bits &= ~msk; - pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); + pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt, + PAGE_SIZE - bcnt, &ccnt); bcnt += ccnt; if (bcnt >= PAGE_SIZE) break; buf[bcnt] = '\n'; bcnt++; } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id); + pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)", + cip->chptr, cip->ctl_id); return bcnt; } -static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, +static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl, const char *buf,unsigned int count) { - struct pvr2_ctrl *cptr; int ret; int mask,val; - - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); if (customfl) { - ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val); + ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count, + &mask, &val); } else { - ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val); + ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count, + &mask, &val); } if (ret < 0) return ret; - ret = pvr2_ctrl_set_mask_value(cptr,mask,val); - pvr2_hdw_commit_ctl(sfp->channel.hdw); + ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val); + pvr2_hdw_commit_ctl(cip->chptr->channel.hdw); return ret; } -static ssize_t store_val_norm(int id,struct device *class_dev, - const char *buf,size_t count) +static ssize_t store_val_norm(struct device *class_dev, + struct device_attribute *attr, + const char *buf, size_t count) { - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; int ret; - sfp = (struct pvr2_sysfs *)class_dev->driver_data; + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", - sfp,id,(int)count,buf); - ret = store_val_any(id,0,sfp,buf,count); + cip->chptr, cip->ctl_id, (int)count, buf); + ret = store_val_any(cip, 0, buf, count); if (!ret) ret = count; return ret; } -static ssize_t store_val_custom(int id,struct device *class_dev, - const char *buf,size_t count) +static ssize_t store_val_custom(struct device *class_dev, + struct device_attribute *attr, + const char *buf, size_t count) { - struct pvr2_sysfs *sfp; + struct pvr2_sysfs_ctl_item *cip; int ret; - sfp = (struct pvr2_sysfs *)class_dev->driver_data; + cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", - sfp,id,(int)count,buf); - ret = store_val_any(id,1,sfp,buf,count); + cip->chptr, cip->ctl_id, (int)count, buf); + ret = store_val_any(cip, 1, buf, count); if (!ret) ret = count; return ret; } -/* - Mike Isely 30-April-2005 - - This next batch of horrible preprocessor hackery is needed because the - kernel's device_attribute mechanism fails to pass the actual - attribute through to the show / store functions, which means we have no - way to package up any attribute-specific parameters, like for example the - control id. So we work around this brain-damage by encoding the control - id into the show / store functions themselves and pick the function based - on the control id we're setting up. These macros try to ease the pain. - Yuck. -*/ - -#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ -struct device_attribute *attr, char *buf) \ -{ return sf_name(ctl_id,class_dev,buf); } - -#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ -struct device_attribute *attr, const char *buf, size_t count) \ -{ return sf_name(ctl_id,class_dev,buf,count); } - -#define CREATE_BATCH(ctl_id) \ -CREATE_SHOW_INSTANCE(show_name,ctl_id) \ -CREATE_SHOW_INSTANCE(show_type,ctl_id) \ -CREATE_SHOW_INSTANCE(show_min,ctl_id) \ -CREATE_SHOW_INSTANCE(show_max,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ -CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ -CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ - -CREATE_BATCH(0) -CREATE_BATCH(1) -CREATE_BATCH(2) -CREATE_BATCH(3) -CREATE_BATCH(4) -CREATE_BATCH(5) -CREATE_BATCH(6) -CREATE_BATCH(7) -CREATE_BATCH(8) -CREATE_BATCH(9) -CREATE_BATCH(10) -CREATE_BATCH(11) -CREATE_BATCH(12) -CREATE_BATCH(13) -CREATE_BATCH(14) -CREATE_BATCH(15) -CREATE_BATCH(16) -CREATE_BATCH(17) -CREATE_BATCH(18) -CREATE_BATCH(19) -CREATE_BATCH(20) -CREATE_BATCH(21) -CREATE_BATCH(22) -CREATE_BATCH(23) -CREATE_BATCH(24) -CREATE_BATCH(25) -CREATE_BATCH(26) -CREATE_BATCH(27) -CREATE_BATCH(28) -CREATE_BATCH(29) -CREATE_BATCH(30) -CREATE_BATCH(31) -CREATE_BATCH(32) -CREATE_BATCH(33) -CREATE_BATCH(34) -CREATE_BATCH(35) -CREATE_BATCH(36) -CREATE_BATCH(37) -CREATE_BATCH(38) -CREATE_BATCH(39) -CREATE_BATCH(40) -CREATE_BATCH(41) -CREATE_BATCH(42) -CREATE_BATCH(43) -CREATE_BATCH(44) -CREATE_BATCH(45) -CREATE_BATCH(46) -CREATE_BATCH(47) -CREATE_BATCH(48) -CREATE_BATCH(49) -CREATE_BATCH(50) -CREATE_BATCH(51) -CREATE_BATCH(52) -CREATE_BATCH(53) -CREATE_BATCH(54) -CREATE_BATCH(55) -CREATE_BATCH(56) -CREATE_BATCH(57) -CREATE_BATCH(58) -CREATE_BATCH(59) - -struct pvr2_sysfs_func_set { - ssize_t (*show_name)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_type)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_min)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_max)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_enum)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_bits)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*show_val_norm)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*store_val_norm)(struct device *, - struct device_attribute *attr, - const char *,size_t); - ssize_t (*show_val_custom)(struct device *, - struct device_attribute *attr, char *); - ssize_t (*store_val_custom)(struct device *, - struct device_attribute *attr, - const char *,size_t); -}; - -#define INIT_BATCH(ctl_id) \ -[ctl_id] = { \ - .show_name = show_name_##ctl_id, \ - .show_type = show_type_##ctl_id, \ - .show_min = show_min_##ctl_id, \ - .show_max = show_max_##ctl_id, \ - .show_enum = show_enum_##ctl_id, \ - .show_bits = show_bits_##ctl_id, \ - .show_val_norm = show_val_norm_##ctl_id, \ - .store_val_norm = store_val_norm_##ctl_id, \ - .show_val_custom = show_val_custom_##ctl_id, \ - .store_val_custom = store_val_custom_##ctl_id, \ -} \ - -static struct pvr2_sysfs_func_set funcs[] = { - INIT_BATCH(0), - INIT_BATCH(1), - INIT_BATCH(2), - INIT_BATCH(3), - INIT_BATCH(4), - INIT_BATCH(5), - INIT_BATCH(6), - INIT_BATCH(7), - INIT_BATCH(8), - INIT_BATCH(9), - INIT_BATCH(10), - INIT_BATCH(11), - INIT_BATCH(12), - INIT_BATCH(13), - INIT_BATCH(14), - INIT_BATCH(15), - INIT_BATCH(16), - INIT_BATCH(17), - INIT_BATCH(18), - INIT_BATCH(19), - INIT_BATCH(20), - INIT_BATCH(21), - INIT_BATCH(22), - INIT_BATCH(23), - INIT_BATCH(24), - INIT_BATCH(25), - INIT_BATCH(26), - INIT_BATCH(27), - INIT_BATCH(28), - INIT_BATCH(29), - INIT_BATCH(30), - INIT_BATCH(31), - INIT_BATCH(32), - INIT_BATCH(33), - INIT_BATCH(34), - INIT_BATCH(35), - INIT_BATCH(36), - INIT_BATCH(37), - INIT_BATCH(38), - INIT_BATCH(39), - INIT_BATCH(40), - INIT_BATCH(41), - INIT_BATCH(42), - INIT_BATCH(43), - INIT_BATCH(44), - INIT_BATCH(45), - INIT_BATCH(46), - INIT_BATCH(47), - INIT_BATCH(48), - INIT_BATCH(49), - INIT_BATCH(50), - INIT_BATCH(51), - INIT_BATCH(52), - INIT_BATCH(53), - INIT_BATCH(54), - INIT_BATCH(55), - INIT_BATCH(56), - INIT_BATCH(57), - INIT_BATCH(58), - INIT_BATCH(59), -}; - - static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) { struct pvr2_sysfs_ctl_item *cip; - struct pvr2_sysfs_func_set *fp; struct pvr2_ctrl *cptr; unsigned int cnt,acnt; int ret; - if ((ctl_id < 0) || (ctl_id >= ARRAY_SIZE(funcs))) { - return; - } - - fp = funcs + ctl_id; cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); if (!cptr) return; @@ -526,6 +293,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); cip->cptr = cptr; + cip->ctl_id = ctl_id; cip->chptr = sfp; cip->item_next = NULL; @@ -538,19 +306,19 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cip->attr_name.attr.name = "name"; cip->attr_name.attr.mode = S_IRUGO; - cip->attr_name.show = fp->show_name; + cip->attr_name.show = show_name; cip->attr_type.attr.name = "type"; cip->attr_type.attr.mode = S_IRUGO; - cip->attr_type.show = fp->show_type; + cip->attr_type.show = show_type; cip->attr_min.attr.name = "min_val"; cip->attr_min.attr.mode = S_IRUGO; - cip->attr_min.show = fp->show_min; + cip->attr_min.show = show_min; cip->attr_max.attr.name = "max_val"; cip->attr_max.attr.mode = S_IRUGO; - cip->attr_max.show = fp->show_max; + cip->attr_max.show = show_max; cip->attr_val.attr.name = "cur_val"; cip->attr_val.attr.mode = S_IRUGO; @@ -560,11 +328,11 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cip->attr_enum.attr.name = "enum_val"; cip->attr_enum.attr.mode = S_IRUGO; - cip->attr_enum.show = fp->show_enum; + cip->attr_enum.show = show_enum; cip->attr_bits.attr.name = "bit_val"; cip->attr_bits.attr.mode = S_IRUGO; - cip->attr_bits.show = fp->show_bits; + cip->attr_bits.show = show_bits; if (pvr2_ctrl_is_writable(cptr)) { cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; @@ -575,12 +343,12 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cip->attr_gen[acnt++] = &cip->attr_name.attr; cip->attr_gen[acnt++] = &cip->attr_type.attr; cip->attr_gen[acnt++] = &cip->attr_val.attr; - cip->attr_val.show = fp->show_val_norm; - cip->attr_val.store = fp->store_val_norm; + cip->attr_val.show = show_val_norm; + cip->attr_val.store = store_val_norm; if (pvr2_ctrl_has_custom_symbols(cptr)) { cip->attr_gen[acnt++] = &cip->attr_custom.attr; - cip->attr_custom.show = fp->show_val_custom; - cip->attr_custom.store = fp->store_val_custom; + cip->attr_custom.show = show_val_custom; + cip->attr_custom.store = store_val_custom; } switch (pvr2_ctrl_get_type(cptr)) { case pvr2_ctl_enum: -- cgit v1.2.3 From 1d0ba5f3784612fe6e91a12e0dec37c797d4f07c Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Mon, 26 May 2008 18:40:46 -0300 Subject: V4L/DVB (7942): Hardware frequency seek ioctl interface Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/compat_ioctl32.c | 1 + drivers/media/video/videodev.c | 12 ++++++++++++ include/linux/videodev2.h | 10 ++++++++++ include/media/v4l2-dev.h | 2 ++ 4 files changed, 25 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index cefd1381e8de..54de0cd482e9 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c @@ -884,6 +884,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_G_INPUT32: case VIDIOC_S_INPUT32: case VIDIOC_TRY_FMT32: + case VIDIOC_S_HW_FREQ_SEEK: ret = do_video_ioctl(file, cmd, arg); break; diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 7649860a388d..52c56678ee69 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -278,6 +278,7 @@ static const char *v4l2_ioctls[] = { [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", + [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", #endif }; #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) @@ -1763,6 +1764,17 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret = vfd->vidioc_default(file, fh, cmd, arg); break; } + case VIDIOC_S_HW_FREQ_SEEK: + { + struct v4l2_hw_freq_seek *p = arg; + if (!vfd->vidioc_s_hw_freq_seek) + break; + dbgarg(cmd, + "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", + p->tuner, p->type, p->seek_upward, p->wrap_around); + ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); + break; + } } /* switch */ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4a535ea1e123..9385c823a978 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -246,6 +246,7 @@ struct v4l2_capability #define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */ #define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ #define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */ +#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ #define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ #define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ @@ -1156,6 +1157,14 @@ struct v4l2_frequency __u32 reserved[8]; }; +struct v4l2_hw_freq_seek { + __u32 tuner; + enum v4l2_tuner_type type; + __u32 seek_upward; + __u32 wrap_around; + __u32 reserved[8]; +}; + /* * A U D I O */ @@ -1441,6 +1450,7 @@ struct v4l2_chip_ident { #define VIDIOC_G_CHIP_IDENT _IOWR ('V', 81, struct v4l2_chip_ident) #endif +#define VIDIOC_S_HW_FREQ_SEEK _IOW ('V', 82, struct v4l2_hw_freq_seek) #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 859f7a6f6f67..53b651ac685a 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -306,6 +306,8 @@ struct video_device /* Log status ioctl */ int (*vidioc_log_status) (struct file *file, void *fh); + int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh, + struct v4l2_hw_freq_seek *a); /* Debugging ioctls */ #ifdef CONFIG_VIDEO_ADV_DEBUG -- cgit v1.2.3 From 7bb846afceafdaceb88d2ed2e861585d26e353b9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 May 2008 21:32:08 -0300 Subject: V4L/DVB (7946): videodev: small fixes for VIDIOC_G_FREQUENCY and VIDIOC_G_FMT __video_do_ioctl incorrectly zeroed the tuner field of v4l2_frequency and did not zero the full fmt union of v4l2_format. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 52c56678ee69..91fd6cbc60ca 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -883,16 +883,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_G_FMT: { struct v4l2_format *f = (struct v4l2_format *)arg; - enum v4l2_buf_type type=f->type; - memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); - f->type=type; + memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(type, - v4l2_type_names)); + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); - switch (type) { + switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_g_fmt_cap) ret=vfd->vidioc_g_fmt_cap(file, fh, f); @@ -1688,16 +1685,17 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_G_FREQUENCY: { - struct v4l2_frequency *p=arg; + struct v4l2_frequency *p = arg; + if (!vfd->vidioc_g_frequency) break; - memset(p,0,sizeof(*p)); + memset(p->reserved, 0, sizeof(p->reserved)); - ret=vfd->vidioc_g_frequency(file, fh, p); + ret = vfd->vidioc_g_frequency(file, fh, p); if (!ret) - dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", - p->tuner,p->type,p->frequency); + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", + p->tuner, p->type, p->frequency); break; } case VIDIOC_S_FREQUENCY: -- cgit v1.2.3 From b2de2313f170c3f7341d3a94365c5139a23067a7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 28 May 2008 08:27:00 -0300 Subject: V4L/DVB (7947): videodev: add vidioc_g_std callback. The default videodev behavior for VIDIOC_G_STD is not correct for all devices. Add a new callback that drivers can use instead. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 12 ++++++++---- include/media/v4l2-dev.h | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 91fd6cbc60ca..4d58b55095d7 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -1206,11 +1206,15 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { v4l2_std_id *id = arg; - *id = vfd->current_norm; - - dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id); + ret = 0; + /* Calls the specific handler */ + if (vfd->vidioc_g_std) + ret = vfd->vidioc_g_std(file, fh, id); + else + *id = vfd->current_norm; - ret=0; + if (!ret) + dbgarg(cmd, "value=%08Lx\n", (long long unsigned)*id); break; } case VIDIOC_S_STD: diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 53b651ac685a..8a40f481d899 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -212,8 +212,9 @@ struct video_device int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i); /* Standard handling - G_STD and ENUMSTD are handled by videodev.c + ENUMSTD is handled by videodev.c */ + int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm); int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm); int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); -- cgit v1.2.3 From 0e3bd2b9996dfa4105617e2369155823df6b389a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 27 May 2008 22:31:43 -0300 Subject: V4L/DVB (7948): videodev: add missing vidioc_try_fmt_sliced_vbi_output and VIDIOC_ENUMOUTPUT handling There was no vidioc_try_fmt_sliced_vbi_output, instead vidioc_try_fmt_vbi_output was reused. The VIDIOC_ENUMOUTPUT handling was missing altogether, even though the callback existed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 35 +++++++++++++++++++++++++++-------- include/media/v4l2-dev.h | 10 +++++++++- 2 files changed, 36 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 4d58b55095d7..83106bba100d 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -840,8 +840,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_enum_fmt_vbi_output) - ret=vfd->vidioc_enum_fmt_vbi_output(file, + if (vfd->vidioc_enum_fmt_sliced_vbi_output) + ret = vfd->vidioc_enum_fmt_sliced_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: @@ -905,8 +905,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_g_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_output) - ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); + if (vfd->vidioc_g_fmt_sliced_vbi_output) + ret = vfd->vidioc_g_fmt_sliced_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_g_fmt_vbi_capture) @@ -957,8 +957,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_s_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_output) - ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); + if (vfd->vidioc_s_fmt_sliced_vbi_output) + ret = vfd->vidioc_s_fmt_sliced_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_s_fmt_vbi_capture) @@ -1009,8 +1009,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_try_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - ret=vfd->vidioc_try_fmt_vbi_output(file, + if (vfd->vidioc_try_fmt_sliced_vbi_output) + ret = vfd->vidioc_try_fmt_sliced_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: @@ -1297,6 +1297,25 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } /* ------ output switching ---------- */ + case VIDIOC_ENUMOUTPUT: + { + struct v4l2_output *p = arg; + int i = p->index; + + if (!vfd->vidioc_enum_output) + break; + memset(p, 0, sizeof(*p)); + p->index = i; + + ret = vfd->vidioc_enum_output(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "audioset=%d, " + "modulator=%d, std=%08Lx\n", + p->index, p->name, p->type, p->audioset, + p->modulator, (unsigned long long)p->std); + break; + } case VIDIOC_G_OUTPUT: { unsigned int *i = arg; diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 8a40f481d899..f14181fae6ce 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -132,6 +132,8 @@ struct video_device struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_vbi_output) (struct file *file, void *fh, struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_sliced_vbi_output) (struct file *file, void *fh, + struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, struct v4l2_fmtdesc *f); @@ -144,6 +146,8 @@ struct video_device struct v4l2_format *f); int (*vidioc_g_fmt_vbi_output) (struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_g_fmt_sliced_vbi_output) (struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_vbi_capture)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_g_fmt_video_output)(struct file *file, void *fh, @@ -163,6 +167,8 @@ struct video_device struct v4l2_format *f); int (*vidioc_s_fmt_vbi_output) (struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_s_fmt_sliced_vbi_output) (struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_vbi_capture)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_s_fmt_video_output)(struct file *file, void *fh, @@ -181,6 +187,8 @@ struct video_device struct v4l2_format *f); int (*vidioc_try_fmt_vbi_output) (struct file *file, void *fh, struct v4l2_format *f); + int (*vidioc_try_fmt_sliced_vbi_output) (struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_vbi_capture)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_try_fmt_video_output)(struct file *file, void *fh, @@ -225,7 +233,7 @@ struct video_device int (*vidioc_s_input) (struct file *file, void *fh, unsigned int i); /* Output handling */ - int (*vidioc_enumoutput) (struct file *file, void *fh, + int (*vidioc_enum_output) (struct file *file, void *fh, struct v4l2_output *a); int (*vidioc_g_output) (struct file *file, void *fh, unsigned int *i); int (*vidioc_s_output) (struct file *file, void *fh, unsigned int i); -- cgit v1.2.3 From 78b526a43561d7e5e702ba27948e422dfbc4bea1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 28 May 2008 12:16:41 -0300 Subject: V4L/DVB (7949): videodev: renamed the vidioc_*_fmt_* callbacks The naming for the callbacks that handle the VIDIOC_ENUM_FMT and VIDIOC_S/G/TRY_FMT ioctls was very confusing. Renamed it to match the v4l2_buf_type name. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 44 ++--- drivers/media/video/bt8xx/bttv-vbi.c | 6 +- drivers/media/video/bt8xx/bttvp.h | 6 +- drivers/media/video/cafe_ccic.c | 18 +- drivers/media/video/cx23885/cx23885-video.c | 24 +-- drivers/media/video/cx88/cx88-blackbird.c | 16 +- drivers/media/video/cx88/cx88-video.c | 24 +-- drivers/media/video/em28xx/em28xx-video.c | 30 ++-- drivers/media/video/meye.c | 18 +- drivers/media/video/saa7134/saa7134-empress.c | 12 +- drivers/media/video/saa7134/saa7134-video.c | 46 ++--- drivers/media/video/stk-webcam.c | 18 +- drivers/media/video/usbvision/usbvision-video.c | 18 +- drivers/media/video/videodev.c | 230 ++++++++++++------------ drivers/media/video/vivi.c | 18 +- drivers/media/video/zr364xx.c | 16 +- include/media/v4l2-dev.h | 68 ++++--- 17 files changed, 302 insertions(+), 310 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 0165aac533bf..c4aa802494ff 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -2448,7 +2448,7 @@ pix_format_set_size (struct v4l2_pix_format * f, } } -static int bttv_g_fmt_cap(struct file *file, void *priv, +static int bttv_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; @@ -2461,7 +2461,7 @@ static int bttv_g_fmt_cap(struct file *file, void *priv, return 0; } -static int bttv_g_fmt_overlay(struct file *file, void *priv, +static int bttv_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; @@ -2472,7 +2472,7 @@ static int bttv_g_fmt_overlay(struct file *file, void *priv, return 0; } -static int bttv_try_fmt_cap(struct file *file, void *priv, +static int bttv_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { const struct bttv_format *fmt; @@ -2532,7 +2532,7 @@ static int bttv_try_fmt_cap(struct file *file, void *priv, return 0; } -static int bttv_try_fmt_overlay(struct file *file, void *priv, +static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; @@ -2542,7 +2542,7 @@ static int bttv_try_fmt_overlay(struct file *file, void *priv, /* adjust_crop */ 0); } -static int bttv_s_fmt_cap(struct file *file, void *priv, +static int bttv_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { int retval; @@ -2556,7 +2556,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, if (0 != retval) return retval; - retval = bttv_try_fmt_cap(file, priv, f); + retval = bttv_try_fmt_vid_cap(file, priv, f); if (0 != retval) return retval; @@ -2591,7 +2591,7 @@ static int bttv_s_fmt_cap(struct file *file, void *priv, return 0; } -static int bttv_s_fmt_overlay(struct file *file, void *priv, +static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; @@ -2661,7 +2661,7 @@ static int bttv_querycap(struct file *file, void *priv, return 0; } -static int bttv_enum_fmt_vbi(struct file *file, void *priv, +static int bttv_enum_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (0 != f->index) @@ -2692,7 +2692,7 @@ static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) return i; } -static int bttv_enum_fmt_cap(struct file *file, void *priv, +static int bttv_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { int rc = bttv_enum_fmt_cap_ovr(f); @@ -2703,7 +2703,7 @@ static int bttv_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int bttv_enum_fmt_overlay(struct file *file, void *priv, +static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { int rc; @@ -3362,18 +3362,18 @@ static struct video_device bttv_video_template = .fops = &bttv_fops, .minor = -1, .vidioc_querycap = bttv_querycap, - .vidioc_enum_fmt_cap = bttv_enum_fmt_cap, - .vidioc_g_fmt_cap = bttv_g_fmt_cap, - .vidioc_try_fmt_cap = bttv_try_fmt_cap, - .vidioc_s_fmt_cap = bttv_s_fmt_cap, - .vidioc_enum_fmt_overlay = bttv_enum_fmt_overlay, - .vidioc_g_fmt_overlay = bttv_g_fmt_overlay, - .vidioc_try_fmt_overlay = bttv_try_fmt_overlay, - .vidioc_s_fmt_overlay = bttv_s_fmt_overlay, - .vidioc_enum_fmt_vbi = bttv_enum_fmt_vbi, - .vidioc_g_fmt_vbi = bttv_g_fmt_vbi, - .vidioc_try_fmt_vbi = bttv_try_fmt_vbi, - .vidioc_s_fmt_vbi = bttv_s_fmt_vbi, + .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay, + .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay, + .vidioc_enum_fmt_vbi_cap = bttv_enum_fmt_vbi_cap, + .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, + .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, + .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, .vidioc_g_audio = bttv_g_audio, .vidioc_s_audio = bttv_s_audio, .vidioc_cropcap = bttv_cropcap, diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index bfdbc469e30f..68f28e5fa040 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c @@ -303,7 +303,7 @@ static int try_fmt(struct v4l2_vbi_format *f, const struct bttv_tvnorm *tvnorm, return 0; } -int bttv_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) +int bttv_try_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; @@ -321,7 +321,7 @@ int bttv_try_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) } -int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) +int bttv_s_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; @@ -369,7 +369,7 @@ int bttv_s_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) } -int bttv_g_fmt_vbi(struct file *file, void *f, struct v4l2_format *frt) +int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt) { struct bttv_fh *fh = f; const struct bttv_tvnorm *tvnorm; diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 27da7b423275..955e6bcd8ae0 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -254,9 +254,9 @@ int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, /* ---------------------------------------------------------- */ /* bttv-vbi.c */ -int bttv_try_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); -int bttv_g_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); -int bttv_s_fmt_vbi(struct file *file, void *fh, struct v4l2_format *f); +int bttv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); +int bttv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); +int bttv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f); extern struct videobuf_queue_ops bttv_vbi_qops; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 5195b1f3378a..d99453faaab7 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -1593,7 +1593,7 @@ static struct v4l2_pix_format cafe_def_pix_format = { .sizeimage = VGA_WIDTH*VGA_HEIGHT*2, }; -static int cafe_vidioc_enum_fmt_cap(struct file *filp, +static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_fmtdesc *fmt) { struct cafe_camera *cam = priv; @@ -1608,7 +1608,7 @@ static int cafe_vidioc_enum_fmt_cap(struct file *filp, } -static int cafe_vidioc_try_fmt_cap (struct file *filp, void *priv, +static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { struct cafe_camera *cam = priv; @@ -1620,7 +1620,7 @@ static int cafe_vidioc_try_fmt_cap (struct file *filp, void *priv, return ret; } -static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv, +static int cafe_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { struct cafe_camera *cam = priv; @@ -1635,7 +1635,7 @@ static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv, /* * See if the formatting works in principle. */ - ret = cafe_vidioc_try_fmt_cap(filp, priv, fmt); + ret = cafe_vidioc_try_fmt_vid_cap(filp, priv, fmt); if (ret) return ret; /* @@ -1670,7 +1670,7 @@ static int cafe_vidioc_s_fmt_cap(struct file *filp, void *priv, * The V4l2 spec wants us to be smarter, and actually get this from * the camera (and not mess with it at open time). Someday. */ -static int cafe_vidioc_g_fmt_cap(struct file *filp, void *priv, +static int cafe_vidioc_g_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *f) { struct cafe_camera *cam = priv; @@ -1780,10 +1780,10 @@ static struct video_device cafe_v4l_template = { .release = cafe_v4l_dev_release, .vidioc_querycap = cafe_vidioc_querycap, - .vidioc_enum_fmt_cap = cafe_vidioc_enum_fmt_cap, - .vidioc_try_fmt_cap = cafe_vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = cafe_vidioc_s_fmt_cap, - .vidioc_g_fmt_cap = cafe_vidioc_g_fmt_cap, + .vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = cafe_vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = cafe_vidioc_s_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = cafe_vidioc_g_fmt_vid_cap, .vidioc_enum_input = cafe_vidioc_enum_input, .vidioc_g_input = cafe_vidioc_g_input, .vidioc_s_input = cafe_vidioc_s_input, diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 84652210a28c..043fc4e5c586 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -915,7 +915,7 @@ static void init_controls(struct cx23885_dev *dev) /* ------------------------------------------------------------------ */ /* VIDEO IOCTLS */ -static int vidioc_g_fmt_cap(struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx23885_fh *fh = priv; @@ -932,7 +932,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_try_fmt_cap(struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; @@ -983,7 +983,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_cap(struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx23885_fh *fh = priv; @@ -991,7 +991,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, int err; dprintk(2, "%s()\n", __func__); - err = vidioc_try_fmt_cap(file, priv, f); + err = vidioc_try_fmt_vid_cap(file, priv, f); if (0 != err) return err; @@ -1025,7 +1025,7 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_cap(struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(formats))) @@ -1440,13 +1440,13 @@ static struct video_device cx23885_video_template = { .fops = &video_fops, .minor = -1, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, - .vidioc_g_fmt_vbi = cx23885_vbi_fmt, - .vidioc_try_fmt_vbi = cx23885_vbi_fmt, - .vidioc_s_fmt_vbi = cx23885_vbi_fmt, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt, + .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt, + .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 6c0c94c5ef91..fb67e4188b2f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -737,7 +737,7 @@ static int vidioc_querycap (struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_cap (struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index != 0) @@ -749,7 +749,7 @@ static int vidioc_enum_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_cap (struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_fh *fh = priv; @@ -768,7 +768,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_try_fmt_cap (struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_fh *fh = priv; @@ -784,7 +784,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_cap (struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *f) { struct cx8802_fh *fh = priv; @@ -1181,10 +1181,10 @@ static struct video_device cx8802_mpeg_template = .minor = -1, .vidioc_querymenu = vidioc_querymenu, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index eea23f95edb7..0fed5cd2ccea 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1045,7 +1045,7 @@ static void init_controls(struct cx88_core *core) /* ------------------------------------------------------------------ */ /* VIDEO IOCTLS */ -static int vidioc_g_fmt_cap (struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_fh *fh = priv; @@ -1061,7 +1061,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_try_fmt_cap (struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx88_core *core = ((struct cx8800_fh *)priv)->dev->core; @@ -1112,11 +1112,11 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_cap (struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct cx8800_fh *fh = priv; - int err = vidioc_try_fmt_cap (file,priv,f); + int err = vidioc_try_fmt_vid_cap (file,priv,f); if (0 != err) return err; @@ -1147,7 +1147,7 @@ static int vidioc_querycap (struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_cap (struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (unlikely(f->index >= ARRAY_SIZE(formats))) @@ -1690,13 +1690,13 @@ static struct video_device cx8800_video_template = .fops = &video_fops, .minor = -1, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, - .vidioc_g_fmt_vbi = cx8800_vbi_fmt, - .vidioc_try_fmt_vbi = cx8800_vbi_fmt, - .vidioc_s_fmt_vbi = cx8800_vbi_fmt, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = cx8800_vbi_fmt, + .vidioc_try_fmt_vbi_cap = cx8800_vbi_fmt, + .vidioc_s_fmt_vbi_cap = cx8800_vbi_fmt, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 285bc62bbe46..1c3e8b6291ea 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -683,7 +683,7 @@ static void get_scale(struct em28xx *dev, IOCTL vidioc handling ------------------------------------------------------------------*/ -static int vidioc_g_fmt_cap(struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx_fh *fh = priv; @@ -706,7 +706,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_try_fmt_cap(struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx_fh *fh = priv; @@ -766,7 +766,7 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_cap(struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx_fh *fh = priv; @@ -777,7 +777,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, if (rc < 0) return rc; - vidioc_try_fmt_cap(file, priv, f); + vidioc_try_fmt_vid_cap(file, priv, f); mutex_lock(&dev->lock); @@ -826,7 +826,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) /* Adjusts width/height, if needed */ f.fmt.pix.width = dev->width; f.fmt.pix.height = dev->height; - vidioc_try_fmt_cap(file, priv, &f); + vidioc_try_fmt_vid_cap(file, priv, &f); mutex_lock(&dev->lock); @@ -1277,7 +1277,7 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_cap(struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fmtd) { if (fmtd->index != 0) @@ -1292,7 +1292,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, } /* Sliced VBI ioctls */ -static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv, +static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx_fh *fh = priv; @@ -1316,7 +1316,7 @@ static int vidioc_g_fmt_vbi_capture(struct file *file, void *priv, return rc; } -static int vidioc_try_set_vbi_capture(struct file *file, void *priv, +static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { struct em28xx_fh *fh = priv; @@ -1776,17 +1776,17 @@ static const struct video_device em28xx_video_template = { .minor = -1, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_g_audio = vidioc_g_audio, .vidioc_s_audio = vidioc_s_audio, .vidioc_cropcap = vidioc_cropcap, - .vidioc_g_fmt_vbi_capture = vidioc_g_fmt_vbi_capture, - .vidioc_try_fmt_vbi_capture = vidioc_try_set_vbi_capture, - .vidioc_s_fmt_vbi_capture = vidioc_try_set_vbi_capture, + .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, + .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, + .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index e7ccbc895d7a..2fb5854cf6f0 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1253,7 +1253,7 @@ static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) return 0; } -static int vidioc_enum_fmt_cap(struct file *file, void *fh, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { if (f->index > 1) @@ -1283,7 +1283,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *fh, return 0; } -static int vidioc_try_fmt_cap(struct file *file, void *fh, +static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -1316,7 +1316,8 @@ static int vidioc_try_fmt_cap(struct file *file, void *fh, return 0; } -static int vidioc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) +static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) { if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1346,7 +1347,8 @@ static int vidioc_g_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) return 0; } -static int vidioc_s_fmt_cap(struct file *file, void *fh, struct v4l2_format *f) +static int vidioc_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) { if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1709,10 +1711,10 @@ static struct video_device meye_template = { .vidioc_queryctrl = vidioc_queryctrl, .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 3ae71a340822..e11700eb3e5a 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -208,7 +208,7 @@ static int empress_s_input(struct file *file, void *priv, unsigned int i) return 0; } -static int empress_enum_fmt_cap(struct file *file, void *priv, +static int empress_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index != 0) @@ -220,7 +220,7 @@ static int empress_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int empress_g_fmt_cap(struct file *file, void *priv, +static int empress_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; @@ -233,7 +233,7 @@ static int empress_g_fmt_cap(struct file *file, void *priv, return 0; } -static int empress_s_fmt_cap(struct file *file, void *priv, +static int empress_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_dev *dev = file->private_data; @@ -348,9 +348,9 @@ static struct video_device saa7134_empress_template = .minor = -1, .vidioc_querycap = empress_querycap, - .vidioc_enum_fmt_cap = empress_enum_fmt_cap, - .vidioc_s_fmt_cap = empress_s_fmt_cap, - .vidioc_g_fmt_cap = empress_g_fmt_cap, + .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap, .vidioc_reqbufs = empress_reqbufs, .vidioc_querybuf = empress_querybuf, .vidioc_qbuf = empress_qbuf, diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 48e1a01718ec..bba23219ce94 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1496,7 +1496,7 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma) /* ------------------------------------------------------------------ */ -static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv, +static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1516,7 +1516,7 @@ static int saa7134_try_get_set_fmt_vbi(struct file *file, void *priv, return 0; } -static int saa7134_g_fmt_cap(struct file *file, void *priv, +static int saa7134_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1532,7 +1532,7 @@ static int saa7134_g_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_g_fmt_overlay(struct file *file, void *priv, +static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1546,7 +1546,7 @@ static int saa7134_g_fmt_overlay(struct file *file, void *priv, return 0; } -static int saa7134_try_fmt_cap(struct file *file, void *priv, +static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1597,7 +1597,7 @@ static int saa7134_try_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_try_fmt_overlay(struct file *file, void *priv, +static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -1611,13 +1611,13 @@ static int saa7134_try_fmt_overlay(struct file *file, void *priv, return verify_preview(dev, &f->fmt.win); } -static int saa7134_s_fmt_cap(struct file *file, void *priv, +static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; int err; - err = saa7134_try_fmt_cap(file, priv, f); + err = saa7134_try_fmt_vid_cap(file, priv, f); if (0 != err) return err; @@ -1628,7 +1628,7 @@ static int saa7134_s_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_s_fmt_overlay(struct file *file, void *priv, +static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct saa7134_fh *fh = priv; @@ -2028,7 +2028,7 @@ static int saa7134_s_priority(struct file *file, void *f, return v4l2_prio_change(&dev->prio, &fh->prio, prio); } -static int saa7134_enum_fmt_cap(struct file *file, void *priv, +static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index >= FORMATS) @@ -2042,7 +2042,7 @@ static int saa7134_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int saa7134_enum_fmt_overlay(struct file *file, void *priv, +static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (saa7134_no_overlay > 0) { @@ -2061,7 +2061,7 @@ static int saa7134_enum_fmt_overlay(struct file *file, void *priv, return 0; } -static int saa7134_enum_fmt_vbi(struct file *file, void *priv, +static int saa7134_enum_fmt_vbi_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (0 != f->index) @@ -2348,18 +2348,18 @@ struct video_device saa7134_video_template = .fops = &video_fops, .minor = -1, .vidioc_querycap = saa7134_querycap, - .vidioc_enum_fmt_cap = saa7134_enum_fmt_cap, - .vidioc_g_fmt_cap = saa7134_g_fmt_cap, - .vidioc_try_fmt_cap = saa7134_try_fmt_cap, - .vidioc_s_fmt_cap = saa7134_s_fmt_cap, - .vidioc_enum_fmt_overlay = saa7134_enum_fmt_overlay, - .vidioc_g_fmt_overlay = saa7134_g_fmt_overlay, - .vidioc_try_fmt_overlay = saa7134_try_fmt_overlay, - .vidioc_s_fmt_overlay = saa7134_s_fmt_overlay, - .vidioc_enum_fmt_vbi = saa7134_enum_fmt_vbi, - .vidioc_g_fmt_vbi = saa7134_try_get_set_fmt_vbi, - .vidioc_try_fmt_vbi = saa7134_try_get_set_fmt_vbi, - .vidioc_s_fmt_vbi = saa7134_try_get_set_fmt_vbi, + .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = saa7134_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = saa7134_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_overlay = saa7134_enum_fmt_vid_overlay, + .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay, + .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay, + .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay, + .vidioc_enum_fmt_vbi_cap = saa7134_enum_fmt_vbi_cap, + .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, + .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, + .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_g_audio = saa7134_g_audio, .vidioc_s_audio = saa7134_s_audio, .vidioc_cropcap = saa7134_cropcap, diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index b12c60cf5a09..f308c38d744f 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -981,7 +981,7 @@ static int stk_vidioc_s_ctrl(struct file *filp, } -static int stk_vidioc_enum_fmt_cap(struct file *filp, +static int stk_vidioc_enum_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_fmtdesc *fmtd) { fmtd->flags = 0; @@ -1025,7 +1025,7 @@ static struct stk_size { { .w = 176, .h = 144, .m = MODE_QCIF, }, }; -static int stk_vidioc_g_fmt_cap(struct file *filp, +static int stk_vidioc_g_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *f) { struct v4l2_pix_format *pix_format = &f->fmt.pix; @@ -1054,7 +1054,7 @@ static int stk_vidioc_g_fmt_cap(struct file *filp, return 0; } -static int stk_vidioc_try_fmt_cap(struct file *filp, +static int stk_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { int i; @@ -1131,7 +1131,7 @@ static int stk_setup_format(struct stk_camera *dev) return stk_sensor_configure(dev); } -static int stk_vidioc_s_fmt_cap(struct file *filp, +static int stk_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmtd) { int ret; @@ -1145,7 +1145,7 @@ static int stk_vidioc_s_fmt_cap(struct file *filp, return -EBUSY; if (dev->owner && dev->owner != filp) return -EBUSY; - ret = stk_vidioc_try_fmt_cap(filp, priv, fmtd); + ret = stk_vidioc_try_fmt_vid_cap(filp, priv, fmtd); if (ret) return ret; dev->owner = filp; @@ -1342,10 +1342,10 @@ static struct video_device stk_v4l_data = { .release = stk_v4l_dev_release, .vidioc_querycap = stk_vidioc_querycap, - .vidioc_enum_fmt_cap = stk_vidioc_enum_fmt_cap, - .vidioc_try_fmt_cap = stk_vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = stk_vidioc_s_fmt_cap, - .vidioc_g_fmt_cap = stk_vidioc_g_fmt_cap, + .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = stk_vidioc_s_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = stk_vidioc_g_fmt_vid_cap, .vidioc_enum_input = stk_vidioc_enum_input, .vidioc_s_input = stk_vidioc_s_input, .vidioc_g_input = stk_vidioc_g_input, diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index d97261ab430f..a9e5e08caec5 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -998,7 +998,7 @@ static int vidioc_streamoff(struct file *file, return 0; } -static int vidioc_enum_fmt_cap (struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv, struct v4l2_fmtdesc *vfd) { if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) { @@ -1012,7 +1012,7 @@ static int vidioc_enum_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_cap (struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *vf) { struct video_device *dev = video_devdata(file); @@ -1030,7 +1030,7 @@ static int vidioc_g_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_try_fmt_cap (struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap (struct file *file, void *priv, struct v4l2_format *vf) { struct video_device *dev = video_devdata(file); @@ -1060,7 +1060,7 @@ static int vidioc_try_fmt_cap (struct file *file, void *priv, return 0; } -static int vidioc_s_fmt_cap(struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf) { struct video_device *dev = video_devdata(file); @@ -1068,7 +1068,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, (struct usb_usbvision *) video_get_drvdata(dev); int ret; - if( 0 != (ret=vidioc_try_fmt_cap (file, priv, vf)) ) { + if( 0 != (ret=vidioc_try_fmt_vid_cap (file, priv, vf)) ) { return ret; } @@ -1407,10 +1407,10 @@ static struct video_device usbvision_video_template = { .release = video_device_release, .minor = -1, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 83106bba100d..6cf6ad7193d9 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -683,35 +683,35 @@ static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) { switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_cap) + if (vfd->vidioc_try_fmt_vid_cap) return (0); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_overlay) + if (vfd->vidioc_try_fmt_vid_overlay) return (0); break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi) + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_try_fmt_vid_out) return (0); break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_try_fmt_vid_out_overlay) return (0); break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_capture) + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_vbi_cap) return (0); break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_video_output) + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_vbi_out) return (0); break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_sliced_vbi_cap) return (0); break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_output_overlay) + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_sliced_vbi_out) return (0); break; case V4L2_BUF_TYPE_PRIVATE: @@ -828,46 +828,37 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_enum_fmt_cap) - ret=vfd->vidioc_enum_fmt_cap(file, fh, f); + if (vfd->vidioc_enum_fmt_vid_cap) + ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_enum_fmt_overlay) - ret=vfd->vidioc_enum_fmt_overlay(file, fh, f); + if (vfd->vidioc_enum_fmt_vid_overlay) + ret = vfd->vidioc_enum_fmt_vid_overlay(file, + fh, f); break; +#if 1 + /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT + * according to the spec. The bttv and saa7134 drivers support + * it though, so just warn that this is deprecated and will be + * removed in the near future. */ case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi) - ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_enum_fmt_sliced_vbi_output) - ret = vfd->vidioc_enum_fmt_sliced_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi_capture) - ret=vfd->vidioc_enum_fmt_vbi_capture(file, - fh, f); + if (vfd->vidioc_enum_fmt_vbi_cap) { + printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); + ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); + } break; +#endif case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_enum_fmt_video_output) - ret=vfd->vidioc_enum_fmt_video_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_enum_fmt_vbi_output) - ret=vfd->vidioc_enum_fmt_vbi_output(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_enum_fmt_output_overlay) - ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f); + if (vfd->vidioc_enum_fmt_vid_out) + ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_enum_fmt_type_private) - ret=vfd->vidioc_enum_fmt_type_private(file, + ret = vfd->vidioc_enum_fmt_type_private(file, fh, f); break; + default: + break; } if (!ret) dbgarg (cmd, "index=%d, type=%d, flags=%d, " @@ -891,43 +882,46 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_g_fmt_cap) - ret=vfd->vidioc_g_fmt_cap(file, fh, f); + if (vfd->vidioc_g_fmt_vid_cap) + ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd,&f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_g_fmt_overlay) - ret=vfd->vidioc_g_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi) - ret=vfd->vidioc_g_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_sliced_vbi_output) - ret = vfd->vidioc_g_fmt_sliced_vbi_output(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi_capture) - ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f); + if (vfd->vidioc_g_fmt_vid_overlay) + ret = vfd->vidioc_g_fmt_vid_overlay(file, + fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_g_fmt_video_output) - ret=vfd->vidioc_g_fmt_video_output(file, - fh, f); + if (vfd->vidioc_g_fmt_vid_out) + ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_g_fmt_output_overlay) - ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f); + if (vfd->vidioc_g_fmt_vid_out_overlay) + ret = vfd->vidioc_g_fmt_vid_out_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_g_fmt_vbi_cap) + ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_output) - ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); + if (vfd->vidioc_g_fmt_vbi_out) + ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_g_fmt_sliced_vbi_cap) + ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, + fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_g_fmt_sliced_vbi_out) + ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, + fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_g_fmt_type_private) - ret=vfd->vidioc_g_fmt_type_private(file, + ret = vfd->vidioc_g_fmt_type_private(file, fh, f); break; } @@ -945,42 +939,44 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: v4l_print_pix_fmt(vfd,&f->fmt.pix); - if (vfd->vidioc_s_fmt_cap) - ret=vfd->vidioc_s_fmt_cap(file, fh, f); + if (vfd->vidioc_s_fmt_vid_cap) + ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_s_fmt_overlay) - ret=vfd->vidioc_s_fmt_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi) - ret=vfd->vidioc_s_fmt_vbi(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_sliced_vbi_output) - ret = vfd->vidioc_s_fmt_sliced_vbi_output(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi_capture) - ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f); + if (vfd->vidioc_s_fmt_vid_overlay) + ret = vfd->vidioc_s_fmt_vid_overlay(file, + fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_s_fmt_video_output) - ret=vfd->vidioc_s_fmt_video_output(file, - fh, f); + if (vfd->vidioc_s_fmt_vid_out) + ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_s_fmt_output_overlay) - ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f); + if (vfd->vidioc_s_fmt_vid_out_overlay) + ret = vfd->vidioc_s_fmt_vid_out_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_s_fmt_vbi_cap) + ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_output) - ret=vfd->vidioc_s_fmt_vbi_output(file, - fh, f); + if (vfd->vidioc_s_fmt_vbi_out) + ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_s_fmt_sliced_vbi_cap) + ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, + fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_s_fmt_sliced_vbi_out) + ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, + fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_s_fmt_type_private) - ret=vfd->vidioc_s_fmt_type_private(file, + ret = vfd->vidioc_s_fmt_type_private(file, fh, f); break; } @@ -995,46 +991,46 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_cap) - ret=vfd->vidioc_try_fmt_cap(file, fh, f); + if (vfd->vidioc_try_fmt_vid_cap) + ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd,&f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_overlay) - ret=vfd->vidioc_try_fmt_overlay(file, fh, f); + if (vfd->vidioc_try_fmt_vid_overlay) + ret = vfd->vidioc_try_fmt_vid_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_try_fmt_vid_out) + ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_try_fmt_vid_out_overlay) + ret = vfd->vidioc_try_fmt_vid_out_overlay(file, + fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi) - ret=vfd->vidioc_try_fmt_vbi(file, fh, f); + if (vfd->vidioc_try_fmt_vbi_cap) + ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_output) - ret = vfd->vidioc_try_fmt_sliced_vbi_output(file, - fh, f); + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_vbi_out) + ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_capture) - ret=vfd->vidioc_try_fmt_vbi_capture(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_video_output) - ret=vfd->vidioc_try_fmt_video_output(file, + if (vfd->vidioc_try_fmt_sliced_vbi_cap) + ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, fh, f); break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_output_overlay) - ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_output) - ret=vfd->vidioc_try_fmt_vbi_output(file, + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_sliced_vbi_out) + ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_try_fmt_type_private) - ret=vfd->vidioc_try_fmt_type_private(file, + ret = vfd->vidioc_try_fmt_type_private(file, fh, f); break; } diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 5ff9a58b6135..a9747a10c546 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -630,7 +630,7 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } -static int vidioc_enum_fmt_cap(struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index > 0) @@ -641,7 +641,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_cap(struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct vivi_fh *fh = priv; @@ -658,7 +658,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, return (0); } -static int vidioc_try_fmt_cap(struct file *file, void *priv, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct vivi_fh *fh = priv; @@ -706,13 +706,13 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, } /*FIXME: This seems to be generic enough to be at videodev2 */ -static int vidioc_s_fmt_cap(struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct vivi_fh *fh = priv; struct videobuf_queue *q = &fh->vb_vidq; - int ret = vidioc_try_fmt_cap(file, fh, f); + int ret = vidioc_try_fmt_vid_cap(file, fh, f); if (ret < 0) return (ret); @@ -1066,10 +1066,10 @@ static struct video_device vivi_template = { .release = video_device_release, .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_reqbufs = vidioc_reqbufs, .vidioc_querybuf = vidioc_querybuf, .vidioc_qbuf = vidioc_qbuf, diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index a0e49dc66301..485df2e36132 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -521,7 +521,7 @@ static int zr364xx_vidioc_g_ctrl(struct file *file, void *priv, return 0; } -static int zr364xx_vidioc_enum_fmt_cap(struct file *file, +static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { if (f->index > 0) @@ -537,7 +537,7 @@ static int zr364xx_vidioc_enum_fmt_cap(struct file *file, return 0; } -static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv, +static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); @@ -564,7 +564,7 @@ static int zr364xx_vidioc_try_fmt_cap(struct file *file, void *priv, return 0; } -static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv, +static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); @@ -589,7 +589,7 @@ static int zr364xx_vidioc_g_fmt_cap(struct file *file, void *priv, return 0; } -static int zr364xx_vidioc_s_fmt_cap(struct file *file, void *priv, +static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct video_device *vdev = video_devdata(file); @@ -770,10 +770,10 @@ static struct video_device zr364xx_template = { .minor = -1, .vidioc_querycap = zr364xx_vidioc_querycap, - .vidioc_enum_fmt_cap = zr364xx_vidioc_enum_fmt_cap, - .vidioc_try_fmt_cap = zr364xx_vidioc_try_fmt_cap, - .vidioc_s_fmt_cap = zr364xx_vidioc_s_fmt_cap, - .vidioc_g_fmt_cap = zr364xx_vidioc_g_fmt_cap, + .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = zr364xx_vidioc_s_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = zr364xx_vidioc_g_fmt_vid_cap, .vidioc_enum_input = zr364xx_vidioc_enum_input, .vidioc_g_input = zr364xx_vidioc_g_input, .vidioc_s_input = zr364xx_vidioc_s_input, diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index f14181fae6ce..40b0810a595a 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -118,82 +118,76 @@ struct video_device enum v4l2_priority p); /* VIDIOC_ENUM_FMT handlers */ - int (*vidioc_enum_fmt_cap) (struct file *file, void *fh, + int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_overlay) (struct file *file, void *fh, + int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh, struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vbi) (struct file *file, void *fh, + int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vbi_capture) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_video_output)(struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_output_overlay) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vbi_output) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_sliced_vbi_output) (struct file *file, void *fh, +#if 1 + /* deprecated, will be removed in 2.6.28 */ + int (*vidioc_enum_fmt_vbi_cap) (struct file *file, void *fh, struct v4l2_fmtdesc *f); +#endif int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, struct v4l2_fmtdesc *f); /* VIDIOC_G_FMT handlers */ - int (*vidioc_g_fmt_cap) (struct file *file, void *fh, + int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_overlay) (struct file *file, void *fh, + int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_vbi) (struct file *file, void *fh, + int (*vidioc_g_fmt_vid_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_output) (struct file *file, void *fh, + int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_sliced_vbi_output) (struct file *file, void *fh, + int (*vidioc_g_fmt_vbi_cap) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_capture)(struct file *file, void *fh, + int (*vidioc_g_fmt_vbi_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_video_output)(struct file *file, void *fh, + int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_output_overlay) (struct file *file, void *fh, + int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, struct v4l2_format *f); /* VIDIOC_S_FMT handlers */ - int (*vidioc_s_fmt_cap) (struct file *file, void *fh, + int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh, struct v4l2_format *f); - - int (*vidioc_s_fmt_overlay) (struct file *file, void *fh, + int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_vbi) (struct file *file, void *fh, + int (*vidioc_s_fmt_vid_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_output) (struct file *file, void *fh, + int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_sliced_vbi_output) (struct file *file, void *fh, + int (*vidioc_s_fmt_vbi_cap) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_capture)(struct file *file, void *fh, + int (*vidioc_s_fmt_vbi_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_video_output)(struct file *file, void *fh, + int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_output_overlay) (struct file *file, void *fh, + int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, struct v4l2_format *f); /* VIDIOC_TRY_FMT handlers */ - int (*vidioc_try_fmt_cap) (struct file *file, void *fh, + int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_overlay) (struct file *file, void *fh, + int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_vbi) (struct file *file, void *fh, + int (*vidioc_try_fmt_vid_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_output) (struct file *file, void *fh, + int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_sliced_vbi_output) (struct file *file, void *fh, + int (*vidioc_try_fmt_vbi_cap) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_capture)(struct file *file, void *fh, + int (*vidioc_try_fmt_vbi_out) (struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_video_output)(struct file *file, void *fh, + int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_output_overlay)(struct file *file, void *fh, + int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, struct v4l2_format *f); -- cgit v1.2.3 From b6b2d268445ad4f5fac495bbbae6d2922f0becd9 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 00:53:27 -0300 Subject: V4L/DVB (7950): AU6610: coding style fixes - coding style fixes raised by checkpatch Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/au6610.c | 38 ++++++++++++++++++-------------------- drivers/media/dvb/dvb-usb/au6610.h | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c index 2ccb90fa60c8..b44a3c4c5450 100644 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ b/drivers/media/dvb/dvb-usb/au6610.c @@ -3,8 +3,8 @@ * Copyright (C) 2006 Antti Palosaari * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, version 2. * * see Documentation/dvb/README.dvb-usb for more information */ @@ -17,8 +17,8 @@ /* debug */ static int dvb_usb_au6610_debug; module_param_named(debug, dvb_usb_au6610_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." + DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, @@ -42,9 +42,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, } ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, - USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf, - sizeof(usb_buf), AU6610_USB_TIMEOUT); - + USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, + usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT); if (ret < 0) return ret; @@ -133,12 +132,12 @@ static struct zl10353_config au6610_zl10353_config = { static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) { - if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, - &adap->dev->i2c_adap)) != NULL) { - return 0; - } + adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, + &adap->dev->i2c_adap); + if (adap->fe == NULL) + return -EIO; - return -EIO; + return 0; } static struct qt1010_config au6610_qt1010_config = { @@ -186,7 +185,7 @@ static struct usb_device_id au6610_table [] = { { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, au6610_table); +MODULE_DEVICE_TABLE(usb, au6610_table); static struct dvb_usb_device_properties au6610_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, @@ -206,7 +205,7 @@ static struct dvb_usb_device_properties au6610_properties = { .u = { .isoc = { .framesperurb = 40, - .framesize = 942, /* maximum packet size */ + .framesize = 942, .interval = 1.25, /* 125 us */ } } @@ -236,12 +235,11 @@ static int __init au6610_module_init(void) { int ret; - if ((ret = usb_register(&au6610_driver))) { + ret = usb_register(&au6610_driver); + if (ret) err("usb_register failed. Error number %d", ret); - return ret; - } - return 0; + return ret; } static void __exit au6610_module_exit(void) @@ -250,8 +248,8 @@ static void __exit au6610_module_exit(void) usb_deregister(&au6610_driver); } -module_init (au6610_module_init); -module_exit (au6610_module_exit); +module_init(au6610_module_init); +module_exit(au6610_module_exit); MODULE_AUTHOR("Antti Palosaari "); MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610"); diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h index 4161b054c713..abca6291c725 100644 --- a/drivers/media/dvb/dvb-usb/au6610.h +++ b/drivers/media/dvb/dvb-usb/au6610.h @@ -4,7 +4,7 @@ #define DVB_USB_LOG_PREFIX "au6610" #include "dvb-usb.h" -#define deb_rc(args...) dprintk(dvb_usb_au6610_debug,0x01,args) +#define deb_rc(args...) dprintk(dvb_usb_au6610_debug, 0x01, args) #define AU6610_REQ_I2C_WRITE 0x14 #define AU6610_REQ_I2C_READ 0x13 -- cgit v1.2.3 From bbf23af2b10926c0d489d74814d9744cd495c3bc Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 01:01:04 -0300 Subject: V4L/DVB (7951): AU6610: remove useless identify_state - remove useless identify_state - device is always warm Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/au6610.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c index b44a3c4c5450..a0895fba2e5f 100644 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ b/drivers/media/dvb/dvb-usb/au6610.c @@ -115,15 +115,6 @@ static struct i2c_algorithm au6610_i2c_algo = { }; /* Callbacks for DVB USB */ -static int au6610_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - *cold = 0; - return 0; -} - static struct zl10353_config au6610_zl10353_config = { .demod_address = 0x0f, .no_tuner = 1, @@ -191,7 +182,6 @@ static struct dvb_usb_device_properties au6610_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = DEVICE_SPECIFIC, .size_of_priv = 0, - .identify_state = au6610_identify_state, .num_adapters = 1, .adapter = { { @@ -213,12 +203,13 @@ static struct dvb_usb_device_properties au6610_properties = { } }, .i2c_algo = &au6610_i2c_algo, + .num_device_descs = 1, .devices = { { - "Sigmatek DVB-110 DVB-T USB2.0", - { &au6610_table[0], NULL }, - { NULL }, + .name = "Sigmatek DVB-110 DVB-T USB2.0", + .cold_ids = {NULL}, + .warm_ids = {&au6610_table[0], NULL}, }, } }; -- cgit v1.2.3 From 53af158a901a32dd8639fbe03db5354ab711d8f0 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 03:57:39 -0300 Subject: V4L/DVB (7952): AU6610: various cosmetic changes - update license comments - change MODULE_DESCRIPTION from device specific to chipset specific - correct debug switch from deb_rc to deb_info - correct MPEG2 stream interval from 1.25 to 1 - change frontend_attach error code from -EIO to -ENODEV Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/au6610.c | 38 ++++++++++++++++++++++++-------------- drivers/media/dvb/dvb-usb/au6610.h | 22 +++++++++++++++++++++- 2 files changed, 45 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c index a0895fba2e5f..eb34cc3894e0 100644 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ b/drivers/media/dvb/dvb-usb/au6610.c @@ -1,24 +1,31 @@ -/* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver +/* + * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0. * * Copyright (C) 2006 Antti Palosaari * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, version 2. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * see Documentation/dvb/README.dvb-usb for more information + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "au6610.h" - #include "zl10353.h" #include "qt1010.h" /* debug */ static int dvb_usb_au6610_debug; module_param_named(debug, dvb_usb_au6610_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." - DVB_USB_DEBUG_STATUS); +MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, @@ -126,7 +133,7 @@ static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, &adap->dev->i2c_adap); if (adap->fe == NULL) - return -EIO; + return -ENODEV; return 0; } @@ -161,7 +168,7 @@ static int au6610_probe(struct usb_interface *intf, alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING); if (alt == NULL) { - deb_rc("no alt found!\n"); + deb_info("%s: no alt found!\n", __func__); return -ENODEV; } ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, @@ -171,7 +178,6 @@ static int au6610_probe(struct usb_interface *intf, return ret; } - static struct usb_device_id au6610_table [] = { { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) }, { } /* Terminating entry */ @@ -180,8 +186,11 @@ MODULE_DEVICE_TABLE(usb, au6610_table); static struct dvb_usb_device_properties au6610_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, - .size_of_priv = 0, + + .size_of_priv = 0, + .num_adapters = 1, .adapter = { { @@ -196,12 +205,13 @@ static struct dvb_usb_device_properties au6610_properties = { .isoc = { .framesperurb = 40, .framesize = 942, - .interval = 1.25, /* 125 us */ + .interval = 1, } } }, } }, + .i2c_algo = &au6610_i2c_algo, .num_device_descs = 1, @@ -243,6 +253,6 @@ module_init(au6610_module_init); module_exit(au6610_module_exit); MODULE_AUTHOR("Antti Palosaari "); -MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610"); +MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0"); MODULE_VERSION("0.1"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h index abca6291c725..7849abe2c614 100644 --- a/drivers/media/dvb/dvb-usb/au6610.h +++ b/drivers/media/dvb/dvb-usb/au6610.h @@ -1,10 +1,30 @@ +/* + * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0. + * + * Copyright (C) 2006 Antti Palosaari + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef _DVB_USB_AU6610_H_ #define _DVB_USB_AU6610_H_ #define DVB_USB_LOG_PREFIX "au6610" #include "dvb-usb.h" -#define deb_rc(args...) dprintk(dvb_usb_au6610_debug, 0x01, args) +#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args) #define AU6610_REQ_I2C_WRITE 0x14 #define AU6610_REQ_I2C_READ 0x13 -- cgit v1.2.3 From f808a9e3cefd577d96d43d308685468c0a03185e Mon Sep 17 00:00:00 2001 From: Dmitri Belimov Date: Wed, 21 May 2008 03:16:52 -0300 Subject: V4L/DVB (7976): I2S on for MPEG of saa7134_empress Rework saa7134_enable_i2s function. Add vendor specific data. Add definition for I2S audio output control register. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-reg.h | 1 + drivers/media/video/saa7134/saa7134-tvaudio.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h index 86f5eefdb0f6..258792c1784e 100644 --- a/drivers/media/video/saa7134/saa7134-reg.h +++ b/drivers/media/video/saa7134/saa7134-reg.h @@ -353,6 +353,7 @@ /* I2S output */ #define SAA7134_I2S_AUDIO_OUTPUT 0x1c0 +#define SAA7134_I2S_AUDIO_CONTROL 0x591 /* test modes */ #define SAA7134_SPECIAL_MODE 0x1d0 diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 232af598d947..460d4a35e5f1 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -873,13 +873,25 @@ void saa7134_enable_i2s(struct saa7134_dev *dev) if (!card_is_empress(dev)) return; - i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01; - /* enable I2S audio output for the mpeg encoder */ - saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); - saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); - saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); - saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + switch (dev->board) { + case SAA7134_BOARD_BEHOLD_M6: + /* configure GPIO for out audio */ + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000); + /* Set I2S format */ + saa_writeb(SAA7134_I2S_AUDIO_CONTROL, 0x00); + /* Start I2S */ + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11); + break; + default: + i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01; + + /* enable I2S audio output for the mpeg encoder */ + saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); + saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); + saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + } } int saa7134_tvaudio_rx2mode(u32 rx) -- cgit v1.2.3 From 26151c32d3d001f64e75871588acd0aff3f216d7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 3 Jun 2008 05:16:37 -0300 Subject: V4L/DVB (7984): tda18271: update filename in comments This file was renamed but we forgot to change it in the comments. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda18271-maps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c index 83e7561960c1..ab14ceb9e0ce 100644 --- a/drivers/media/common/tuners/tda18271-maps.c +++ b/drivers/media/common/tuners/tda18271-maps.c @@ -1,5 +1,5 @@ /* - tda18271-tables.c - driver for the Philips / NXP TDA18271 silicon tuner + tda18271-maps.c - driver for the Philips / NXP TDA18271 silicon tuner Copyright (C) 2007, 2008 Michael Krufky -- cgit v1.2.3 From 335377b73dd0b0af1fbd283ceae6fcb87a747885 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 7 May 2008 01:43:10 -0300 Subject: V4L/DVB (7986): cx23885: add initial support for DViCO FusionHDTV7 Dual Express Only one frontend is enabled right now. The second frontend can lock, but transport doesn't work yet. The device will be supported as a single tuner device until the second frontend is working. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.cx23885 | 1 + drivers/media/video/cx23885/cx23885-cards.c | 13 +++++++++++++ drivers/media/video/cx23885/cx23885-dvb.c | 27 +++++++++++++++++++++++++++ drivers/media/video/cx23885/cx23885.h | 1 + 4 files changed, 42 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 191194ea1e25..f0e613ba55b8 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -8,3 +8,4 @@ 7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3] 8 -> Hauppauge WinTV-HVR1700 [0070:8101] 9 -> Hauppauge WinTV-HVR1400 [0070:8010] + 10 -> DViCO FusionHDTV7 Dual Express [18ac:d618] diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 20e05f230546..fd7112c11d35 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -143,6 +143,10 @@ struct cx23885_board cx23885_boards[] = { .name = "Hauppauge WinTV-HVR1400", .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { + .name = "DViCO FusionHDTV7 Dual Express", + .portc = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -210,6 +214,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x8010, .card = CX23885_BOARD_HAUPPAUGE_HVR1400, + },{ + .subvendor = 0x18ac, + .subdevice = 0xd618, + .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -477,6 +485,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) } switch (dev->board) { + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ + ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + /* break omitted intentionally */ case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 022aa391937a..51dedb182c99 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -164,12 +164,28 @@ static struct s5h1409_config hauppauge_hvr1500q_config = { .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, }; +static struct s5h1409_config dvico_s5h1409_config = { + .demod_address = 0x32 >> 1, + .output_mode = S5H1409_SERIAL_OUTPUT, + .gpio = S5H1409_GPIO_ON, + .qam_if = 44000, + .inversion = S5H1409_INVERSION_OFF, + .status_mode = S5H1409_DEMODLOCKING, + .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, +}; + static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, .tuner_callback = cx23885_tuner_callback }; +static struct xc5000_config dvico_xc5000_tunerconfig = { + .i2c_address = 0x64, + .if_khz = 5380, + .tuner_callback = cx23885_tuner_callback +}; + static struct tda829x_config tda829x_no_probe = { .probe_tuner = TDA829X_DONT_PROBE, }; @@ -453,6 +469,17 @@ static int dvb_register(struct cx23885_tsport *port) fe->ops.tuner_ops.set_config(fe, &ctl); } break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + i2c_bus = &dev->i2c_bus[port->nr - 1]; + + port->dvb.frontend = dvb_attach(s5h1409_attach, + &dvico_s5h1409_config, + &i2c_bus->i2c_adap); + if (port->dvb.frontend != NULL) + dvb_attach(xc5000_attach, port->dvb.frontend, + &i2c_bus->i2c_adap, + &dvico_xc5000_tunerconfig, i2c_bus); + break; default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", dev->name); diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index 32af87f25e7b..00dfdc89d641 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -63,6 +63,7 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1200 7 #define CX23885_BOARD_HAUPPAUGE_HVR1700 8 #define CX23885_BOARD_HAUPPAUGE_HVR1400 9 +#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 /* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ #define CX23885_NORMS (\ -- cgit v1.2.3 From 72937890f98167cbe626f24df2c16d6b63e3e357 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 1 Jun 2008 10:35:18 -0300 Subject: V4L/DVB (7988): soc_camera: missed fmt callback conversion. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/soc_camera.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index d015bfe00950..8ae2d9916d9f 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -44,7 +44,7 @@ format_by_fourcc(struct soc_camera_device *icd, unsigned int fourcc) return NULL; } -static int soc_camera_try_fmt_cap(struct file *file, void *priv, +static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct soc_camera_file *icf = file->private_data; @@ -342,7 +342,7 @@ static struct file_operations soc_camera_fops = { }; -static int soc_camera_s_fmt_cap(struct file *file, void *priv, +static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct soc_camera_file *icf = file->private_data; @@ -362,7 +362,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv, /* buswidth may be further adjusted by the ici */ icd->buswidth = data_fmt->depth; - ret = soc_camera_try_fmt_cap(file, icf, f); + ret = soc_camera_try_fmt_vid_cap(file, icf, f); if (ret < 0) return ret; @@ -389,7 +389,7 @@ static int soc_camera_s_fmt_cap(struct file *file, void *priv, return ici->ops->set_bus_param(icd, f->fmt.pix.pixelformat); } -static int soc_camera_enum_fmt_cap(struct file *file, void *priv, +static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { struct soc_camera_file *icf = file->private_data; @@ -408,7 +408,7 @@ static int soc_camera_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int soc_camera_g_fmt_cap(struct file *file, void *priv, +static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct soc_camera_file *icf = file->private_data; @@ -925,15 +925,15 @@ int soc_camera_video_start(struct soc_camera_device *icd) vdev->minor = -1; vdev->tvnorms = V4L2_STD_UNKNOWN, vdev->vidioc_querycap = soc_camera_querycap; - vdev->vidioc_g_fmt_cap = soc_camera_g_fmt_cap; - vdev->vidioc_enum_fmt_cap = soc_camera_enum_fmt_cap; - vdev->vidioc_s_fmt_cap = soc_camera_s_fmt_cap; + vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap; + vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap; + vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap; vdev->vidioc_enum_input = soc_camera_enum_input; vdev->vidioc_g_input = soc_camera_g_input; vdev->vidioc_s_input = soc_camera_s_input; vdev->vidioc_s_std = soc_camera_s_std; vdev->vidioc_reqbufs = soc_camera_reqbufs; - vdev->vidioc_try_fmt_cap = soc_camera_try_fmt_cap; + vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap; vdev->vidioc_querybuf = soc_camera_querybuf; vdev->vidioc_qbuf = soc_camera_qbuf; vdev->vidioc_dqbuf = soc_camera_dqbuf; -- cgit v1.2.3 From 4fd305b2a2c4d16e8d4ebc95c84f946edd3385c5 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 4 Jun 2008 13:43:46 -0300 Subject: V4L/DVB (7992): Add support for Pinnacle PCTV HD Pro stick (the older variant 2304:0227) Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 27 +++++++++++++++++++++++++++ drivers/media/video/em28xx/em28xx-dvb.c | 2 ++ drivers/media/video/em28xx/em28xx.h | 1 + 4 files changed, 31 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 1d6a245c828f..5d9d366038ff 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -15,3 +15,4 @@ 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] + 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 8cbda43727c3..c22c90301d85 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -196,6 +196,29 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { + .name = "Pinnacle PCTV HD Pro Stick", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, @@ -417,6 +440,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, { USB_DEVICE(0x2304, 0x021a), .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0227), + .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), @@ -544,6 +569,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); msleep(50); @@ -577,6 +603,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) ctl->demod = XC3028_FE_ZARLINK456; break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: /* FIXME: Better to specify the needed IF */ ctl->demod = XC3028_FE_DEFAULT; break; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 0b2333ee07f8..9327d78fcf43 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -5,6 +5,7 @@ (c) 2008 Devin Heitmueller - Fixes for the driver to properly work with HVR-950 + - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick (c) 2008 Aidan Thornton @@ -399,6 +400,7 @@ static int dvb_init(struct em28xx *dev) /* init frontend */ switch (dev->model) { case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 002f170b211a..c3b5f460b211 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -55,6 +55,7 @@ #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 #define EM2800_BOARD_VGEAR_POCKETTV 15 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 +#define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From ce5829e5fc8204af09db5b226a3dce9824e7d596 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 31 May 2008 15:04:32 -0300 Subject: V4L/DVB (7993): si470x: move global lock to device structure this patch brings the following changes: - move the global disconnect lock into the device structure - code cleanup (spaces to tabs, long line splits, ...) Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 84 +++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 43 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 5dd33197bbdd..707988edc1b1 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -85,7 +85,7 @@ * Oliver Neukum * Version 1.0.7 * - usb autosuspend support - * - unplugging fixed + * - unplugging fixed * * ToDo: * - add seeking support @@ -425,7 +425,8 @@ struct si470x_device { /* driver management */ unsigned int users; - unsigned char disconnected; + unsigned char disconnected; + struct mutex disconnect_lock; /* Silabs internal registers (0..15) */ unsigned short registers[RADIO_REGISTER_NUM]; @@ -441,12 +442,6 @@ struct si470x_device { }; -/* - * Lock to prevent kfree of data before all users have releases the device. - */ -static DEFINE_MUTEX(open_close_lock); - - /* * The frequency is set in units of 62.5 Hz when using V4L2_TUNER_CAP_LOW, * 62.5 kHz otherwise. @@ -582,7 +577,7 @@ static int si470x_get_rds_registers(struct si470x_device *radio) usb_rcvintpipe(radio->usbdev, 1), (void *) &buf, sizeof(buf), &size, usb_timeout); if (size != sizeof(buf)) - printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " + printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " "return size differs: %d != %zu\n", size, sizeof(buf)); if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: " @@ -591,7 +586,8 @@ static int si470x_get_rds_registers(struct si470x_device *radio) if (retval >= 0) for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) radio->registers[STATUSRSSI + regnr] = - get_unaligned_be16(&buf[regnr * RADIO_REGISTER_SIZE + 1]); + get_unaligned_be16( + &buf[regnr * RADIO_REGISTER_SIZE + 1]); return (retval < 0) ? -EINVAL : 0; } @@ -879,8 +875,8 @@ static void si470x_work(struct work_struct *work) struct si470x_device *radio = container_of(work, struct si470x_device, work.work); - if (radio->disconnected) - return; + if (radio->disconnected) + return; if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) return; @@ -1007,20 +1003,20 @@ static int si470x_fops_open(struct inode *inode, struct file *file) static int si470x_fops_release(struct inode *inode, struct file *file) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval = 0; + int retval = 0; if (!radio) return -ENODEV; - mutex_lock(&open_close_lock); + mutex_lock(&radio->disconnect_lock); radio->users--; if (radio->users == 0) { - if (radio->disconnected) { - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - goto done; - } + if (radio->disconnected) { + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); + goto unlock; + } /* stop rds reception */ cancel_delayed_work_sync(&radio->work); @@ -1032,9 +1028,9 @@ static int si470x_fops_release(struct inode *inode, struct file *file) usb_autopm_put_interface(radio->intf); } -done: - mutex_unlock(&open_close_lock); - return retval; +unlock: + mutex_unlock(&radio->disconnect_lock); + return retval; } @@ -1174,8 +1170,8 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -1201,8 +1197,8 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -1266,8 +1262,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; if (tuner->index > 0) return -EINVAL; @@ -1324,8 +1320,8 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; if (tuner->index > 0) return -EINVAL; @@ -1351,8 +1347,8 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; freq->type = V4L2_TUNER_RADIO; freq->frequency = si470x_get_freq(radio); @@ -1370,8 +1366,8 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval; - if (radio->disconnected) - return -EIO; + if (radio->disconnected) + return -EIO; if (freq->type != V4L2_TUNER_RADIO) return -EINVAL; @@ -1436,8 +1432,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, memcpy(radio->videodev, &si470x_viddev_template, sizeof(si470x_viddev_template)); radio->users = 0; + radio->disconnected = 0; radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; + mutex_init(&radio->disconnect_lock); mutex_init(&radio->lock); video_set_drvdata(radio->videodev, radio); @@ -1542,16 +1540,16 @@ static void si470x_usb_driver_disconnect(struct usb_interface *intf) { struct si470x_device *radio = usb_get_intfdata(intf); - mutex_lock(&open_close_lock); - radio->disconnected = 1; + mutex_lock(&radio->disconnect_lock); + radio->disconnected = 1; cancel_delayed_work_sync(&radio->work); usb_set_intfdata(intf, NULL); - if (radio->users == 0) { - video_unregister_device(radio->videodev); - kfree(radio->buffer); - kfree(radio); - } - mutex_unlock(&open_close_lock); + if (radio->users == 0) { + video_unregister_device(radio->videodev); + kfree(radio->buffer); + kfree(radio); + } + mutex_unlock(&radio->disconnect_lock); } -- cgit v1.2.3 From 6cc72658897ee970e4ecfefaae58f043a98a8e65 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 31 May 2008 15:06:50 -0300 Subject: V4L/DVB (7994): si470x: let si470x_get_freq return errno This patch brings the following changes: - version bumped to 1.0.8 for all the following patches - si470x_get_freq now returns errno Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 707988edc1b1..7df1163d7097 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -23,6 +23,19 @@ */ +/* + * User Notes: + * - USB Audio is provided by the alsa snd_usb_audio module. + * For listing you have to redirect the sound, for example using: + * arecord -D hw:1,0 -r96000 -c2 -f S16_LE | artsdsp aplay -B - + * - regarding module parameters in /sys/module/radio_si470x/parameters: + * the contents of read-only files (0444) are not updated, even if + * space, band and de are changed using private video controls + * - increase tune_timeout, if you often get -EIO errors + * - hw_freq_seek returns -EAGAIN, when timed out or band limit is reached + */ + + /* * History: * 2008-01-12 Tobias Lorenz @@ -86,6 +99,9 @@ * Version 1.0.7 * - usb autosuspend support * - unplugging fixed + * 2008-05-07 Tobias Lorenz + * Version 1.0.8 + * - let si470x_get_freq return errno * * ToDo: * - add seeking support @@ -98,10 +114,10 @@ /* driver definitions */ #define DRIVER_AUTHOR "Tobias Lorenz " #define DRIVER_NAME "radio-si470x" -#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 7) +#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8) #define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver" #define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers" -#define DRIVER_VERSION "1.0.7" +#define DRIVER_VERSION "1.0.8" /* kernel includes */ @@ -631,9 +647,9 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) /* * si470x_get_freq - get the frequency */ -static unsigned int si470x_get_freq(struct si470x_device *radio) +static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq) { - unsigned int spacing, band_bottom, freq; + unsigned int spacing, band_bottom; unsigned short chan; int retval; @@ -659,14 +675,12 @@ static unsigned int si470x_get_freq(struct si470x_device *radio) /* read channel */ retval = si470x_get_register(radio, READCHAN); - if (retval < 0) - return retval; chan = radio->registers[READCHAN] & READCHAN_READCHAN; /* Frequency (MHz) = Spacing (kHz) x Channel + Bottom of Band (MHz) */ - freq = chan * spacing + band_bottom; + *freq = chan * spacing + band_bottom; - return freq; + return retval; } @@ -1351,9 +1365,7 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, return -EIO; freq->type = V4L2_TUNER_RADIO; - freq->frequency = si470x_get_freq(radio); - - return 0; + return si470x_get_freq(radio, &radio->frequency); } -- cgit v1.2.3 From a7c850a07eddf0e0f515d57b2ce696a9779c6ed1 Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 31 May 2008 15:07:52 -0300 Subject: V4L/DVB (7995): si470x: a lot of small code cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch brings the following changes: - comment on how to listen to an usb audio device   (i get so many questions about that...) - code cleanup (error handling, more warnings, spacing, ...) Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 286 +++++++++++++++++++++++++------------ 1 file changed, 196 insertions(+), 90 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 7df1163d7097..954ba997895d 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -101,7 +101,7 @@ * - unplugging fixed * 2008-05-07 Tobias Lorenz * Version 1.0.8 - * - let si470x_get_freq return errno + * - more safety checks, let si470x_get_freq return errno * * ToDo: * - add seeking support @@ -487,11 +487,11 @@ static int si470x_get_report(struct si470x_device *radio, void *buf, int size) USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, report[0], 2, buf, size, usb_timeout); + if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_get_report: usb_control_msg returned %d\n", retval); - return retval; } @@ -510,11 +510,11 @@ static int si470x_set_report(struct si470x_device *radio, void *buf, int size) USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, report[0], 2, buf, size, usb_timeout); + if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": si470x_set_report: usb_control_msg returned %d\n", retval); - return retval; } @@ -623,24 +623,30 @@ static int si470x_set_chan(struct si470x_device *radio, unsigned short chan) radio->registers[CHANNEL] |= CHANNEL_TUNE | chan; retval = si470x_set_register(radio, CHANNEL); if (retval < 0) - return retval; + goto done; - /* wait till seek operation has completed */ + /* wait till tune operation has completed */ timeout = jiffies + msecs_to_jiffies(tune_timeout); do { retval = si470x_get_register(radio, STATUSRSSI); if (retval < 0) - return retval; + goto stop; timed_out = time_after(jiffies, timeout); } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && (!timed_out)); + if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) + printk(KERN_WARNING DRIVER_NAME ": tune does not complete\n"); if (timed_out) printk(KERN_WARNING DRIVER_NAME - ": seek does not finish after %u ms\n", tune_timeout); + ": tune timed out after %u ms\n", tune_timeout); +stop: /* stop tuning */ radio->registers[CHANNEL] &= ~CHANNEL_TUNE; - return si470x_set_register(radio, CHANNEL); + retval = si470x_set_register(radio, CHANNEL); + +done: + return retval; } @@ -731,27 +737,30 @@ static int si470x_start(struct si470x_device *radio) POWERCFG_DMUTE | POWERCFG_ENABLE | POWERCFG_RDSM; retval = si470x_set_register(radio, POWERCFG); if (retval < 0) - return retval; + goto done; /* sysconfig 1 */ radio->registers[SYSCONFIG1] = SYSCONFIG1_DE; retval = si470x_set_register(radio, SYSCONFIG1); if (retval < 0) - return retval; + goto done; /* sysconfig 2 */ radio->registers[SYSCONFIG2] = - (0x3f << 8) | /* SEEKTH */ - (band << 6) | /* BAND */ - (space << 4) | /* SPACE */ - 15; /* VOLUME (max) */ + (0x3f << 8) | /* SEEKTH */ + ((band << 6) & SYSCONFIG2_BAND) | /* BAND */ + ((space << 4) & SYSCONFIG2_SPACE) | /* SPACE */ + 15; /* VOLUME (max) */ retval = si470x_set_register(radio, SYSCONFIG2); if (retval < 0) - return retval; + goto done; /* reset last channel */ - return si470x_set_chan(radio, + retval = si470x_set_chan(radio, radio->registers[CHANNEL] & CHANNEL_CHAN); + +done: + return retval; } @@ -766,13 +775,16 @@ static int si470x_stop(struct si470x_device *radio) radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_RDS; retval = si470x_set_register(radio, SYSCONFIG1); if (retval < 0) - return retval; + goto done; /* powercfg */ radio->registers[POWERCFG] &= ~POWERCFG_DMUTE; /* POWERCFG_ENABLE has to automatically go low */ radio->registers[POWERCFG] |= POWERCFG_ENABLE | POWERCFG_DISABLE; - return si470x_set_register(radio, POWERCFG); + retval = si470x_set_register(radio, POWERCFG); + +done: + return retval; } @@ -889,6 +901,7 @@ static void si470x_work(struct work_struct *work) struct si470x_device *radio = container_of(work, struct si470x_device, work.work); + /* safety checks */ if (radio->disconnected) return; if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) @@ -923,11 +936,15 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, /* block if no new data available */ while (radio->wr_index == radio->rd_index) { - if (file->f_flags & O_NONBLOCK) - return -EWOULDBLOCK; + if (file->f_flags & O_NONBLOCK) { + retval = -EWOULDBLOCK; + goto done; + } if (wait_event_interruptible(radio->read_queue, - radio->wr_index != radio->rd_index) < 0) - return -EINTR; + radio->wr_index != radio->rd_index) < 0) { + retval = -EINTR; + goto done; + } } /* calculate block count from byte count */ @@ -956,6 +973,7 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf, } mutex_unlock(&radio->lock); +done: return retval; } @@ -967,6 +985,7 @@ static unsigned int si470x_fops_poll(struct file *file, struct poll_table_struct *pts) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; /* switch on rds reception */ if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0) { @@ -978,9 +997,9 @@ static unsigned int si470x_fops_poll(struct file *file, poll_wait(file, &radio->read_queue, pts); if (radio->rd_index != radio->wr_index) - return POLLIN | POLLRDNORM; + retval = POLLIN | POLLRDNORM; - return 0; + return retval; } @@ -997,17 +1016,18 @@ static int si470x_fops_open(struct inode *inode, struct file *file) retval = usb_autopm_get_interface(radio->intf); if (retval < 0) { radio->users--; - return -EIO; + retval = -EIO; + goto done; } if (radio->users == 1) { retval = si470x_start(radio); if (retval < 0) usb_autopm_put_interface(radio->intf); - return retval; } - return 0; +done: + return retval; } @@ -1019,8 +1039,11 @@ static int si470x_fops_release(struct inode *inode, struct file *file) struct si470x_device *radio = video_get_drvdata(video_devdata(file)); int retval = 0; - if (!radio) - return -ENODEV; + /* safety check */ + if (!radio) { + retval = -ENODEV; + goto done; + } mutex_lock(&radio->disconnect_lock); radio->users--; @@ -1044,6 +1067,8 @@ static int si470x_fops_release(struct inode *inode, struct file *file) unlock: mutex_unlock(&radio->disconnect_lock); + +done: return retval; } @@ -1131,7 +1156,7 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, /* * si470x_vidioc_g_input - get input */ -static int si470x_vidioc_g_input(struct file *filp, void *priv, +static int si470x_vidioc_g_input(struct file *file, void *priv, unsigned int *i) { *i = 0; @@ -1143,12 +1168,18 @@ static int si470x_vidioc_g_input(struct file *filp, void *priv, /* * si470x_vidioc_s_input - set input */ -static int si470x_vidioc_s_input(struct file *filp, void *priv, unsigned int i) +static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i) { + int retval = 0; + + /* safety checks */ if (i != 0) - return -EINVAL; + retval = -EINVAL; - return 0; + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set input failed with %d\n", retval); + return retval; } @@ -1161,17 +1192,22 @@ static int si470x_vidioc_queryctrl(struct file *file, void *priv, unsigned char i; int retval = -EINVAL; + /* safety checks */ + if (!qc->id) + goto done; + for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) { - if (qc->id && qc->id == si470x_v4l2_queryctrl[i].id) { + if (qc->id == si470x_v4l2_queryctrl[i].id) { memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc)); retval = 0; break; } } + +done: if (retval < 0) printk(KERN_WARNING DRIVER_NAME - ": query control failed with %d\n", retval); - + ": query controls failed with %d\n", retval); return retval; } @@ -1183,9 +1219,13 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; - if (radio->disconnected) - return -EIO; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -1196,9 +1236,15 @@ static int si470x_vidioc_g_ctrl(struct file *file, void *priv, ctrl->value = ((radio->registers[POWERCFG] & POWERCFG_DMUTE) == 0) ? 1 : 0; break; + default: + retval = -EINVAL; } - return 0; +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": get control failed with %d\n", retval); + return retval; } @@ -1209,10 +1255,13 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - if (radio->disconnected) - return -EIO; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -1230,10 +1279,11 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, default: retval = -EINVAL; } + +done: if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": set control failed with %d\n", retval); - return retval; } @@ -1244,13 +1294,22 @@ static int si470x_vidioc_s_ctrl(struct file *file, void *priv, static int si470x_vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *audio) { - if (audio->index > 1) - return -EINVAL; + int retval = 0; + + /* safety checks */ + if (audio->index != 0) { + retval = -EINVAL; + goto done; + } strcpy(audio->name, "Radio"); audio->capability = V4L2_AUDCAP_STEREO; - return 0; +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": get audio failed with %d\n", retval); + return retval; } @@ -1260,10 +1319,19 @@ static int si470x_vidioc_g_audio(struct file *file, void *priv, static int si470x_vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *audio) { - if (audio->index != 0) - return -EINVAL; + int retval = 0; - return 0; + /* safety checks */ + if (audio->index != 0) { + retval = -EINVAL; + goto done; + } + +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set audio failed with %d\n", retval); + return retval; } @@ -1274,20 +1342,23 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - if (radio->disconnected) - return -EIO; - if (tuner->index > 0) - return -EINVAL; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } + if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; + goto done; + } - /* read status rssi */ retval = si470x_get_register(radio, STATUSRSSI); if (retval < 0) - return retval; + goto done; strcpy(tuner->name, "FM"); - tuner->type = V4L2_TUNER_RADIO; switch (band) { /* 0: 87.5 - 108 MHz (USA, Europe, default) */ default: @@ -1321,7 +1392,11 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, /* automatic frequency control: -1: freq to low, 1 freq to high */ tuner->afc = 0; - return 0; +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": get tuner failed with %d\n", retval); + return retval; } @@ -1332,12 +1407,17 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *tuner) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - if (radio->disconnected) - return -EIO; - if (tuner->index > 0) - return -EINVAL; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } + if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; + goto done; + } if (tuner->audmode == V4L2_TUNER_MODE_MONO) radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */ @@ -1345,10 +1425,11 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv, radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */ retval = si470x_set_register(radio, POWERCFG); + +done: if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": set tuner failed with %d\n", retval); - return retval; } @@ -1360,12 +1441,25 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; - if (radio->disconnected) - return -EIO; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } + if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; + goto done; + } + + retval = si470x_get_freq(radio, &freq->frequency); - freq->type = V4L2_TUNER_RADIO; - return si470x_get_freq(radio, &radio->frequency); +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": get frequency failed with %d\n", retval); + return retval; } @@ -1376,19 +1470,25 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *freq) { struct si470x_device *radio = video_get_drvdata(video_devdata(file)); - int retval; + int retval = 0; - if (radio->disconnected) - return -EIO; - if (freq->type != V4L2_TUNER_RADIO) - return -EINVAL; + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } + if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; + goto done; + } retval = si470x_set_freq(radio, freq->frequency); + +done: if (retval < 0) printk(KERN_WARNING DRIVER_NAME ": set frequency failed with %d\n", retval); - - return 0; + return retval; } @@ -1428,33 +1528,36 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct si470x_device *radio; - int retval = -ENOMEM; + int retval = 0; - /* private data allocation */ + /* private data allocation and initialization */ radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); - if (!radio) + if (!radio) { + retval = -ENOMEM; goto err_initial; - - /* video device allocation */ - radio->videodev = video_device_alloc(); - if (!radio->videodev) - goto err_radio; - - /* initial configuration */ - memcpy(radio->videodev, &si470x_viddev_template, - sizeof(si470x_viddev_template)); + } radio->users = 0; radio->disconnected = 0; radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; mutex_init(&radio->disconnect_lock); mutex_init(&radio->lock); + + /* video device allocation and initialization */ + radio->videodev = video_device_alloc(); + if (!radio->videodev) { + retval = -ENOMEM; + goto err_radio; + } + memcpy(radio->videodev, &si470x_viddev_template, + sizeof(si470x_viddev_template)); video_set_drvdata(radio->videodev, radio); /* show some infos about the specific device */ - retval = -EIO; - if (si470x_get_all_registers(radio) < 0) + if (si470x_get_all_registers(radio) < 0) { + retval = -EIO; goto err_all; + } printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); @@ -1480,8 +1583,10 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); - if (!radio->buffer) + if (!radio->buffer) { + retval = -EIO; goto err_all; + } /* rds buffer configuration */ radio->wr_index = 0; @@ -1493,6 +1598,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, /* register video device */ if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) { + retval = -EIO; printk(KERN_WARNING DRIVER_NAME ": Could not register video device\n"); goto err_all; -- cgit v1.2.3 From ace7d4bbe6170ef9b72bfa82c3e5769d250fffae Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 31 May 2008 15:09:07 -0300 Subject: V4L/DVB (7996): si470x: afc indication This patch brings the following changes: - afc indication: device has no indication whether freq is too low or too high therefore afc always return 1, when freq is wrong Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 954ba997895d..db9d64a228bb 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -101,6 +101,7 @@ * - unplugging fixed * 2008-05-07 Tobias Lorenz * Version 1.0.8 + * - afc indication * - more safety checks, let si470x_get_freq return errno * * ToDo: @@ -1390,7 +1391,8 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv, * 0x0101; /* automatic frequency control: -1: freq to low, 1 freq to high */ - tuner->afc = 0; + /* AFCRL does only indicate that freq. differs, not if too low/high */ + tuner->afc = (radio->registers[STATUSRSSI] & STATUSRSSI_AFCRL) ? 1 : 0; done: if (retval < 0) -- cgit v1.2.3 From bbc8995f9fa3f9cdd77aeb7c9bbf5bf526feca3c Mon Sep 17 00:00:00 2001 From: Tobias Lorenz Date: Sat, 31 May 2008 15:11:32 -0300 Subject: V4L/DVB (7997): si470x: hardware frequency seek support This patch brings the following changes: - this now finally adds hardware frequency seek support Signed-off-by: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/radio-si470x.c | 97 +++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index db9d64a228bb..dc93a882b385 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -101,11 +101,11 @@ * - unplugging fixed * 2008-05-07 Tobias Lorenz * Version 1.0.8 + * - hardware frequency seek support * - afc indication * - more safety checks, let si470x_get_freq return errno * * ToDo: - * - add seeking support * - add firmware download/update support * - RDS support: interrupt mode, instead of polling * - add LED status output (check if that's not already done in firmware) @@ -192,6 +192,11 @@ static unsigned int tune_timeout = 3000; module_param(tune_timeout, uint, 0); MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*"); +/* Seek timeout */ +static unsigned int seek_timeout = 5000; +module_param(seek_timeout, uint, 0); +MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*"); + /* RDS buffer blocks */ static unsigned int rds_buf = 100; module_param(rds_buf, uint, 0); @@ -726,6 +731,62 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq) } +/* + * si470x_set_seek - set seek + */ +static int si470x_set_seek(struct si470x_device *radio, + unsigned int wrap_around, unsigned int seek_upward) +{ + int retval = 0; + unsigned long timeout; + bool timed_out = 0; + + /* start seeking */ + radio->registers[POWERCFG] |= POWERCFG_SEEK; + if (wrap_around == 1) + radio->registers[POWERCFG] &= ~POWERCFG_SKMODE; + else + radio->registers[POWERCFG] |= POWERCFG_SKMODE; + if (seek_upward == 1) + radio->registers[POWERCFG] |= POWERCFG_SEEKUP; + else + radio->registers[POWERCFG] &= ~POWERCFG_SEEKUP; + retval = si470x_set_register(radio, POWERCFG); + if (retval < 0) + goto done; + + /* wait till seek operation has completed */ + timeout = jiffies + msecs_to_jiffies(seek_timeout); + do { + retval = si470x_get_register(radio, STATUSRSSI); + if (retval < 0) + goto stop; + timed_out = time_after(jiffies, timeout); + } while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) && + (!timed_out)); + if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) + printk(KERN_WARNING DRIVER_NAME ": seek does not complete\n"); + if (radio->registers[STATUSRSSI] & STATUSRSSI_SF) + printk(KERN_WARNING DRIVER_NAME + ": seek failed / band limit reached\n"); + if (timed_out) + printk(KERN_WARNING DRIVER_NAME + ": seek timed out after %u ms\n", seek_timeout); + +stop: + /* stop seeking */ + radio->registers[POWERCFG] &= ~POWERCFG_SEEK; + retval = si470x_set_register(radio, POWERCFG); + +done: + /* try again, if timed out */ + if ((retval == 0) && timed_out) + retval = -EAGAIN; + + return retval; +} + + /* * si470x_start - switch on radio */ @@ -1148,7 +1209,8 @@ static int si470x_vidioc_querycap(struct file *file, void *priv, strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); sprintf(capability->bus_info, "USB"); capability->version = DRIVER_KERNEL_VERSION; - capability->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; + capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | + V4L2_CAP_TUNER | V4L2_CAP_RADIO; return 0; } @@ -1494,6 +1556,36 @@ done: } +/* + * si470x_vidioc_s_hw_freq_seek - set hardware frequency seek + */ +static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv, + struct v4l2_hw_freq_seek *seek) +{ + struct si470x_device *radio = video_get_drvdata(video_devdata(file)); + int retval = 0; + + /* safety checks */ + if (radio->disconnected) { + retval = -EIO; + goto done; + } + if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) { + retval = -EINVAL; + goto done; + } + + retval = si470x_set_seek(radio, seek->wrap_around, seek->seek_upward); + +done: + if (retval < 0) + printk(KERN_WARNING DRIVER_NAME + ": set hardware frequency seek failed with %d\n", + retval); + return retval; +} + + /* * si470x_viddev_tamples - video device interface */ @@ -1514,6 +1606,7 @@ static struct video_device si470x_viddev_template = { .vidioc_s_tuner = si470x_vidioc_s_tuner, .vidioc_g_frequency = si470x_vidioc_g_frequency, .vidioc_s_frequency = si470x_vidioc_s_frequency, + .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, .owner = THIS_MODULE, }; -- cgit v1.2.3 From 17d9d558e818530cc7d210ffea575a36f48eaa1a Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 8 Jun 2008 10:22:03 -0300 Subject: V4L/DVB (8006): em28xx: Split HVR900 into two separate entries - Separate the newer variant of the HVR-900 into its own device profile because it has a Micronas DRX397 instead of the Zarlink demod. This doesn't make the device work, but at least we don't try to initialize it as though it had the Zarlink device. Signed-off-by: Devin Heitmueller [mchehab@infradead.org: avoid compilation breakage at mainstream, where drx397xD.h doesn't exist yet] Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 3 ++- drivers/media/video/em28xx/em28xx-cards.c | 29 ++++++++++++++++++++++++++++- drivers/media/video/em28xx/em28xx-dvb.c | 23 +++++++++++++++++++++++ drivers/media/video/em28xx/em28xx.h | 1 + 4 files changed, 54 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 5d9d366038ff..c7e23942c1dc 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -8,7 +8,7 @@ 7 -> Leadtek Winfast USB II (em2800) 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] - 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502] + 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] 11 -> Terratec Hybrid XS (em2880) [0ccd:0042] 12 -> Kworld PVR TV 2800 RF (em2820/em2840) 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] @@ -16,3 +16,4 @@ 15 -> V-Gear PocketTV (em2800) 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] + 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index c22c90301d85..938c51e1c86d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -173,6 +173,27 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { + .name = "Hauppauge WinTV HVR 900 (R2)", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { .name = "Hauppauge WinTV HVR 950", .vchannels = 3, @@ -445,7 +466,7 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, + .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ @@ -567,6 +588,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) switch (dev->model) { case EM2880_BOARD_TERRATEC_PRODIGY_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: @@ -602,6 +624,10 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: ctl->demod = XC3028_FE_ZARLINK456; break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: + /* djh - Not sure which demod we need here */ + ctl->demod = XC3028_FE_DEFAULT; + break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: /* FIXME: Better to specify the needed IF */ @@ -781,6 +807,7 @@ void em28xx_card_setup(struct em28xx *dev) switch (dev->model) { case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 9327d78fcf43..cc61cfb23a4a 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -27,6 +27,9 @@ #include "lgdt330x.h" #include "zl10353.h" +#ifdef EM28XX_DRX397XD_SUPPORT +#include "drx397xD.h" +#endif MODULE_DESCRIPTION("driver for em28xx based DVB cards"); MODULE_AUTHOR("Mauro Carvalho Chehab "); @@ -228,6 +231,13 @@ static struct zl10353_config em28xx_zl10353_with_xc3028 = { .if2 = 45600, }; +#ifdef EM28XX_DRX397XD_SUPPORT +/* [TODO] djh - not sure yet what the device config needs to contain */ +static struct drx397xD_config em28xx_drx397xD_with_xc3028 = { + .demod_address = (0xe0 >> 1), +}; +#endif + /* ------------------------------------------------------------------ */ static int attach_xc3028(u8 addr, struct em28xx *dev) @@ -418,6 +428,19 @@ static int dvb_init(struct em28xx *dev) goto out_free; } break; + case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: +#ifdef EM28XX_DRX397XD_SUPPORT + /* We don't have the config structure properly populated, so + this is commented out for now */ + dvb->frontend = dvb_attach(drx397xD_attach, + &em28xx_drx397xD_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; +#endif default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index c3b5f460b211..cff618b2d13c 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -56,6 +56,7 @@ #define EM2800_BOARD_VGEAR_POCKETTV 15 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 +#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From fb49558c3b6b55c0f3378b7e8935c2d9e357f93a Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 28 May 2008 22:16:31 -0300 Subject: V4L/DVB (8014): gl861: coding style fixes - coding style fixes raised by checkpatch Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/gl861.c | 38 +++++++++++++++++++------------------- drivers/media/dvb/dvb-usb/gl861.h | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index 037f7ffb47b2..6f596ed41761 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c @@ -1,8 +1,8 @@ /* DVB USB compliant linux driver for GL861 USB2.0 devices. * * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, version 2. * * see Documentation/dvb/README.dvb-usb for more information */ @@ -13,9 +13,9 @@ /* debug */ static int dvb_usb_gl861_debug; -module_param_named(debug,dvb_usb_gl861_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - +module_param_named(debug, dvb_usb_gl861_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." + DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, @@ -70,7 +70,7 @@ static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], /* write/read request */ if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) + msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) break; i++; } else @@ -102,12 +102,13 @@ static struct zl10353_config gl861_zl10353_config = { static int gl861_frontend_attach(struct dvb_usb_adapter *adap) { - if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, - &adap->dev->i2c_adap)) != NULL) { - return 0; - } - return -EIO; + adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, + &adap->dev->i2c_adap); + if (adap->fe == NULL) + return -EIO; + + return 0; } static struct qt1010_config gl861_qt1010_config = { @@ -156,7 +157,7 @@ static struct usb_device_id gl861_table [] = { { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, gl861_table); +MODULE_DEVICE_TABLE(usb, gl861_table); static struct dvb_usb_device_properties gl861_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, @@ -180,7 +181,7 @@ static struct dvb_usb_device_properties gl861_properties = { } } }, - }}, + } }, .i2c_algo = &gl861_i2c_algo, .num_device_descs = 2, @@ -210,12 +211,11 @@ static int __init gl861_module_init(void) { int ret; - if ((ret = usb_register(&gl861_driver))) { + ret = usb_register(&gl861_driver); + if (ret) err("usb_register failed. Error number %d", ret); - return ret; - } - return 0; + return ret; } static void __exit gl861_module_exit(void) @@ -224,8 +224,8 @@ static void __exit gl861_module_exit(void) usb_deregister(&gl861_driver); } -module_init (gl861_module_init); -module_exit (gl861_module_exit); +module_init(gl861_module_init); +module_exit(gl861_module_exit); MODULE_AUTHOR("Carl Lundqvist "); MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h index 72a51afd5ee3..c54855e2c233 100644 --- a/drivers/media/dvb/dvb-usb/gl861.h +++ b/drivers/media/dvb/dvb-usb/gl861.h @@ -4,7 +4,7 @@ #define DVB_USB_LOG_PREFIX "gl861" #include "dvb-usb.h" -#define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args) +#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args) #define GL861_WRITE 0x40 #define GL861_READ 0xc0 -- cgit v1.2.3 From 37df96d39eefd0c1db69a336895c4691d2bc63a1 Mon Sep 17 00:00:00 2001 From: Dmitry Belimov Date: Tue, 10 Jun 2008 12:43:58 -0300 Subject: V4L/DVB (8019): New for I2S on for MPEG of saa7134_empress Rework saa7134_enable_i2s function. Remove vendor specific data. Configure I2S output port specific for model of SAA7133/5-SAA7134. I think it is more good. Renamed definition of I2S audio output control register. It`s SAA7133/5 register Start video port after configuring procedure. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-reg.h | 2 +- drivers/media/video/saa7134/saa7134-tvaudio.c | 33 +++++++++++++++++---------- drivers/media/video/saa7134/saa7134-video.c | 6 ++++- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-reg.h b/drivers/media/video/saa7134/saa7134-reg.h index 258792c1784e..cf89d96d7295 100644 --- a/drivers/media/video/saa7134/saa7134-reg.h +++ b/drivers/media/video/saa7134/saa7134-reg.h @@ -353,7 +353,6 @@ /* I2S output */ #define SAA7134_I2S_AUDIO_OUTPUT 0x1c0 -#define SAA7134_I2S_AUDIO_CONTROL 0x591 /* test modes */ #define SAA7134_SPECIAL_MODE 0x1d0 @@ -369,6 +368,7 @@ #define SAA7135_DSP_RWCLEAR 0x586 #define SAA7135_DSP_RWCLEAR_RERR 1 +#define SAA7133_I2S_AUDIO_CONTROL 0x591 /* ------------------------------------------------------------------ */ /* * Local variables: diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 460d4a35e5f1..4cc3741c5472 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -874,23 +874,32 @@ void saa7134_enable_i2s(struct saa7134_dev *dev) if (!card_is_empress(dev)) return; - switch (dev->board) { - case SAA7134_BOARD_BEHOLD_M6: - /* configure GPIO for out audio */ - saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000); - /* Set I2S format */ - saa_writeb(SAA7134_I2S_AUDIO_CONTROL, 0x00); + if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130) + return; + + /* configure GPIO for out */ + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x0E000000, 0x00000000); + + switch (dev->pci->device) { + case PCI_DEVICE_ID_PHILIPS_SAA7133: + case PCI_DEVICE_ID_PHILIPS_SAA7135: + /* Set I2S format (SONY)  */ + saa_writeb(SAA7133_I2S_AUDIO_CONTROL, 0x00); /* Start I2S */ - saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11); + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x11); break; - default: + + case PCI_DEVICE_ID_PHILIPS_SAA7134: i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01; /* enable I2S audio output for the mpeg encoder */ - saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); - saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); - saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); - saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80); + saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format); + saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F); + saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01); + + default: + break; } } diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index bba23219ce94..8a8b3e118f8b 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2458,13 +2458,14 @@ int saa7134_videoport_init(struct saa7134_dev *dev) int vo = saa7134_boards[dev->board].video_out; int video_reg; unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts; + + /* Configure videoport */ saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]); video_reg = video_out[vo][1]; if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED) video_reg &= ~VP_T_CODE_P_INVERTED; saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg); saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]); - saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]); video_reg = video_out[vo][5]; if (vid_port_opts & SET_CLOCK_NOT_DELAYED) @@ -2481,6 +2482,9 @@ int saa7134_videoport_init(struct saa7134_dev *dev) saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]); saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]); + /* Start videoport */ + saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]); + return 0; } -- cgit v1.2.3 From 878cf2a5d86c7045b480f09b56b96a779449b0f6 Mon Sep 17 00:00:00 2001 From: Dmitry Belimov Date: Tue, 10 Jun 2008 14:22:00 -0300 Subject: V4L/DVB (8021): Beholder's cards description Split the Beholder M6 family to different models. Because M6 hasn`t RDS, M63 has chip with AC3 codec, M6 Extra has other type of HF module. Add correct data for support MPEG encoder. Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 4 +- drivers/media/video/saa7134/saa7134-cards.c | 95 ++++++++++++++++++++++++++--- drivers/media/video/saa7134/saa7134-input.c | 2 + drivers/media/video/saa7134/saa7134.h | 3 +- 4 files changed, 95 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 67937df1e974..4c8a86f24dbe 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -128,7 +128,7 @@ 127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090] 128 -> Beholder BeholdTV Columbus TVFM [0000:5201] 129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093] -130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193,5ace:6191] +130 -> Beholder BeholdTV M6 [5ace:6190] 131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022] 132 -> Genius TVGO AM11MCE 133 -> NXP Snake DVB-S reference design @@ -141,3 +141,5 @@ 140 -> Avermedia DVB-S Pro A700 [1461:a7a1] 141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2] 142 -> Beholder BeholdTV H6 [5ace:6290] +143 -> Beholder BeholdTV M63 [5ace:6191] +144 -> Beholder BeholdTV M6 Extra [5ace:6193] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 2618cfa592e7..6c53168f20f7 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3940,32 +3940,111 @@ struct saa7134_board saa7134_boards[] = { [SAA7134_BOARD_BEHOLD_M6] = { /* Igor Kuznetsov */ /* Andrey Melnikoff */ - .name = "Beholder BeholdTV M6 / BeholdTV M6 Extra", + /* Beholder Intl. Ltd. Dmitry Belimov */ + .name = "Beholder BeholdTV M6", .audio_clock = 0x00187de7, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .inputs = {{ + .inputs = { { .name = name_tv, .vmux = 3, .amux = TV, .tv = 1, - },{ + }, { .name = name_comp1, .vmux = 1, .amux = LINE1, - },{ + }, { .name = name_svideo, .vmux = 8, .amux = LINE1, - }}, + } }, .radio = { .name = name_radio, .amux = LINE2, }, .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), + }, + [SAA7134_BOARD_BEHOLD_M63] = { + /* Igor Kuznetsov */ + /* Andrey Melnikoff */ + /* Beholder Intl. Ltd. Dmitry Belimov */ + .name = "Beholder BeholdTV M63", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = { { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), + }, + [SAA7134_BOARD_BEHOLD_M6_EXTRA] = { + /* Igor Kuznetsov */ + /* Andrey Melnikoff */ + /* Beholder Intl. Ltd. Dmitry Belimov */ + .name = "Beholder BeholdTV M6 Extra", + .audio_clock = 0x00187de7, + /* FIXME: Must be PHILIPS_FM1216ME_MK5*/ + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .inputs = { { + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + }, { + .name = name_comp1, + .vmux = 1, + .amux = LINE1, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE1, + } }, + .radio = { + .name = name_radio, + .amux = LINE2, + }, + .mpeg = SAA7134_MPEG_EMPRESS, + .video_out = CCIR656, + .vid_port_opts = (SET_T_CODE_POLARITY_NON_INVERTED | + SET_CLOCK_NOT_DELAYED | + SET_CLOCK_INVERTED | + SET_VSYNC_OFF), }, [SAA7134_BOARD_TWINHAN_DTV_DVB_3056] = { .name = "Twinhan Hybrid DTV-DVB 3056 PCI", @@ -5226,13 +5305,13 @@ struct pci_device_id saa7134_pci_tbl[] = { .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5ace, .subdevice = 0x6193, - .driver_data = SAA7134_BOARD_BEHOLD_M6, + .driver_data = SAA7134_BOARD_BEHOLD_M6_EXTRA, }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, .subvendor = 0x5ace, .subdevice = 0x6191, - .driver_data = SAA7134_BOARD_BEHOLD_M6, + .driver_data = SAA7134_BOARD_BEHOLD_M63, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -5601,6 +5680,8 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_HAUPPAUGE_HVR1110: case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: + case SAA7134_BOARD_BEHOLD_M63: + case SAA7134_BOARD_BEHOLD_M6_EXTRA: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 76e6501d238d..6edabc06e6d0 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -540,6 +540,8 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) break; case SAA7134_BOARD_BEHOLD_607_9FM: case SAA7134_BOARD_BEHOLD_M6: + case SAA7134_BOARD_BEHOLD_M63: + case SAA7134_BOARD_BEHOLD_M6_EXTRA: case SAA7134_BOARD_BEHOLD_H6: snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV"); ir->get_key = get_key_beholdm6xx; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 34ff0d4998f3..0a94be7afc1e 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -264,7 +264,8 @@ struct saa7134_format { #define SAA7134_BOARD_AVERMEDIA_A700_PRO 140 #define SAA7134_BOARD_AVERMEDIA_A700_HYBRID 141 #define SAA7134_BOARD_BEHOLD_H6 142 - +#define SAA7134_BOARD_BEHOLD_M63 143 +#define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3 From 745271aefec602326b1dafded778d1eb94bc50ad Mon Sep 17 00:00:00 2001 From: Carl Karsten Date: Tue, 10 Jun 2008 00:02:32 -0300 Subject: V4L/DVB (8023): vivi: announce that it is registered as /dev/video%d Signed-off-by: Carl Karsten Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index a9747a10c546..9a8ded371eb8 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -39,6 +39,8 @@ #include #include +#define MODULE_NAME "vivi" + /* Wake up at about 30 fps */ #define WAKE_NUMERATOR 30 #define WAKE_DENOMINATOR 1001 @@ -47,7 +49,7 @@ #include "font.h" #define VIVI_MAJOR_VERSION 0 -#define VIVI_MINOR_VERSION 4 +#define VIVI_MINOR_VERSION 5 #define VIVI_RELEASE 0 #define VIVI_VERSION \ KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) @@ -1017,10 +1019,15 @@ static int vivi_release(void) list_del(list); dev = list_entry(list, struct vivi_dev, vivi_devlist); - if (-1 != dev->vfd->minor) + if (-1 != dev->vfd->minor) { video_unregister_device(dev->vfd); - else + printk(KERN_INFO "%s: /dev/video%d unregistered.\n", + MODULE_NAME, dev->vfd->minor); + } else { video_device_release(dev->vfd); + printk(KERN_INFO "%s: /dev/video%d released.\n", + MODULE_NAME, dev->vfd->minor); + } kfree(dev); } @@ -1131,6 +1138,8 @@ static int __init vivi_init(void) video_nr++; dev->vfd = vfd; + printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", + MODULE_NAME, vfd->minor); } if (ret < 0) { @@ -1138,7 +1147,9 @@ static int __init vivi_init(void) printk(KERN_INFO "Error %d while loading vivi driver\n", ret); } else printk(KERN_INFO "Video Technology Magazine Virtual Video " - "Capture Board successfully loaded.\n"); + "Capture Board ver %u.%u.%u successfully loaded.\n", + (VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF, + VIVI_VERSION & 0xFF); return ret; } -- cgit v1.2.3 From 584ce48de9e01838402c8e82c78f166775ea3075 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 10 Jun 2008 15:21:49 -0300 Subject: V4L/DVB (8024): vivi: rename MODULE_NAME macro to VIVI_MODULE_NAME to avoid namespace conflicts Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 9a8ded371eb8..059b01c11dc1 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -39,7 +39,7 @@ #include #include -#define MODULE_NAME "vivi" +#define VIVI_MODULE_NAME "vivi" /* Wake up at about 30 fps */ #define WAKE_NUMERATOR 30 @@ -1022,11 +1022,11 @@ static int vivi_release(void) if (-1 != dev->vfd->minor) { video_unregister_device(dev->vfd); printk(KERN_INFO "%s: /dev/video%d unregistered.\n", - MODULE_NAME, dev->vfd->minor); + VIVI_MODULE_NAME, dev->vfd->minor); } else { video_device_release(dev->vfd); printk(KERN_INFO "%s: /dev/video%d released.\n", - MODULE_NAME, dev->vfd->minor); + VIVI_MODULE_NAME, dev->vfd->minor); } kfree(dev); @@ -1139,7 +1139,7 @@ static int __init vivi_init(void) dev->vfd = vfd; printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n", - MODULE_NAME, vfd->minor); + VIVI_MODULE_NAME, vfd->minor); } if (ret < 0) { -- cgit v1.2.3 From e75888661a7008503e3d147f92499d9c30ebf6e3 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 9 Jun 2008 22:53:04 -0300 Subject: V4L/DVB (8030): TDA10023: make TS output mode configurable - make TS output mode configurable Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda10023.c | 6 +++++- drivers/media/dvb/frontends/tda1002x.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c index 2996b73cf4b4..a3c34eecdee9 100644 --- a/drivers/media/dvb/frontends/tda10023.c +++ b/drivers/media/dvb/frontends/tda10023.c @@ -269,7 +269,8 @@ static int tda10023_init (struct dvb_frontend *fe) /* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */ /* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */ /* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */ -/* 093 */ 0x12, 0xff, 0xa1, /* INTP1 POCLKP=1 FEL=1 MFS=0 */ +/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /* + INTP1 POCLKP=1 FEL=1 MFS=0 */ /* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */ /* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */ /* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */ @@ -289,6 +290,9 @@ static int tda10023_init (struct dvb_frontend *fe) tda10023_inittab[83] = (state->config->deltaf >> 8); } + if (state->config->output_mode) + tda10023_inittab[95] = state->config->output_mode; + tda10023_writetab(state, tda10023_inittab); return 0; diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h index 4522b7ef53c9..afc0a32eaabd 100644 --- a/drivers/media/dvb/frontends/tda1002x.h +++ b/drivers/media/dvb/frontends/tda1002x.h @@ -32,6 +32,13 @@ struct tda1002x_config { u8 invert; }; +enum tda10023_output_mode { + TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0, + TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1, + TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0, + TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */ +}; + struct tda10023_config { /* the demodulator's i2c address */ u8 demod_address; @@ -43,6 +50,9 @@ struct tda10023_config { u8 pll_p; /* defaults: 4 */ u8 pll_n; /* defaults: 1 */ + /* MPEG2 TS output mode */ + u8 output_mode; + /* input freq offset + baseband conversion type */ u16 deltaf; }; -- cgit v1.2.3 From 5ae2fcaee4b0d6bf0fa5d9bd71e1291c9a9a6e60 Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Mon, 9 Jun 2008 22:58:22 -0300 Subject: V4L/DVB (8031): Anysee: support for Anysee E30C Plus rev 0.4 - support for Anysee E30C Plus rev 0.4 - set IO port E - set correct TS mode - change deltaf according to latest Windows driver Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/anysee.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index dada92a14cf3..a3f9bbc355bb 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -227,7 +227,8 @@ static struct tda10023_config anysee_tda10023_config = { .pll_m = 11, .pll_p = 3, .pll_n = 1, - .deltaf = 0xfed6, + .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, + .deltaf = 0xfeeb, }; static struct mt352_config anysee_mt352_config = { @@ -272,8 +273,8 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) 1. E30 MT352 02 0.2.1 2. E30 ZL10353 02 0.2.1 3. E30 Plus ZL10353 06 0.1.0 - 4. E30C Plus TDA10023 0a 0.1.0 - E30C Plus TDA10023 0f 0.1.2 (not working) + 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2 + 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4 */ /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ @@ -305,13 +306,10 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) return 0; } - /* known not working (E30C Plus v0.1.2) */ - if (hw_info[0] == 0x0f) { - info("this version of Anysee is not supported yet"); - /* return IO port D to init value for safe */ - ret = anysee_write_reg(adap->dev, 0xb0, io_d); - return -ENODEV; - } + /* IO port E - E30C rev 0.4 board requires this */ + ret = anysee_write_reg(adap->dev, 0xb1, 0xa7); + if (ret) + return ret; /* Philips TDA10023 DVB-C demod */ adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, -- cgit v1.2.3 From 9fdd9caf44296213c1e1130e86c2f919f83124da Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 11 Jun 2008 11:43:19 -0300 Subject: V4L/DVB (8032): Anysee: fix Kconfig - select DVB_PLL - fix typos in comments Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + drivers/media/dvb/dvb-usb/anysee.c | 4 ++-- drivers/media/dvb/dvb-usb/anysee.h | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3f7b9b6326b3..cae574fa79e0 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -244,6 +244,7 @@ config DVB_USB_AF9005_REMOTE config DVB_USB_ANYSEE tristate "Anysee DVB-T/C USB2.0 support" depends on DVB_USB + select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index a3f9bbc355bb..adfd4fc82efd 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -23,8 +23,8 @@ * Card reader in Anysee is nothing more than ISO 7816 card reader. * There is no hardware CAM in any Anysee device sold. * In my understanding it should be implemented by making own module - * for ISO 7816 card reader, like dvb_ca_en50221 is implented. This - * module registers serial interface that can be used to comminicate + * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This + * module registers serial interface that can be used to communicate * with any ISO 7816 smart card. * * Any help according to implement serial smart card reader support diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index 48da3949ef0b..7ca01ff6e13c 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -23,8 +23,8 @@ * Card reader in Anysee is nothing more than ISO 7816 card reader. * There is no hardware CAM in any Anysee device sold. * In my understanding it should be implemented by making own module - * for ISO 7816 card reader, like dvb_ca_en50221 is implented. This - * module registers serial interface that can be used to comminicate + * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This + * module registers serial interface that can be used to communicate * with any ISO 7816 smart card. * * Any help according to implement serial smart card reader support -- cgit v1.2.3 From 6275163e3ddbf0f0b34981bf6dc50b803e5a1c67 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 12 Jun 2008 13:20:46 -0300 Subject: V4L/DVB (8046): zoran: i2c structure templates clean-up Clean up the use of structure templates in zoran_card. For one thing, a real template is supposed to be read-only. And in some cases it's more efficient to initialize the few fields we need individually. Signed-off-by: Jean Delvare Acked-by: Ronald S. Bultje Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_card.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 006d48847e24..24afe81a59de 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -59,8 +59,6 @@ #include "zoran_device.h" #include "zoran_procfs.h" -#define I2C_NAME(x) (x)->name - extern const struct zoran_format zoran_formats[]; static int card[BUZ_MAX] = { -1, -1, -1, -1 }; @@ -809,7 +807,7 @@ clientunreg_unlock_and_return: return res; } -static struct i2c_algo_bit_data zoran_i2c_bit_data_template = { +static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = { .setsda = zoran_i2c_setsda, .setscl = zoran_i2c_setscl, .getsda = zoran_i2c_getsda, @@ -818,24 +816,17 @@ static struct i2c_algo_bit_data zoran_i2c_bit_data_template = { .timeout = 100, }; -static struct i2c_adapter zoran_i2c_adapter_template = { - .name = "zr36057", - .id = I2C_HW_B_ZR36067, - .algo = NULL, - .client_register = zoran_i2c_client_register, - .client_unregister = zoran_i2c_client_unregister, -}; - static int zoran_register_i2c (struct zoran *zr) { memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template, sizeof(struct i2c_algo_bit_data)); zr->i2c_algo.data = zr; - memcpy(&zr->i2c_adapter, &zoran_i2c_adapter_template, - sizeof(struct i2c_adapter)); - strncpy(I2C_NAME(&zr->i2c_adapter), ZR_DEVNAME(zr), - sizeof(I2C_NAME(&zr->i2c_adapter)) - 1); + zr->i2c_adapter.id = I2C_HW_B_ZR36067; + zr->i2c_adapter.client_register = zoran_i2c_client_register; + zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister; + strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr), + sizeof(zr->i2c_adapter.name)); i2c_set_adapdata(&zr->i2c_adapter, zr); zr->i2c_adapter.algo_data = &zr->i2c_algo; zr->i2c_adapter.dev.parent = &zr->pci_dev->dev; -- cgit v1.2.3 From df9b5d4cf636f992276b6b595620d9b2a63095db Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 15 Jun 2008 12:20:18 -0300 Subject: V4L/DVB (8047): bt8xx: i2c structure templates clean-up Clean up the use of structure templates in bttv-i2c. For one thing, a real template is supposed to be read-only. And in some cases it's more efficient to initialize the few fields we need individually. This clean-up shrinks bttv-i2c.o by 29% (x86_64). Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-i2c.c | 49 +++++++++++------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c index 4d5b8035e466..bcd2cd240a16 100644 --- a/drivers/media/video/bt8xx/bttv-i2c.c +++ b/drivers/media/video/bt8xx/bttv-i2c.c @@ -36,11 +36,6 @@ #include #include -static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; -static struct i2c_adapter bttv_i2c_adap_sw_template; -static struct i2c_adapter bttv_i2c_adap_hw_template; -static struct i2c_client bttv_i2c_client_template; - static int attach_inform(struct i2c_client *client); static int i2c_debug; @@ -104,7 +99,7 @@ static int bttv_bit_getsda(void *data) return state; } -static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { +static struct i2c_algo_bit_data __devinitdata bttv_i2c_algo_bit_template = { .setsda = bttv_bit_setsda, .setscl = bttv_bit_setscl, .getsda = bttv_bit_getsda, @@ -113,14 +108,6 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { .timeout = 200, }; -static struct i2c_adapter bttv_i2c_adap_sw_template = { - .owner = THIS_MODULE, - .class = I2C_CLASS_TV_ANALOG, - .name = "bttv", - .id = I2C_HW_B_BT848, - .client_register = attach_inform, -}; - /* ----------------------------------------------------------------------- */ /* I2C functions - hardware i2c */ @@ -270,20 +257,11 @@ static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int return retval; } -static struct i2c_algorithm bttv_algo = { +static const struct i2c_algorithm bttv_algo = { .master_xfer = bttv_i2c_xfer, .functionality = functionality, }; -static struct i2c_adapter bttv_i2c_adap_hw_template = { - .owner = THIS_MODULE, - .class = I2C_CLASS_TV_ANALOG, - .name = "bt878", - .id = I2C_HW_B_BT848 /* FIXME */, - .algo = &bttv_algo, - .client_register = attach_inform, -}; - /* ----------------------------------------------------------------------- */ /* I2C functions - common stuff */ @@ -332,10 +310,6 @@ void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg) i2c_clients_command(&btv->c.i2c_adap, cmd, arg); } -static struct i2c_client bttv_i2c_client_template = { - .name = "bttv internal", -}; - /* read I2C */ int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for) @@ -417,29 +391,34 @@ static void do_i2c_scan(char *name, struct i2c_client *c) /* init + register i2c algo-bit adapter */ int __devinit init_bttv_i2c(struct bttv *btv) { - memcpy(&btv->i2c_client, &bttv_i2c_client_template, - sizeof(bttv_i2c_client_template)); + strlcpy(btv->i2c_client.name, "bttv internal", I2C_NAME_SIZE); if (i2c_hw) btv->use_i2c_hw = 1; if (btv->use_i2c_hw) { /* bt878 */ - memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template, - sizeof(bttv_i2c_adap_hw_template)); + strlcpy(btv->c.i2c_adap.name, "bt878", + sizeof(btv->c.i2c_adap.name)); + btv->c.i2c_adap.id = I2C_HW_B_BT848; /* FIXME */ + btv->c.i2c_adap.algo = &bttv_algo; } else { /* bt848 */ /* Prevents usage of invalid delay values */ if (i2c_udelay<5) i2c_udelay=5; - bttv_i2c_algo_bit_template.udelay=i2c_udelay; - memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template, - sizeof(bttv_i2c_adap_sw_template)); + strlcpy(btv->c.i2c_adap.name, "bttv", + sizeof(btv->c.i2c_adap.name)); + btv->c.i2c_adap.id = I2C_HW_B_BT848; memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template, sizeof(bttv_i2c_algo_bit_template)); + btv->i2c_algo.udelay = i2c_udelay; btv->i2c_algo.data = btv; btv->c.i2c_adap.algo_data = &btv->i2c_algo; } + btv->c.i2c_adap.owner = THIS_MODULE; + btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG; + btv->c.i2c_adap.client_register = attach_inform; btv->c.i2c_adap.dev.parent = &btv->c.pci->dev; snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name), -- cgit v1.2.3 From 11417daab6d596f8d4851476777ca49fb3b12a87 Mon Sep 17 00:00:00 2001 From: Sigmund Augdal Date: Sun, 15 Jun 2008 17:25:46 -0300 Subject: V4L/DVB (8049): budget-ci: Add support for Technotrend budget C-1501 dvb-c card The following experimental patch adds support for the technotrend budget C-1501 dvb-c card. The parameters used to configure the tda10023 demod chip are largely determined experimentally, but works quite for me in my initial tests. Signed-off-by: Sigmund Augdal Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 6530323d5406..374100316dc3 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -46,6 +46,8 @@ #include "lnbp21.h" #include "bsbe1.h" #include "bsru6.h" +#include "tda1002x.h" +#include "tda827x.h" /* * Regarding DEBIADDR_IR: @@ -1056,6 +1058,15 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = { .stop_during_read = 1, }; +static struct tda10023_config tda10023_config = { + .demod_address = 0xc, + .invert = 0, + .xtal = 16000000, + .pll_m = 11, + .pll_p = 3, + .pll_n = 1, + .deltaf = 0xa511, +}; @@ -1126,7 +1137,17 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend = NULL; } } + break; + case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ + budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); + if (budget_ci->budget.dvb_frontend) { + if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) { + printk(KERN_ERR "%s: No tda827x found!\n", __func__); + dvb_frontend_detach(budget_ci->budget.dvb_frontend); + budget_ci->budget.dvb_frontend = NULL; + } + } break; } @@ -1216,6 +1237,7 @@ MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); +MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), @@ -1224,6 +1246,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), + MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), { .vendor = 0, } -- cgit v1.2.3 From c121ba1f408eb13ff50891ff8d9e5914f993939c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jun 2008 12:31:57 -0300 Subject: V4L/DVB (8050): Add register get/set debug ioctls to saa7134 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-video.c | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 8a8b3e118f8b..1a5137550e7a 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2208,6 +2208,32 @@ static int saa7134_g_parm(struct file *file, void *fh, return 0; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int vidioc_g_register (struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + reg->val = saa_readb(reg->reg); + return 0; +} + +static int vidioc_s_register (struct file *file, void *priv, + struct v4l2_register *reg) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return -EINVAL; + saa_writeb(reg->reg&0xffffff, reg->val); + return 0; +} +#endif + static int radio_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -2391,6 +2417,10 @@ struct video_device saa7134_video_template = .vidioc_g_parm = saa7134_g_parm, .vidioc_g_frequency = saa7134_g_frequency, .vidioc_s_frequency = saa7134_s_frequency, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = vidioc_g_register, + .vidioc_s_register = vidioc_s_register, +#endif .tvnorms = SAA7134_NORMS, .current_norm = V4L2_STD_PAL, }; -- cgit v1.2.3 From a046e43dc884e4cd01c682b22db9cc872d7b0e60 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jun 2008 12:35:06 -0300 Subject: V4L/DVB (8051): ttpci/Kconfig: Technotrend budget C-1501 needs tda10023 Auto-selects tda10023, for budget-ci, if !DVB_FE_CUSTOMISE. This is needed for Technotrend budget C-1501 dvb board. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 07643e010093..0816344e0206 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -106,6 +106,7 @@ config DVB_BUDGET_CI select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE + select DVB_TDA10023 if !DVB_FE_CUSTOMISE select VIDEO_IR help Support for simple SAA7146 based DVB cards -- cgit v1.2.3 From 03a0ea11e2db5cf4fb47ca78cb25c4f7b9c8293b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 18 Jun 2008 09:27:21 -0300 Subject: V4L/DVB (8059): Add missing select for MEDIA_TUNER_TDA827X $ find linux/drivers/media/dvb -exec grep -l tda827x_attach '{}' \; linux/drivers/media/dvb/dvb-usb/m920x.c linux/drivers/media/dvb/ttpci/budget-ci.c Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + drivers/media/dvb/ttpci/Kconfig | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index cae574fa79e0..bee1bf3c9db1 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -120,6 +120,7 @@ config DVB_USB_M920X depends on DVB_USB select DVB_MT352 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 0816344e0206..87c973ac668b 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -107,6 +107,7 @@ config DVB_BUDGET_CI select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE select VIDEO_IR help Support for simple SAA7146 based DVB cards -- cgit v1.2.3 From fb733bf52377a2a91d9f85775a2bd1d877927ea0 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 17 Jun 2008 15:32:08 -0300 Subject: V4L/DVB (8060): Kconfig: MEDIA_TUNER_CUSTOMIZE should be disabled by default The build option, MEDIA_TUNER_CUSTOMIZE, allows us to disable tuner drivers that would have otherwise been selected by default. This is an advanced customization option that should be disabled by default. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 85482960d012..850d5689b14d 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -34,6 +34,7 @@ config MEDIA_TUNER menuconfig MEDIA_TUNER_CUSTOMIZE bool "Customize analog and hybrid tuner modules to build" depends on MEDIA_TUNER + default n help This allows the user to deselect tuner drivers unnecessary for their hardware from the build. Use this option with care -- cgit v1.2.3 From 980b59fb5b4ed4fac91dc57f4e50593faa804f8f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 18 Jun 2008 16:23:52 -0300 Subject: V4L/DVB (8065): Add missing selects at dvb-usb/Kconfig Add missing auto-selects for MEDIA_TUNER_XC2028 and DVB_TDA1004X at dvb-usb/Kconfig. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index bee1bf3c9db1..7847a8320fe7 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -76,6 +76,7 @@ config DVB_USB_DIB0700 select DVB_DIB3000MC select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE select DVB_TUNER_DIB0070 help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The @@ -107,6 +108,7 @@ config DVB_USB_CXUSB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode @@ -121,6 +123,7 @@ config DVB_USB_M920X select DVB_MT352 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE + select DVB_TDA1004X if !DVB_FE_CUSTOMISE help Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. Currently, only devices with a product id of -- cgit v1.2.3 From ccb43646ed574ef0d1ab6ddf73283a3c7caa426d Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 22:56:03 -0300 Subject: V4L/DVB (8072): av7110: Removed some obsolete definitions and one unused variable Removed some obsolete definitions and one unused variable. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110.c | 1 - drivers/media/dvb/ttpci/av7110.h | 1 - drivers/media/dvb/ttpci/av7110_hw.h | 3 --- 3 files changed, 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index f05d43d8b5cf..6d7b9f6a6c75 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -1198,7 +1198,6 @@ static int start_ts_capture(struct av7110 *budget) if (budget->feeding1) return ++budget->feeding1; memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); - budget->tsf = 0xff; budget->ttbp = 0; SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index e494e04eeee8..55f23ddcb994 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h @@ -188,7 +188,6 @@ struct av7110 { struct dvb_net dvb_net1; spinlock_t feedlock1; int feeding1; - u8 tsf; u32 ttbp; unsigned char *grabbing; struct saa7146_pgtable pt; diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index 74d940f75da6..ca99e5c1fc8a 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h @@ -305,7 +305,6 @@ enum av7110_command_type { #define IRQ_STATE (DPRAM_BASE + 0x0F4) #define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6) #define MSGSTATE (DPRAM_BASE + 0x0F8) -#define FILT_STATE (DPRAM_BASE + 0x0FA) #define COMMAND (DPRAM_BASE + 0x0FC) #define COM_BUFF (DPRAM_BASE + 0x100) #define COM_BUFF_SIZE 0x20 @@ -332,8 +331,6 @@ enum av7110_command_type { /* firmware status area */ #define STATUS_BASE (DPRAM_BASE + 0x1FC0) -#define STATUS_SCR (STATUS_BASE + 0x00) -#define STATUS_MODES (STATUS_BASE + 0x04) #define STATUS_LOOPS (STATUS_BASE + 0x08) #define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C) -- cgit v1.2.3 From bbfc4c234e240b67ccd9cdca72d76267bad0dc96 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Thu, 19 Jun 2008 23:36:45 -0300 Subject: V4L/DVB (8076): budget-ci: Support the bundled remote control of the TT DVB-C 1501 Support the bundled remote control of the TT DVB-C 1501 Thanks-to: SG Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/budget-ci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 374100316dc3..060e7c785326 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -227,6 +227,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci) break; case 0x1010: case 0x1017: + case 0x101a: /* for the Technotrend 1500 bundled remote */ ir_input_init(input_dev, &budget_ci->ir.state, IR_TYPE_RC5, ir_codes_tt_1500); -- cgit v1.2.3 From 539a7555b31e65e66fb84c881d07d2bf18c974d0 Mon Sep 17 00:00:00 2001 From: "brandon@ifup.org" Date: Fri, 20 Jun 2008 22:58:53 -0300 Subject: V4L/DVB (8078): Introduce "index" attribute for persistent video4linux device nodes A number of V4L drivers have a mod param to specify their preferred minors. This is because it is often desirable for applications to have a static /dev name for a particular device. However, using minors has several disadvantages: 1) the requested minor may already be taken 2) using a mod param is driver specific 3) it requires every driver to add a param 4) requires configuration by hand This patch introduces an "index" attribute that when combined with udev rules can create static device paths like this: /dev/v4l/by-path/pci-0000\:00\:1d.2-usb-0\:1\:1.0-video0 /dev/v4l/by-path/pci-0000\:00\:1d.2-usb-0\:1\:1.0-video1 /dev/v4l/by-path/pci-0000\:00\:1d.2-usb-0\:1\:1.0-video2 $ ls -la /dev/v4l/by-path/pci-0000\:00\:1d.2-usb-0\:1\:1.0-video0 lrwxrwxrwx 1 root root 12 2008-04-28 00:02 /dev/v4l/by-path/pci-0000:00:1d.2-usb-0:1:1.0-video0 -> ../../video1 These paths are steady across reboots and should be resistant to rearranging across Kernel versions. video_register_device_index is available to drivers to request a specific index number. Signed-off-by: Brandon Philips Signed-off-by: Kees Cook Signed-off-by: Kay Sievers Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 98 +++++++++++++++++++++++++++++++++++++++++- include/media/v4l2-dev.h | 4 ++ 2 files changed, 100 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 6cf6ad7193d9..9c539eb33811 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -372,6 +372,14 @@ EXPORT_SYMBOL(v4l_printk_ioctl); * sysfs stuff */ +static ssize_t show_index(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + return sprintf(buf, "%i\n", vfd->index); +} + static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) { @@ -410,6 +418,7 @@ static void video_release(struct device *cd) static struct device_attribute video_device_attrs[] = { __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(index, S_IRUGO, show_index, NULL), __ATTR_NULL }; @@ -1900,8 +1909,82 @@ out: } EXPORT_SYMBOL(video_ioctl2); +struct index_info { + struct device *dev; + unsigned int used[VIDEO_NUM_DEVICES]; +}; + +static int __fill_index_info(struct device *cd, void *data) +{ + struct index_info *info = data; + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + + if (info->dev == vfd->dev) + info->used[vfd->index] = 1; + + return 0; +} + +/** + * assign_index - assign stream number based on parent device + * @vdev: video_device to assign index number to, vdev->dev should be assigned + * @num: -1 if auto assign, requested number otherwise + * + * + * returns -ENFILE if num is already in use, a free index number if + * successful. + */ +static int get_index(struct video_device *vdev, int num) +{ + struct index_info *info; + int i; + int ret = 0; + + if (num >= VIDEO_NUM_DEVICES) + return -EINVAL; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + info->dev = vdev->dev; + + ret = class_for_each_device(&video_class, info, + __fill_index_info); + + if (ret < 0) + goto out; + + if (num >= 0) { + if (!info->used[num]) + ret = num; + else + ret = -ENFILE; + + goto out; + } + + for (i = 0; i < VIDEO_NUM_DEVICES; i++) { + if (info->used[i]) + continue; + ret = i; + goto out; + } + +out: + kfree(info); + return ret; +} + static const struct file_operations video_fops; +int video_register_device(struct video_device *vfd, int type, int nr) +{ + return video_register_device_index(vfd, type, nr, -1); +} +EXPORT_SYMBOL(video_register_device); + /** * video_register_device - register video4linux devices * @vfd: video device structure we want to register @@ -1927,7 +2010,8 @@ static const struct file_operations video_fops; * %VFL_TYPE_RADIO - A radio card */ -int video_register_device(struct video_device *vfd, int type, int nr) +int video_register_device_index(struct video_device *vfd, int type, int nr, + int index) { int i=0; int base; @@ -1984,6 +2068,16 @@ int video_register_device(struct video_device *vfd, int type, int nr) } video_device[i]=vfd; vfd->minor=i; + + ret = get_index(vfd, index); + if (ret < 0) { + printk(KERN_ERR "%s: get_index failed\n", + __func__); + goto fail_minor; + } + + vfd->index = ret; + mutex_unlock(&videodev_lock); mutex_init(&vfd->lock); @@ -2017,7 +2111,7 @@ fail_minor: mutex_unlock(&videodev_lock); return ret; } -EXPORT_SYMBOL(video_register_device); +EXPORT_SYMBOL(video_register_device_index); /** * video_unregister_device - unregister a video4linux device diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 40b0810a595a..9e6e4f18e948 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -96,6 +96,8 @@ struct video_device int type; /* v4l1 */ int type2; /* v4l2 */ int minor; + /* attribute to diferentiate multiple indexs on one physical device */ + int index; int debug; /* Activates debug level*/ @@ -347,6 +349,8 @@ void *priv; /* Version 2 functions */ extern int video_register_device(struct video_device *vfd, int type, int nr); +int video_register_device_index(struct video_device *vfd, int type, int nr, + int index); void video_unregister_device(struct video_device *); extern int video_ioctl2(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -- cgit v1.2.3 From 3f038d80039f60e4340eaedd13369e0d2c758b80 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 29 May 2008 16:43:54 -0300 Subject: V4L/DVB (8079): ivtv: Convert to video_ioctl2. Based on an initial conversion patch from Douglas Landgraf. Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-controls.c | 196 ++- drivers/media/video/ivtv/ivtv-controls.h | 8 +- drivers/media/video/ivtv/ivtv-driver.c | 10 +- drivers/media/video/ivtv/ivtv-ioctl.c | 2099 ++++++++++++++++-------------- drivers/media/video/ivtv/ivtv-ioctl.h | 9 +- drivers/media/video/ivtv/ivtv-streams.c | 3 +- 6 files changed, 1233 insertions(+), 1092 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index c7e449f6397b..06723bac99c5 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = { NULL }; -static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) + +int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; const char *name; IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); @@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) return 0; } -static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu) +int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct v4l2_queryctrl qctrl; + IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); qctrl.id = qmenu->id; - ivtv_queryctrl(itv, &qctrl); + ivtv_queryctrl(file, fh, &qctrl); return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); } -static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) +int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; s32 v = vctrl->value; IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); @@ -125,8 +130,10 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) return 0; } -static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) +int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); switch (vctrl->id) { @@ -191,119 +198,96 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm return 0; } -int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) +int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct v4l2_control ctrl; - switch (cmd) { - case VIDIOC_QUERYMENU: - IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); - return ivtv_querymenu(itv, arg); - - case VIDIOC_QUERYCTRL: - return ivtv_queryctrl(itv, arg); - - case VIDIOC_S_CTRL: - return ivtv_s_ctrl(itv, arg); - - case VIDIOC_G_CTRL: - return ivtv_g_ctrl(itv, arg); - - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = ivtv_s_ctrl(itv, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } - } - return err; - } - IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - static u32 freqs[3] = { 44100, 48000, 32000 }; - struct cx2341x_mpeg_params p = itv->params; - int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd); - unsigned idx; - - if (err) - return err; - - if (p.video_encoding != itv->params.video_encoding) { - int is_mpeg1 = p.video_encoding == - V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_format fmt; - - /* fix videodecoder resolution */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); - fmt.fmt.pix.height = itv->params.height; - itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); - } - err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); - if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) { - err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt); + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + ctrl.id = c->controls[i].id; + ctrl.value = c->controls[i].value; + err = ivtv_g_ctrl(file, fh, &ctrl); + c->controls[i].value = ctrl.value; + if (err) { + c->error_idx = i; + break; } - itv->params = p; - itv->dualwatch_stereo_mode = p.audio_properties & 0x0300; - idx = p.audio_properties & 0x03; - /* The audio clock of the digitizer must match the codec sample - rate otherwise you get some very strange effects. */ - if (idx < sizeof(freqs)) - ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]); - return err; } - return -EINVAL; + return err; } + IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) + return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS); + return -EINVAL; +} - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = ivtv_g_ctrl(itv, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } +int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_control ctrl; + + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + ctrl.id = c->controls[i].id; + ctrl.value = c->controls[i].value; + err = ivtv_s_ctrl(file, fh, &ctrl); + c->controls[i].value = ctrl.value; + if (err) { + c->error_idx = i; + break; } - return err; } - IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&itv->params, 0, arg, cmd); - return -EINVAL; + return err; } + IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { + static u32 freqs[3] = { 44100, 48000, 32000 }; + struct cx2341x_mpeg_params p = itv->params; + int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS); + unsigned idx; + + if (err) + return err; - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; + if (p.video_encoding != itv->params.video_encoding) { + int is_mpeg1 = p.video_encoding == + V4L2_MPEG_VIDEO_ENCODING_MPEG_1; + struct v4l2_format fmt; - IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd); - return -EINVAL; + /* fix videodecoder resolution */ + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1); + fmt.fmt.pix.height = itv->params.height; + itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt); + } + err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p); + if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) + err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt); + itv->params = p; + itv->dualwatch_stereo_mode = p.audio_properties & 0x0300; + idx = p.audio_properties & 0x03; + /* The audio clock of the digitizer must match the codec sample + rate otherwise you get some very strange effects. */ + if (idx < sizeof(freqs)) + ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]); + return err; } + return -EINVAL; +} - default: - return -EINVAL; - } - return 0; +int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) + return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS); + return -EINVAL; } diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h index bb8a6a5ed2bc..304204be6b0d 100644 --- a/drivers/media/video/ivtv/ivtv-controls.h +++ b/drivers/media/video/ivtv/ivtv-controls.h @@ -21,6 +21,12 @@ #ifndef IVTV_CONTROLS_H #define IVTV_CONTROLS_H -int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg); +int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); +int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); +int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); +int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); +int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); +int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); +int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a); #endif diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 323dd68fa1c6..9e6a64903875 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1262,9 +1262,13 @@ err: int ivtv_init_on_first_open(struct ivtv *itv) { struct v4l2_frequency vf; + /* Needed to call ioctls later */ + struct ivtv_open_id fh; int fw_retry_count = 3; int video_input; + fh.itv = itv; + if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) return -ENXIO; @@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv) video_input = itv->active_input; itv->active_input++; /* Force update of input */ - ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input); + ivtv_s_input(NULL, &fh, video_input); /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code in one place. */ itv->std++; /* Force full standard initialization */ itv->std_out = itv->std; - ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); + ivtv_s_frequency(NULL, &fh, &vf); if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { ivtv_init_mpeg_decoder(itv); } - ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); + ivtv_s_std(NULL, &fh, &itv->tuner_std); /* On a cx23416 this seems to be able to enable DMA to the chip? */ if (!itv->has_cx23415) diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 26cc0f6699fd..49b297e788db 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -373,267 +373,172 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) return 0; } -static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt) +static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) { - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - fmt->fmt.pix.width = itv->main_rect.width; - fmt->fmt.pix.height = itv->main_rect.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { - case IVTV_YUV_MODE_INTERLACED: - fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? - V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; - break; - case IVTV_YUV_MODE_PROGRESSIVE: - fmt->fmt.pix.field = V4L2_FIELD_NONE; - break; - default: - fmt->fmt.pix.field = V4L2_FIELD_ANY; - break; - } - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; - fmt->fmt.pix.bytesperline = 720; - fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w; - fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - 1080 * ((fmt->fmt.pix.height + 31) & ~31); - } else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); - } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; - } - break; - - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - fmt->fmt.pix.width = itv->params.width; - fmt->fmt.pix.height = itv->params.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - if (streamtype == IVTV_ENC_STREAM_TYPE_YUV || - streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); - } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; - } - break; - - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - fmt->fmt.win.chromakey = itv->osd_chroma_key; - fmt->fmt.win.global_alpha = itv->osd_global_alpha; - break; - - case V4L2_BUF_TYPE_VBI_CAPTURE: - fmt->fmt.vbi.sampling_rate = 27000000; - fmt->fmt.vbi.offset = 248; - fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4; - fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - fmt->fmt.vbi.start[0] = itv->vbi.start[0]; - fmt->fmt.vbi.start[1] = itv->vbi.start[1]; - fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count; - break; - - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - { - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) - return -EINVAL; - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); - memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); - if (itv->is_60hz) { - vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; - vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; - } else { - vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; - vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; - } - vbifmt->service_set = ivtv_get_service_set(vbifmt); - break; + if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) + return -EINVAL; + vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; + if (itv->is_60hz) { + vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; + vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; + } else { + vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625; + vbifmt->service_lines[0][16] = V4L2_SLICED_VPS; } + vbifmt->service_set = ivtv_get_service_set(vbifmt); + return 0; +} - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - { - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); - memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); - - if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) { - vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : - V4L2_SLICED_VBI_525; - ivtv_expand_service_set(vbifmt, itv->is_50hz); - break; - } +static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); - vbifmt->service_set = ivtv_get_service_set(vbifmt); - break; - } - case V4L2_BUF_TYPE_VBI_OUTPUT: - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - default: - return -EINVAL; + fmt->fmt.pix.width = itv->params.width; + fmt->fmt.pix.height = itv->params.height; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + if (id->type == IVTV_ENC_STREAM_TYPE_YUV || + id->type == IVTV_DEC_STREAM_TYPE_YUV) { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + fmt->fmt.pix.sizeimage = + fmt->fmt.pix.height * fmt->fmt.pix.width + + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + } else { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + fmt->fmt.pix.sizeimage = 128 * 1024; } return 0; } -static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, - struct v4l2_format *fmt, int set_fmt) +static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct yuv_playback_info *yi = &itv->yuv_info; - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - u16 set; + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + fmt->fmt.vbi.sampling_rate = 27000000; + fmt->fmt.vbi.offset = 248; + fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4; + fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; + fmt->fmt.vbi.start[0] = itv->vbi.start[0]; + fmt->fmt.vbi.start[1] = itv->vbi.start[1]; + fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count; + return 0; +} - if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { - struct v4l2_rect r; - int field; +static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - field = fmt->fmt.pix.field; - r.top = 0; - r.left = 0; - r.width = fmt->fmt.pix.width; - r.height = fmt->fmt.pix.height; - ivtv_get_fmt(itv, streamtype, fmt); - fmt->fmt.pix.width = r.width; - fmt->fmt.pix.height = r.height; - if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix.field = field; - if (fmt->fmt.pix.width < 2) - fmt->fmt.pix.width = 2; - if (fmt->fmt.pix.width > 720) - fmt->fmt.pix.width = 720; - if (fmt->fmt.pix.height < 2) - fmt->fmt.pix.height = 2; - if (fmt->fmt.pix.height > 576) - fmt->fmt.pix.height = 576; - } - if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - /* Return now if we already have some frame data */ - if (yi->stream_size) - return -EBUSY; + vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - yi->v4l2_src_w = r.width; - yi->v4l2_src_h = r.height; + if (id->type == IVTV_DEC_STREAM_TYPE_VBI) { + vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 : + V4L2_SLICED_VBI_525; + ivtv_expand_service_set(vbifmt, itv->is_50hz); + return 0; + } - switch (field) { - case V4L2_FIELD_NONE: - yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; - break; - case V4L2_FIELD_ANY: - yi->lace_mode = IVTV_YUV_MODE_AUTO; - break; - case V4L2_FIELD_INTERLACED_BT: - yi->lace_mode = - IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD; - break; - case V4L2_FIELD_INTERLACED_TB: - default: - yi->lace_mode = IVTV_YUV_MODE_INTERLACED; - break; - } - yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1; + itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); + vbifmt->service_set = ivtv_get_service_set(vbifmt); + return 0; +} - if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) - itv->dma_data_req_size = - 1080 * ((yi->v4l2_src_h + 31) & ~31); +static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - /* Force update of yuv registers */ - yi->yuv_forced_update = 1; - return 0; + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + fmt->fmt.pix.width = itv->main_rect.width; + fmt->fmt.pix.height = itv->main_rect.height; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + if (id->type == IVTV_DEC_STREAM_TYPE_YUV) { + switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { + case IVTV_YUV_MODE_INTERLACED: + fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? + V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; + break; + case IVTV_YUV_MODE_PROGRESSIVE: + fmt->fmt.pix.field = V4L2_FIELD_NONE; + break; + default: + fmt->fmt.pix.field = V4L2_FIELD_ANY; + break; } - return 0; + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + fmt->fmt.pix.bytesperline = 720; + fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w; + fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + fmt->fmt.pix.sizeimage = + 1080 * ((fmt->fmt.pix.height + 31) & ~31); + } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + fmt->fmt.pix.sizeimage = + fmt->fmt.pix.height * fmt->fmt.pix.width + + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + } else { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + fmt->fmt.pix.sizeimage = 128 * 1024; } + return 0; +} - if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) { - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - if (set_fmt) { - itv->osd_chroma_key = fmt->fmt.win.chromakey; - itv->osd_global_alpha = fmt->fmt.win.global_alpha; - ivtv_set_osd_alpha(itv); - } - return 0; - } +static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - /* set window size */ - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - struct cx2341x_mpeg_params *p = &itv->params; - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; - - if (w > 720) w = 720; - else if (w < 1) w = 1; - if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480); - else if (h < 2) h = 2; - ivtv_get_fmt(itv, streamtype, fmt); - fmt->fmt.pix.width = w; - fmt->fmt.pix.height = h; - - if (!set_fmt || (p->width == w && p->height == h)) - return 0; - if (atomic_read(&itv->capturing) > 0) - return -EBUSY; + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + fmt->fmt.win.chromakey = itv->osd_chroma_key; + fmt->fmt.win.global_alpha = itv->osd_global_alpha; + return 0; +} - p->width = w; - p->height = h; - if (w != 720 || h != (itv->is_50hz ? 576 : 480)) - p->video_temporal_filter = 0; - else - p->video_temporal_filter = 8; - if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) - fmt->fmt.pix.width /= 2; - itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); - return ivtv_get_fmt(itv, streamtype, fmt); - } +static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) +{ + return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); +} - /* set raw VBI format */ - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - if (set_fmt && atomic_read(&itv->capturing) > 0) { - return -EBUSY; - } - if (set_fmt) { - itv->vbi.sliced_in->service_set = 0; - itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); - } - return ivtv_get_fmt(itv, streamtype, fmt); - } +static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + int w = fmt->fmt.pix.width; + int h = fmt->fmt.pix.height; + + w = min(w, 720); + w = max(w, 1); + h = min(h, itv->is_50hz ? 576 : 480); + h = max(h, 2); + ivtv_g_fmt_vid_cap(file, fh, fmt); + fmt->fmt.pix.width = w; + fmt->fmt.pix.height = h; + return 0; +} - /* set sliced VBI output - In principle the user could request that only certain - VBI types are output and that the others are ignored. - I.e., suppress CC in the even fields or only output - WSS and no VPS. Currently though there is no choice. */ - if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) - return ivtv_get_fmt(itv, streamtype, fmt); +static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + return ivtv_g_fmt_vbi_cap(file, fh, fmt); +} - /* any else but sliced VBI capture is an error */ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; +static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) - return ivtv_get_fmt(itv, streamtype, fmt); + if (id->type == IVTV_DEC_STREAM_TYPE_VBI) + return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt); /* set sliced VBI capture format */ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; @@ -641,777 +546,997 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, if (vbifmt->service_set) ivtv_expand_service_set(vbifmt, itv->is_50hz); - set = check_service_set(vbifmt, itv->is_50hz); + check_service_set(vbifmt, itv->is_50hz); vbifmt->service_set = ivtv_get_service_set(vbifmt); + return 0; +} + +static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv_open_id *id = fh; + s32 w, h; + int field; + int ret; + + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; + field = fmt->fmt.pix.field; + ret = ivtv_g_fmt_vid_out(file, fh, fmt); + fmt->fmt.pix.width = w; + fmt->fmt.pix.height = h; + if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { + fmt->fmt.pix.field = field; + if (fmt->fmt.pix.width < 2) + fmt->fmt.pix.width = 2; + if (fmt->fmt.pix.width > 720) + fmt->fmt.pix.width = 720; + if (fmt->fmt.pix.height < 2) + fmt->fmt.pix.height = 2; + if (fmt->fmt.pix.height > 576) + fmt->fmt.pix.height = 576; + } + return ret; +} + +static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - if (!set_fmt) + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + return 0; +} + +static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) +{ + return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt); +} + +static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + struct cx2341x_mpeg_params *p = &itv->params; + int w = fmt->fmt.pix.width; + int h = fmt->fmt.pix.height; + int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); + + if (ret) + return ret; + + if (p->width == w && p->height == h) return 0; - if (set == 0) + + if (atomic_read(&itv->capturing) > 0) + return -EBUSY; + + p->width = w; + p->height = h; + if (w != 720 || h != (itv->is_50hz ? 576 : 480)) + p->video_temporal_filter = 0; + else + p->video_temporal_filter = 8; + if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) + fmt->fmt.pix.width /= 2; + itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); + return ivtv_g_fmt_vid_cap(file, fh, fmt); +} + +static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + itv->vbi.sliced_in->service_set = 0; + itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); + return ivtv_g_fmt_vbi_cap(file, fh, fmt); +} + +static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) +{ + struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt); + + if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) + return ret; + + if (check_service_set(vbifmt, itv->is_50hz) == 0) return -EINVAL; - if (atomic_read(&itv->capturing) > 0) { + if (atomic_read(&itv->capturing) > 0) return -EBUSY; - } itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); return 0; } -static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) +static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { - struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; + struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; - struct v4l2_register *reg = arg; + struct yuv_playback_info *yi = &itv->yuv_info; + int ret = ivtv_try_fmt_vid_out(file, fh, fmt); - switch (cmd) { - /* ioctls to allow direct access to the encoder registers for testing */ - case VIDIOC_DBG_G_REGISTER: - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) - return ivtv_itvc(itv, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); - return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); - - case VIDIOC_DBG_S_REGISTER: - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) - return ivtv_itvc(itv, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); - return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); - - case VIDIOC_G_CHIP_IDENT: { - struct v4l2_chip_ident *chip = arg; - - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (reg->match_type == V4L2_CHIP_MATCH_HOST) { - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) - chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; - return 0; - } - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return ivtv_i2c_id(itv, reg->match_chip, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR) - return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg); - return -EINVAL; - } + if (ret) + return ret; - case VIDIOC_INT_S_AUDIO_ROUTING: { - struct v4l2_routing *route = arg; + if (id->type != IVTV_DEC_STREAM_TYPE_YUV) + return 0; - ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); - break; - } + /* Return now if we already have some frame data */ + if (yi->stream_size) + return -EBUSY; - case VIDIOC_INT_RESET: { - u32 val = *(u32 *)arg; + yi->v4l2_src_w = fmt->fmt.pix.width; + yi->v4l2_src_h = fmt->fmt.pix.height; - if ((val == 0 && itv->options.newi2c) || (val & 0x01)) { - ivtv_reset_ir_gpio(itv); - } - if (val & 0x02) { - itv->video_dec_func(itv, cmd, NULL); - } + switch (fmt->fmt.pix.field) { + case V4L2_FIELD_NONE: + yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; break; - } - + case V4L2_FIELD_ANY: + yi->lace_mode = IVTV_YUV_MODE_AUTO; + break; + case V4L2_FIELD_INTERLACED_BT: + yi->lace_mode = + IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD; + break; + case V4L2_FIELD_INTERLACED_TB: default: - return -EINVAL; + yi->lace_mode = IVTV_YUV_MODE_INTERLACED; + break; } + yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1; + + if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) + itv->dma_data_req_size = + 1080 * ((yi->v4l2_src_h + 31) & ~31); + + /* Force update of yuv registers */ + yi->yuv_forced_update = 1; return 0; } -int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) +static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) { - struct ivtv_open_id *id = NULL; - struct yuv_playback_info *yi = &itv->yuv_info; - u32 data[CX2341X_MBOX_MAX_DATA]; - int streamtype = 0; + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt); - if (filp) { - id = (struct ivtv_open_id *)filp->private_data; - streamtype = id->type; + if (ret == 0) { + itv->osd_chroma_key = fmt->fmt.win.chromakey; + itv->osd_global_alpha = fmt->fmt.win.global_alpha; + ivtv_set_osd_alpha(itv); } + return ret; +} - switch (cmd) { - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p = arg; +static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - *p = v4l2_prio_max(&itv->prio); - break; + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match_type == V4L2_CHIP_MATCH_HOST) { + if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) + chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416; + return 0; } + if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); + if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) + return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip); + return -EINVAL; +} - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *prio = arg; +static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - return v4l2_prio_change(&itv->prio, &id->prio, *prio); - } + if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); + if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); + return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg); +} + +static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_QUERYCAP:{ - struct v4l2_capability *vcap = arg; + if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); + if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); + return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); +} - memset(vcap, 0, sizeof(*vcap)); - strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); - strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); - strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); - vcap->version = IVTV_DRIVER_VERSION; /* version */ - vcap->capabilities = itv->v4l2_cap; /* capabilities */ +static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - /* reserved.. must set to 0! */ - vcap->reserved[0] = vcap->reserved[1] = - vcap->reserved[2] = vcap->reserved[3] = 0; - break; - } + *p = v4l2_prio_max(&itv->prio); - case VIDIOC_ENUMAUDIO:{ - struct v4l2_audio *vin = arg; + return 0; +} - return ivtv_get_audio_input(itv, vin->index, vin); - } +static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - case VIDIOC_G_AUDIO:{ - struct v4l2_audio *vin = arg; + return v4l2_prio_change(&itv->prio, &id->prio, prio); +} - vin->index = itv->audio_input; - return ivtv_get_audio_input(itv, vin->index, vin); - } +static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + memset(vcap, 0, sizeof(*vcap)); + strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); + strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); + strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); + vcap->version = IVTV_DRIVER_VERSION; /* version */ + vcap->capabilities = itv->v4l2_cap; /* capabilities */ + /* reserved.. must set to 0! */ + vcap->reserved[0] = vcap->reserved[1] = + vcap->reserved[2] = vcap->reserved[3] = 0; + return 0; +} - case VIDIOC_S_AUDIO:{ - struct v4l2_audio *vout = arg; +static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - if (vout->index >= itv->nof_audio_inputs) - return -EINVAL; - itv->audio_input = vout->index; - ivtv_audio_set_io(itv); - break; - } + return ivtv_get_audio_input(itv, vin->index, vin); +} + +static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_ENUMAUDOUT:{ - struct v4l2_audioout *vin = arg; + vin->index = itv->audio_input; + return ivtv_get_audio_input(itv, vin->index, vin); +} - /* set it to defaults from our table */ - return ivtv_get_audio_output(itv, vin->index, vin); - } +static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_G_AUDOUT:{ - struct v4l2_audioout *vin = arg; + if (vout->index >= itv->nof_audio_inputs) + return -EINVAL; - vin->index = 0; - return ivtv_get_audio_output(itv, vin->index, vin); - } + itv->audio_input = vout->index; + ivtv_audio_set_io(itv); - case VIDIOC_S_AUDOUT:{ - struct v4l2_audioout *vout = arg; + return 0; +} - return ivtv_get_audio_output(itv, vout->index, vout); - } +static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_ENUMINPUT:{ - struct v4l2_input *vin = arg; + /* set it to defaults from our table */ + return ivtv_get_audio_output(itv, vin->index, vin); +} - /* set it to defaults from our table */ - return ivtv_get_input(itv, vin->index, vin); - } +static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_ENUMOUTPUT:{ - struct v4l2_output *vout = arg; + vin->index = 0; + return ivtv_get_audio_output(itv, vin->index, vin); +} - return ivtv_get_output(itv, vout->index, vout); - } +static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: { - struct v4l2_format *fmt = arg; + return ivtv_get_audio_output(itv, vout->index, vout); +} - return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT); - } +static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_G_FMT: { - struct v4l2_format *fmt = arg; - int type = fmt->type; + /* set it to defaults from our table */ + return ivtv_get_input(itv, vin->index, vin); +} - memset(fmt, 0, sizeof(*fmt)); - fmt->type = type; - return ivtv_get_fmt(itv, id->type, fmt); - } +static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - case VIDIOC_CROPCAP: { - struct v4l2_cropcap *cropcap = arg; + return ivtv_get_output(itv, vout->index, vout); +} - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) - return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - cropcap->bounds.height = itv->is_50hz ? 576 : 480; - cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; - } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - if (yi->track_osd) { - cropcap->bounds.width = yi->osd_full_w; - cropcap->bounds.height = yi->osd_full_h; - } else { - cropcap->bounds.width = 720; - cropcap->bounds.height = - itv->is_out_50hz ? 576 : 480; - } - cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; +static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + struct yuv_playback_info *yi = &itv->yuv_info; + int streamtype; + + streamtype = id->type; + + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { + cropcap->bounds.height = itv->is_50hz ? 576 : 480; + cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; + cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; + } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { + if (yi->track_osd) { + cropcap->bounds.width = yi->osd_full_w; + cropcap->bounds.height = yi->osd_full_h; } else { - cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; - cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; + cropcap->bounds.width = 720; + cropcap->bounds.height = + itv->is_out_50hz ? 576 : 480; } - cropcap->defrect = cropcap->bounds; - return 0; + cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; + cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; + } else { + cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; + cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; + cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; } + cropcap->defrect = cropcap->bounds; + return 0; +} + +static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + struct yuv_playback_info *yi = &itv->yuv_info; + int streamtype; - case VIDIOC_S_CROP: { - struct v4l2_crop *crop = arg; + streamtype = id->type; - if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { - if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { - yi->main_rect = crop->c; + if (ivtv_debug & IVTV_DBGFLG_IOCTL) { + printk(KERN_INFO "ivtv%d ioctl: ", itv->num); + /* Should be replaced */ + /* v4l_printk_ioctl(VIDIOC_S_CROP); */ + } + + if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { + if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { + yi->main_rect = crop->c; + return 0; + } else { + if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, + crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { + itv->main_rect = crop->c; return 0; - } else { - if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, - crop->c.width, crop->c.height, crop->c.left, crop->c.top)) { - itv->main_rect = crop->c; - return 0; - } } - return -EINVAL; } return -EINVAL; } + return -EINVAL; +} - case VIDIOC_G_CROP: { - struct v4l2_crop *crop = arg; +static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + struct yuv_playback_info *yi = &itv->yuv_info; + int streamtype; - if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && - (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { - if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) - crop->c = yi->main_rect; - else - crop->c = itv->main_rect; - return 0; + streamtype = id->type; + + if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && + (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { + if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) + crop->c = yi->main_rect; + else + crop->c = itv->main_rect; + return 0; + } + return -EINVAL; +} + +static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) +{ + static struct v4l2_fmtdesc formats[] = { + { 0, 0, 0, + "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, + { 0, 0, 0, 0 } + }, + { 1, 0, V4L2_FMT_FLAG_COMPRESSED, + "MPEG", V4L2_PIX_FMT_MPEG, + { 0, 0, 0, 0 } } + }; + enum v4l2_buf_type type = fmt->type; + + if (fmt->index > 1) return -EINVAL; - } - case VIDIOC_ENUM_FMT: { - static struct v4l2_fmtdesc formats[] = { - { 0, 0, 0, - "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, - { 0, 0, 0, 0 } - }, - { 1, 0, V4L2_FMT_FLAG_COMPRESSED, - "MPEG", V4L2_PIX_FMT_MPEG, - { 0, 0, 0, 0 } - } - }; - struct v4l2_fmtdesc *fmt = arg; - enum v4l2_buf_type type = fmt->type; + *fmt = formats[fmt->index]; + fmt->type = type; + return 0; +} - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - break; - default: - return -EINVAL; +static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + static struct v4l2_fmtdesc formats[] = { + { 0, 0, 0, + "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, + { 0, 0, 0, 0 } + }, + { 1, 0, V4L2_FMT_FLAG_COMPRESSED, + "MPEG", V4L2_PIX_FMT_MPEG, + { 0, 0, 0, 0 } } - if (fmt->index > 1) - return -EINVAL; - *fmt = formats[fmt->index]; - fmt->type = type; + }; + enum v4l2_buf_type type = fmt->type; + + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + + if (fmt->index > 1) + return -EINVAL; + + *fmt = formats[fmt->index]; + fmt->type = type; + + return 0; +} + +static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + *i = itv->active_input; + + return 0; +} + +int ivtv_s_input(struct file *file, void *fh, unsigned int inp) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + if (inp < 0 || inp >= itv->nof_inputs) + return -EINVAL; + + if (inp == itv->active_input) { + IVTV_DEBUG_INFO("Input unchanged\n"); return 0; } - case VIDIOC_G_INPUT:{ - *(int *)arg = itv->active_input; - break; + if (atomic_read(&itv->capturing) > 0) { + return -EBUSY; } - case VIDIOC_S_INPUT:{ - int inp = *(int *)arg; + IVTV_DEBUG_INFO("Changing input from %d to %d\n", + itv->active_input, inp); - if (inp < 0 || inp >= itv->nof_inputs) - return -EINVAL; + itv->active_input = inp; + /* Set the audio input to whatever is appropriate for the + input type. */ + itv->audio_input = itv->card->video_inputs[inp].audio_index; - if (inp == itv->active_input) { - IVTV_DEBUG_INFO("Input unchanged\n"); - break; - } - if (atomic_read(&itv->capturing) > 0) { - return -EBUSY; - } - IVTV_DEBUG_INFO("Changing input from %d to %d\n", - itv->active_input, inp); + /* prevent others from messing with the streams until + we're finished changing inputs. */ + ivtv_mute(itv); + ivtv_video_set_io(itv); + ivtv_audio_set_io(itv); + ivtv_unmute(itv); + + return 0; +} - itv->active_input = inp; - /* Set the audio input to whatever is appropriate for the - input type. */ - itv->audio_input = itv->card->video_inputs[inp].audio_index; +static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - /* prevent others from messing with the streams until - we're finished changing inputs. */ - ivtv_mute(itv); - ivtv_video_set_io(itv); - ivtv_audio_set_io(itv); - ivtv_unmute(itv); - break; + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) + return -EINVAL; + + *i = itv->active_output; + + return 0; +} + +static int ivtv_s_output(struct file *file, void *fh, unsigned int outp) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_routing route; + + if (outp >= itv->card->nof_outputs) + return -EINVAL; + + if (outp == itv->active_output) { + IVTV_DEBUG_INFO("Output unchanged\n"); + return 0; } + IVTV_DEBUG_INFO("Changing output from %d to %d\n", + itv->active_output, outp); - case VIDIOC_G_OUTPUT:{ - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) - return -EINVAL; - *(int *)arg = itv->active_output; - break; + itv->active_output = outp; + route.input = SAA7127_INPUT_TYPE_NORMAL; + route.output = itv->card->video_outputs[outp].video_output; + ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); + + return 0; +} + +static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + if (vf->tuner != 0) + return -EINVAL; + + ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf); + return 0; +} + +int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + if (vf->tuner != 0) + return -EINVAL; + + ivtv_mute(itv); + IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); + ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf); + ivtv_unmute(itv); + return 0; +} + +static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + *std = itv->std; + return 0; +} + +int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct yuv_playback_info *yi = &itv->yuv_info; + + if ((*std & V4L2_STD_ALL) == 0) + return -EINVAL; + + if (*std == itv->std) + return 0; + + if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || + atomic_read(&itv->capturing) > 0 || + atomic_read(&itv->decoding) > 0) { + /* Switching standard would turn off the radio or mess + with already running streams, prevent that by + returning EBUSY. */ + return -EBUSY; + } + + itv->std = *std; + itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; + itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; + itv->params.width = 720; + itv->params.height = itv->is_50hz ? 576 : 480; + itv->vbi.count = itv->is_50hz ? 18 : 12; + itv->vbi.start[0] = itv->is_50hz ? 6 : 10; + itv->vbi.start[1] = itv->is_50hz ? 318 : 273; + + if (itv->hw_flags & IVTV_HW_CX25840) + itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; + + IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); + + /* Tuner */ + ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); + + if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { + /* set display standard */ + itv->std_out = *std; + itv->is_out_60hz = itv->is_60hz; + itv->is_out_50hz = itv->is_50hz; + ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); + ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); + itv->main_rect.left = itv->main_rect.top = 0; + itv->main_rect.width = 720; + itv->main_rect.height = itv->params.height; + ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, + 720, itv->main_rect.height, 0, 0); + yi->main_rect = itv->main_rect; + if (!itv->osd_info) { + yi->osd_full_w = 720; + yi->osd_full_h = itv->is_out_50hz ? 576 : 480; + } + } + return 0; +} + +static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + + if (vt->index != 0) + return -EINVAL; + + ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); + + return 0; +} + +static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + + if (vt->index != 0) + return -EINVAL; + + memset(vt, 0, sizeof(*vt)); + ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); + + if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { + strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); + vt->type = V4L2_TUNER_RADIO; + } else { + strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); + vt->type = V4L2_TUNER_ANALOG_TV; } - case VIDIOC_S_OUTPUT:{ - int outp = *(int *)arg; - struct v4l2_routing route; + return 0; +} - if (outp >= itv->card->nof_outputs) +static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; + int f, l; + enum v4l2_buf_type type = cap->type; + + memset(cap, 0, sizeof(*cap)); + cap->type = type; + if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { + for (f = 0; f < 2; f++) { + for (l = 0; l < 24; l++) { + if (valid_service_line(f, l, itv->is_50hz)) + cap->service_lines[f][l] = set; + } + } + return 0; + } + if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { + if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) return -EINVAL; - - if (outp == itv->active_output) { - IVTV_DEBUG_INFO("Output unchanged\n"); - break; + if (itv->is_60hz) { + cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; + cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; + } else { + cap->service_lines[0][23] = V4L2_SLICED_WSS_625; + cap->service_lines[0][16] = V4L2_SLICED_VPS; } - IVTV_DEBUG_INFO("Changing output from %d to %d\n", - itv->active_output, outp); - - itv->active_output = outp; - route.input = SAA7127_INPUT_TYPE_NORMAL; - route.output = itv->card->video_outputs[outp].video_output; - ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); - break; + return 0; } + return -EINVAL; +} - case VIDIOC_G_FREQUENCY:{ - struct v4l2_frequency *vf = arg; +static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_enc_idx_entry *e = idx->entry; + int entries; + int i; - if (vf->tuner != 0) - return -EINVAL; - ivtv_call_i2c_clients(itv, cmd, arg); - break; + entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % + IVTV_MAX_PGM_INDEX; + if (entries > V4L2_ENC_IDX_ENTRIES) + entries = V4L2_ENC_IDX_ENTRIES; + idx->entries = 0; + for (i = 0; i < entries; i++) { + *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; + if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { + idx->entries++; + e++; + } } + itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; + return 0; +} - case VIDIOC_S_FREQUENCY:{ - struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; +static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - if (vf.tuner != 0) - return -EINVAL; + memset(&enc->raw, 0, sizeof(enc->raw)); - ivtv_mute(itv); - IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency); - ivtv_call_i2c_clients(itv, cmd, &vf); - ivtv_unmute(itv); - break; - } + switch (enc->cmd) { + case V4L2_ENC_CMD_START: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); + enc->flags = 0; + return ivtv_start_capture(id); - case VIDIOC_ENUMSTD:{ - struct v4l2_standard *vs = arg; - int idx = vs->index; + case V4L2_ENC_CMD_STOP: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); + enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; + ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); + return 0; - if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) - return -EINVAL; + case V4L2_ENC_CMD_PAUSE: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); + enc->flags = 0; - *vs = (enum_stds[idx].std & V4L2_STD_525_60) ? - ivtv_std_60hz : ivtv_std_50hz; - vs->index = idx; - vs->id = enum_stds[idx].std; - strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name)); - break; - } + if (!atomic_read(&itv->capturing)) + return -EPERM; + if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) + return 0; - case VIDIOC_G_STD:{ - *(v4l2_std_id *) arg = itv->std; + ivtv_mute(itv); + ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); break; - } - - case VIDIOC_S_STD: { - v4l2_std_id std = *(v4l2_std_id *) arg; - if ((std & V4L2_STD_ALL) == 0) - return -EINVAL; + case V4L2_ENC_CMD_RESUME: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); + enc->flags = 0; - if (std == itv->std) - break; + if (!atomic_read(&itv->capturing)) + return -EPERM; - if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || - atomic_read(&itv->capturing) > 0 || - atomic_read(&itv->decoding) > 0) { - /* Switching standard would turn off the radio or mess - with already running streams, prevent that by - returning EBUSY. */ - return -EBUSY; - } + if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) + return 0; - itv->std = std; - itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0; - itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; - itv->params.width = 720; - itv->params.height = itv->is_50hz ? 576 : 480; - itv->vbi.count = itv->is_50hz ? 18 : 12; - itv->vbi.start[0] = itv->is_50hz ? 6 : 10; - itv->vbi.start[1] = itv->is_50hz ? 318 : 273; - if (itv->hw_flags & IVTV_HW_CX25840) { - itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; - } - IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); - - /* Tuner */ - ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); - - if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { - /* set display standard */ - itv->std_out = std; - itv->is_out_60hz = itv->is_60hz; - itv->is_out_50hz = itv->is_50hz; - ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); - ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); - itv->main_rect.left = itv->main_rect.top = 0; - itv->main_rect.width = 720; - itv->main_rect.height = itv->params.height; - ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, - 720, itv->main_rect.height, 0, 0); - yi->main_rect = itv->main_rect; - if (!itv->osd_info) { - yi->osd_full_w = 720; - yi->osd_full_h = itv->is_out_50hz ? 576 : 480; - } - } + ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); + ivtv_unmute(itv); break; + default: + IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); + return -EINVAL; } - case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ - struct v4l2_tuner *vt = arg; + return 0; +} - if (vt->index != 0) - return -EINVAL; +static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); - break; - } + memset(&enc->raw, 0, sizeof(enc->raw)); - case VIDIOC_G_TUNER: { - struct v4l2_tuner *vt = arg; + switch (enc->cmd) { + case V4L2_ENC_CMD_START: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); + enc->flags = 0; + return 0; - if (vt->index != 0) - return -EINVAL; + case V4L2_ENC_CMD_STOP: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); + enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; + return 0; - memset(vt, 0, sizeof(*vt)); - ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); + case V4L2_ENC_CMD_PAUSE: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); + enc->flags = 0; + return 0; - if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { - strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_RADIO; - } else { - strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_ANALOG_TV; - } - break; + case V4L2_ENC_CMD_RESUME: + IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); + enc->flags = 0; + return 0; + default: + IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); + return -EINVAL; } +} - case VIDIOC_G_SLICED_VBI_CAP: { - struct v4l2_sliced_vbi_cap *cap = arg; - int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; - int f, l; - enum v4l2_buf_type type = cap->type; - - memset(cap, 0, sizeof(*cap)); - cap->type = type; - if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - if (valid_service_line(f, l, itv->is_50hz)) { - cap->service_lines[f][l] = set; - } - } - } - return 0; - } - if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { - if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) - return -EINVAL; - if (itv->is_60hz) { - cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; - cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; - } else { - cap->service_lines[0][23] = V4L2_SLICED_WSS_625; - cap->service_lines[0][16] = V4L2_SLICED_VPS; - } - return 0; - } +static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + u32 data[CX2341X_MBOX_MAX_DATA]; + struct yuv_playback_info *yi = &itv->yuv_info; + + int pixfmt; + static u32 pixel_format[16] = { + V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ + V4L2_PIX_FMT_RGB565, + V4L2_PIX_FMT_RGB555, + V4L2_PIX_FMT_RGB444, + V4L2_PIX_FMT_RGB32, + 0, + 0, + 0, + V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ + V4L2_PIX_FMT_YUV565, + V4L2_PIX_FMT_YUV555, + V4L2_PIX_FMT_YUV444, + V4L2_PIX_FMT_YUV32, + 0, + 0, + 0, + }; + + memset(fb, 0, sizeof(*fb)); + + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; - } - case VIDIOC_G_ENC_INDEX: { - struct v4l2_enc_idx *idx = arg; - struct v4l2_enc_idx_entry *e = idx->entry; - int entries; - int i; - - entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % - IVTV_MAX_PGM_INDEX; - if (entries > V4L2_ENC_IDX_ENTRIES) - entries = V4L2_ENC_IDX_ENTRIES; - idx->entries = 0; - for (i = 0; i < entries; i++) { - *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; - if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { - idx->entries++; - e++; - } - } - itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX; - break; - } + fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | + V4L2_FBUF_CAP_GLOBAL_ALPHA; - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: { - struct v4l2_encoder_cmd *enc = arg; - int try = cmd == VIDIOC_TRY_ENCODER_CMD; - - memset(&enc->raw, 0, sizeof(enc->raw)); - switch (enc->cmd) { - case V4L2_ENC_CMD_START: - IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); - enc->flags = 0; - if (try) - return 0; - return ivtv_start_capture(id); + ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); + data[0] |= (read_reg(0x2a00) >> 7) & 0x40; + pixfmt = (data[0] >> 3) & 0xf; - case V4L2_ENC_CMD_STOP: - IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); - enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; - if (try) - return 0; - ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); - return 0; + fb->fmt.pixelformat = pixel_format[pixfmt]; + fb->fmt.width = itv->osd_rect.width; + fb->fmt.height = itv->osd_rect.height; + fb->base = (void *)itv->osd_video_pbase; - case V4L2_ENC_CMD_PAUSE: - IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); - enc->flags = 0; - if (try) - return 0; - if (!atomic_read(&itv->capturing)) - return -EPERM; - if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) - return 0; - ivtv_mute(itv); - ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0); - break; + if (itv->osd_chroma_key_state) + fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; - case V4L2_ENC_CMD_RESUME: - IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); - enc->flags = 0; - if (try) - return 0; - if (!atomic_read(&itv->capturing)) - return -EPERM; - if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) - return 0; - ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); - ivtv_unmute(itv); - break; - default: - IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); - return -EINVAL; - } - break; - } + if (itv->osd_global_alpha_state) + fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; - case VIDIOC_G_FBUF: { - struct v4l2_framebuffer *fb = arg; - int pixfmt; - static u32 pixel_format[16] = { - V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */ - V4L2_PIX_FMT_RGB565, - V4L2_PIX_FMT_RGB555, - V4L2_PIX_FMT_RGB444, - V4L2_PIX_FMT_RGB32, - 0, - 0, - 0, - V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */ - V4L2_PIX_FMT_YUV565, - V4L2_PIX_FMT_YUV555, - V4L2_PIX_FMT_YUV444, - V4L2_PIX_FMT_YUV32, - 0, - 0, - 0, - }; + pixfmt &= 7; - memset(fb, 0, sizeof(*fb)); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; - fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | - V4L2_FBUF_CAP_GLOBAL_ALPHA; - ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); - data[0] |= (read_reg(0x2a00) >> 7) & 0x40; - pixfmt = (data[0] >> 3) & 0xf; - fb->fmt.pixelformat = pixel_format[pixfmt]; - fb->fmt.width = itv->osd_rect.width; - fb->fmt.height = itv->osd_rect.height; - fb->base = (void *)itv->osd_video_pbase; - if (itv->osd_chroma_key_state) - fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; - if (itv->osd_global_alpha_state) - fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; - pixfmt &= 7; - /* no local alpha for RGB565 or unknown formats */ - if (pixfmt == 1 || pixfmt > 4) - break; + /* no local alpha for RGB565 or unknown formats */ + if (pixfmt == 1 || pixfmt > 4) + return 0; + + /* 16-bit formats have inverted local alpha */ + if (pixfmt == 2 || pixfmt == 3) + fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; + else + fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; + + if (itv->osd_local_alpha_state) { /* 16-bit formats have inverted local alpha */ if (pixfmt == 2 || pixfmt == 3) - fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; + fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; else - fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; - if (itv->osd_local_alpha_state) { - /* 16-bit formats have inverted local alpha */ - if (pixfmt == 2 || pixfmt == 3) - fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; - else - fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; - } - if (yi->track_osd) - fb->flags |= V4L2_FBUF_FLAG_OVERLAY; - break; + fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } + if (yi->track_osd) + fb->flags |= V4L2_FBUF_FLAG_OVERLAY; + + return 0; +} - case VIDIOC_S_FBUF: { - struct v4l2_framebuffer *fb = arg; +static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; + struct yuv_playback_info *yi = &itv->yuv_info; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; - itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; - itv->osd_local_alpha_state = - (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; - itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; - ivtv_set_osd_alpha(itv); - yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; - break; - } + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -EINVAL; - case VIDIOC_OVERLAY: { - int *on = arg; + itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; + itv->osd_local_alpha_state = + (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; + itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + ivtv_set_osd_alpha(itv); + yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) - return -EINVAL; - ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0); - break; - } + return 0; +} + +static int ivtv_overlay(struct file *file, void *fh, unsigned int on) +{ + struct ivtv_open_id *id = fh; + struct ivtv *itv = id->itv; - case VIDIOC_LOG_STATUS: - { - int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; - struct v4l2_input vidin; - struct v4l2_audio audin; - int i; + if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) + return -EINVAL; - IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); - IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); - if (itv->hw_flags & IVTV_HW_TVEEPROM) { - struct tveeprom tv; + ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0); - ivtv_read_eeprom(itv, &tv); - } - ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); - ivtv_get_input(itv, itv->active_input, &vidin); - ivtv_get_audio_input(itv, itv->audio_input, &audin); - IVTV_INFO("Video Input: %s\n", vidin.name); - IVTV_INFO("Audio Input: %s%s\n", audin.name, - (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); - if (has_output) { - struct v4l2_output vidout; - struct v4l2_audioout audout; - int mode = itv->output_mode; - static const char * const output_modes[5] = { - "None", - "MPEG Streaming", - "YUV Streaming", - "YUV Frames", - "Passthrough", - }; - static const char * const audio_modes[5] = { - "Stereo", - "Left", - "Right", - "Mono", - "Swapped" - }; - static const char * const alpha_mode[4] = { - "None", - "Global", - "Local", - "Global and Local" - }; - static const char * const pixel_format[16] = { - "ARGB Indexed", - "RGB 5:6:5", - "ARGB 1:5:5:5", - "ARGB 1:4:4:4", - "ARGB 8:8:8:8", - "5", - "6", - "7", - "AYUV Indexed", - "YUV 5:6:5", - "AYUV 1:5:5:5", - "AYUV 1:4:4:4", - "AYUV 8:8:8:8", - "13", - "14", - "15", - }; - - ivtv_get_output(itv, itv->active_output, &vidout); - ivtv_get_audio_output(itv, 0, &audout); - IVTV_INFO("Video Output: %s\n", vidout.name); - IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, - audio_modes[itv->audio_stereo_mode], - audio_modes[itv->audio_bilingual_mode]); - if (mode < 0 || mode > OUT_PASSTHROUGH) - mode = OUT_NONE; - IVTV_INFO("Output Mode: %s\n", output_modes[mode]); - ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); - data[0] |= (read_reg(0x2a00) >> 7) & 0x40; - IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", - data[0] & 1 ? "On" : "Off", - alpha_mode[(data[0] >> 1) & 0x3], - pixel_format[(data[0] >> 3) & 0xf]); - } - IVTV_INFO("Tuner: %s\n", - test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&itv->params, itv->name); - IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); - for (i = 0; i < IVTV_MAX_STREAMS; i++) { - struct ivtv_stream *s = &itv->streams[i]; - - if (s->v4l2dev == NULL || s->buffers == 0) - continue; - IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, - (s->buffers - s->q_free.buffers) * 100 / s->buffers, - (s->buffers * s->buf_size) / 1024, s->buffers); - } - IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); - IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); - break; + return 0; +} + +static int ivtv_log_status(struct file *file, void *fh) +{ + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + u32 data[CX2341X_MBOX_MAX_DATA]; + + int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; + struct v4l2_input vidin; + struct v4l2_audio audin; + int i; + + IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); + IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); + if (itv->hw_flags & IVTV_HW_TVEEPROM) { + struct tveeprom tv; + + ivtv_read_eeprom(itv, &tv); + } + ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); + ivtv_get_input(itv, itv->active_input, &vidin); + ivtv_get_audio_input(itv, itv->audio_input, &audin); + IVTV_INFO("Video Input: %s\n", vidin.name); + IVTV_INFO("Audio Input: %s%s\n", audin.name, + (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); + if (has_output) { + struct v4l2_output vidout; + struct v4l2_audioout audout; + int mode = itv->output_mode; + static const char * const output_modes[5] = { + "None", + "MPEG Streaming", + "YUV Streaming", + "YUV Frames", + "Passthrough", + }; + static const char * const audio_modes[5] = { + "Stereo", + "Left", + "Right", + "Mono", + "Swapped" + }; + static const char * const alpha_mode[4] = { + "None", + "Global", + "Local", + "Global and Local" + }; + static const char * const pixel_format[16] = { + "ARGB Indexed", + "RGB 5:6:5", + "ARGB 1:5:5:5", + "ARGB 1:4:4:4", + "ARGB 8:8:8:8", + "5", + "6", + "7", + "AYUV Indexed", + "YUV 5:6:5", + "AYUV 1:5:5:5", + "AYUV 1:4:4:4", + "AYUV 8:8:8:8", + "13", + "14", + "15", + }; + + ivtv_get_output(itv, itv->active_output, &vidout); + ivtv_get_audio_output(itv, 0, &audout); + IVTV_INFO("Video Output: %s\n", vidout.name); + IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, + audio_modes[itv->audio_stereo_mode], + audio_modes[itv->audio_bilingual_mode]); + if (mode < 0 || mode > OUT_PASSTHROUGH) + mode = OUT_NONE; + IVTV_INFO("Output Mode: %s\n", output_modes[mode]); + ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); + data[0] |= (read_reg(0x2a00) >> 7) & 0x40; + IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", + data[0] & 1 ? "On" : "Off", + alpha_mode[(data[0] >> 1) & 0x3], + pixel_format[(data[0] >> 3) & 0xf]); } + IVTV_INFO("Tuner: %s\n", + test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); + cx2341x_log_status(&itv->params, itv->name); + IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); + for (i = 0; i < IVTV_MAX_STREAMS; i++) { + struct ivtv_stream *s = &itv->streams[i]; - default: - return -EINVAL; + if (s->v4l2dev == NULL || s->buffers == 0) + continue; + IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, + (s->buffers - s->q_free.buffers) * 100 / s->buffers, + (s->buffers * s->buf_size) / 1024, s->buffers); } + + IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); + IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); + return 0; } @@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) return 0; } -static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, void *arg) +static int ivtv_default(struct file *file, void *fh, int cmd, void *arg) { - struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; - struct ivtv *itv = id->itv; - int ret; - - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - case VIDIOC_S_FMT: - case VIDIOC_S_CROP: - case VIDIOC_S_AUDIO: - case VIDIOC_S_AUDOUT: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_S_FBUF: - case VIDIOC_OVERLAY: - ret = v4l2_prio_check(&itv->prio, &id->prio); - if (ret) - return ret; - } + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; switch (cmd) { - case VIDIOC_DBG_G_REGISTER: - case VIDIOC_DBG_S_REGISTER: - case VIDIOC_G_CHIP_IDENT: - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_INT_RESET: - if (ivtv_debug & IVTV_DBGFLG_IOCTL) { - printk(KERN_INFO "ivtv%d ioctl: ", itv->num); - v4l_printk_ioctl(cmd); - printk("\n"); - } - return ivtv_debug_ioctls(filp, cmd, arg); + case VIDIOC_INT_S_AUDIO_ROUTING: { + struct v4l2_routing *route = arg; - case VIDIOC_G_PRIORITY: - case VIDIOC_S_PRIORITY: - case VIDIOC_QUERYCAP: - case VIDIOC_ENUMINPUT: - case VIDIOC_G_INPUT: - case VIDIOC_S_INPUT: - case VIDIOC_ENUMOUTPUT: - case VIDIOC_G_OUTPUT: - case VIDIOC_S_OUTPUT: - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - case VIDIOC_ENUM_FMT: - case VIDIOC_CROPCAP: - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - case VIDIOC_ENUMSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_S_TUNER: - case VIDIOC_G_TUNER: - case VIDIOC_ENUMAUDIO: - case VIDIOC_S_AUDIO: - case VIDIOC_G_AUDIO: - case VIDIOC_ENUMAUDOUT: - case VIDIOC_S_AUDOUT: - case VIDIOC_G_AUDOUT: - case VIDIOC_G_SLICED_VBI_CAP: - case VIDIOC_LOG_STATUS: - case VIDIOC_G_ENC_INDEX: - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: - case VIDIOC_G_FBUF: - case VIDIOC_S_FBUF: - case VIDIOC_OVERLAY: - if (ivtv_debug & IVTV_DBGFLG_IOCTL) { - printk(KERN_INFO "ivtv%d ioctl: ", itv->num); - v4l_printk_ioctl(cmd); - printk("\n"); - } - return ivtv_v4l2_ioctls(itv, filp, cmd, arg); + ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); + break; + } - case VIDIOC_QUERYMENU: - case VIDIOC_QUERYCTRL: - case VIDIOC_S_CTRL: - case VIDIOC_G_CTRL: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: - if (ivtv_debug & IVTV_DBGFLG_IOCTL) { - printk(KERN_INFO "ivtv%d ioctl: ", itv->num); - v4l_printk_ioctl(cmd); - printk("\n"); - } - return ivtv_control_ioctls(itv, cmd, arg); + case VIDIOC_INT_RESET: { + u32 val = *(u32 *)arg; - case IVTV_IOC_DMA_FRAME: - case VIDEO_GET_PTS: - case VIDEO_GET_FRAME_COUNT: - case VIDEO_GET_EVENT: - case VIDEO_PLAY: - case VIDEO_STOP: - case VIDEO_FREEZE: - case VIDEO_CONTINUE: - case VIDEO_COMMAND: - case VIDEO_TRY_COMMAND: - return ivtv_decoder_ioctls(filp, cmd, arg); + if ((val == 0 && itv->options.newi2c) || (val & 0x01)) + ivtv_reset_ir_gpio(itv); + if (val & 0x02) + itv->video_dec_func(itv, cmd, NULL); + break; + } - case 0x00005401: /* Handle isatty() calls */ - return -EINVAL; default: - return v4l_compat_translate_ioctl(inode, filp, cmd, arg, - ivtv_v4l2_do_ioctl); + return -EINVAL; } return 0; } @@ -1729,7 +1763,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - /* Filter dvb ioctls that cannot be handled by video_usercopy */ + struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; + int ret; + + /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */ switch (cmd) { case VIDEO_SELECT_SOURCE: IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); @@ -1758,10 +1795,49 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); return 0; + case IVTV_IOC_DMA_FRAME: + case VIDEO_GET_PTS: + case VIDEO_GET_FRAME_COUNT: + case VIDEO_GET_EVENT: + case VIDEO_PLAY: + case VIDEO_STOP: + case VIDEO_FREEZE: + case VIDEO_CONTINUE: + case VIDEO_COMMAND: + case VIDEO_TRY_COMMAND: + return ivtv_decoder_ioctls(filp, cmd, (void *)arg); + default: break; } - return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); + + /* check priority */ + switch (cmd) { + case VIDIOC_S_CTRL: + case VIDIOC_S_STD: + case VIDIOC_S_INPUT: + case VIDIOC_S_OUTPUT: + case VIDIOC_S_TUNER: + case VIDIOC_S_FREQUENCY: + case VIDIOC_S_FMT: + case VIDIOC_S_CROP: + case VIDIOC_S_AUDIO: + case VIDIOC_S_AUDOUT: + case VIDIOC_S_EXT_CTRLS: + case VIDIOC_S_FBUF: + case VIDIOC_OVERLAY: + ret = v4l2_prio_check(&itv->prio, &id->prio); + if (ret) + return ret; + } + + if (ivtv_debug & IVTV_DBGFLG_IOCTL) { + printk(KERN_INFO "ivtv%d ioctl: ", itv->num); + v4l_printk_ioctl(cmd); + printk("\n"); + } + + return video_ioctl2(inode, filp, cmd, arg); } int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, @@ -1776,3 +1852,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, mutex_unlock(&itv->serialize_lock); return res; } + +void ivtv_set_funcs(struct video_device *vdev) +{ + vdev->vidioc_querycap = ivtv_querycap; + vdev->vidioc_g_priority = ivtv_g_priority; + vdev->vidioc_s_priority = ivtv_s_priority; + vdev->vidioc_s_audio = ivtv_s_audio; + vdev->vidioc_g_audio = ivtv_g_audio; + vdev->vidioc_enumaudio = ivtv_enumaudio; + vdev->vidioc_s_audout = ivtv_s_audout; + vdev->vidioc_g_audout = ivtv_g_audout; + vdev->vidioc_enum_input = ivtv_enum_input; + vdev->vidioc_enum_output = ivtv_enum_output; + vdev->vidioc_enumaudout = ivtv_enumaudout; + vdev->vidioc_cropcap = ivtv_cropcap; + vdev->vidioc_s_crop = ivtv_s_crop; + vdev->vidioc_g_crop = ivtv_g_crop; + vdev->vidioc_g_input = ivtv_g_input; + vdev->vidioc_s_input = ivtv_s_input; + vdev->vidioc_g_output = ivtv_g_output; + vdev->vidioc_s_output = ivtv_s_output; + vdev->vidioc_g_frequency = ivtv_g_frequency; + vdev->vidioc_s_frequency = ivtv_s_frequency; + vdev->vidioc_s_tuner = ivtv_s_tuner; + vdev->vidioc_g_tuner = ivtv_g_tuner; + vdev->vidioc_g_enc_index = ivtv_g_enc_index; + vdev->vidioc_g_fbuf = ivtv_g_fbuf; + vdev->vidioc_s_fbuf = ivtv_s_fbuf; + vdev->vidioc_g_std = ivtv_g_std; + vdev->vidioc_s_std = ivtv_s_std; + vdev->vidioc_overlay = ivtv_overlay; + vdev->vidioc_log_status = ivtv_log_status; + vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap; + vdev->vidioc_encoder_cmd = ivtv_encoder_cmd; + vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd; + vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out; + vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap; + vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap; + vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap; + vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out; + vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay; + vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out; + vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap; + vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap; + vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap; + vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out; + vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay; + vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out; + vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap; + vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap; + vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap; + vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out; + vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay; + vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; + vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; + vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; + vdev->vidioc_g_register = ivtv_g_register; + vdev->vidioc_s_register = ivtv_s_register; + vdev->vidioc_default = ivtv_default; + vdev->vidioc_queryctrl = ivtv_queryctrl; + vdev->vidioc_querymenu = ivtv_querymenu; + vdev->vidioc_g_ctrl = ivtv_g_ctrl; + vdev->vidioc_s_ctrl = ivtv_s_ctrl; + vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; + vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; + vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; +} diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h index 4e67f0ed1fc0..70188588b4f4 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.h +++ b/drivers/media/video/ivtv/ivtv-ioctl.h @@ -24,10 +24,13 @@ u16 ivtv_service2vbi(int type); void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); -int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); -int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg); void ivtv_set_osd_alpha(struct ivtv *itv); int ivtv_set_speed(struct ivtv *itv, int speed); +void ivtv_set_funcs(struct video_device *vdev); +int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std); +int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); +int ivtv_s_input(struct file *file, void *fh, unsigned int inp); +int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); #endif diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index c854285a4371..f8883b487f4a 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) s->v4l2dev->dev = &itv->dev->dev; s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->release = video_device_release; - + s->v4l2dev->tvnorms = V4L2_STD_ALL; + ivtv_set_funcs(s->v4l2dev); return 0; } -- cgit v1.2.3 From e88360c0f306de8535b5072c7c0dcae20f75af62 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 08:00:56 -0300 Subject: V4L/DVB (8080): ivtv: make sure all v4l2_format fields are filled in Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 112 ++++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 45 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 49b297e788db..584ffc61c982 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -378,6 +378,8 @@ static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) return -EINVAL; vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; @@ -396,21 +398,24 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f { struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; - - fmt->fmt.pix.width = itv->params.width; - fmt->fmt.pix.height = itv->params.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - if (id->type == IVTV_ENC_STREAM_TYPE_YUV || - id->type == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; + + pixfmt->width = itv->params.width; + pixfmt->height = itv->params.height; + pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + pixfmt->field = V4L2_FIELD_INTERLACED; + pixfmt->priv = 0; + if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { + pixfmt->pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + pixfmt->sizeimage = + pixfmt->height * pixfmt->width + + pixfmt->height * (pixfmt->width / 2); + pixfmt->bytesperline = 720; } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; + pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; + pixfmt->sizeimage = 128 * 1024; + pixfmt->bytesperline = 0; } return 0; } @@ -418,14 +423,18 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - - fmt->fmt.vbi.sampling_rate = 27000000; - fmt->fmt.vbi.offset = 248; - fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4; - fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - fmt->fmt.vbi.start[0] = itv->vbi.start[0]; - fmt->fmt.vbi.start[1] = itv->vbi.start[1]; - fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count; + struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; + + vbifmt->sampling_rate = 27000000; + vbifmt->offset = 248; + vbifmt->samples_per_line = itv->vbi.raw_decoder_line_size - 4; + vbifmt->sample_format = V4L2_PIX_FMT_GREY; + vbifmt->start[0] = itv->vbi.start[0]; + vbifmt->start[1] = itv->vbi.start[1]; + vbifmt->count[0] = vbifmt->count[1] = itv->vbi.count; + vbifmt->flags = 0; + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; return 0; } @@ -435,6 +444,8 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; if (id->type == IVTV_DEC_STREAM_TYPE_VBI) { @@ -453,42 +464,39 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f { struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - fmt->fmt.pix.width = itv->main_rect.width; - fmt->fmt.pix.height = itv->main_rect.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + pixfmt->width = itv->main_rect.width; + pixfmt->height = itv->main_rect.height; + pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + pixfmt->field = V4L2_FIELD_INTERLACED; + pixfmt->priv = 0; if (id->type == IVTV_DEC_STREAM_TYPE_YUV) { switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) { case IVTV_YUV_MODE_INTERLACED: - fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? + pixfmt->field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ? V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB; break; case IVTV_YUV_MODE_PROGRESSIVE: - fmt->fmt.pix.field = V4L2_FIELD_NONE; + pixfmt->field = V4L2_FIELD_NONE; break; default: - fmt->fmt.pix.field = V4L2_FIELD_ANY; + pixfmt->field = V4L2_FIELD_ANY; break; } - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; - fmt->fmt.pix.bytesperline = 720; - fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w; - fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - 1080 * ((fmt->fmt.pix.height + 31) & ~31); - } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + pixfmt->pixelformat = V4L2_PIX_FMT_HM12; + pixfmt->bytesperline = 720; + pixfmt->width = itv->yuv_info.v4l2_src_w; + pixfmt->height = itv->yuv_info.v4l2_src_h; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + pixfmt->sizeimage = + 1080 * ((pixfmt->height + 31) & ~31); } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; + pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; + pixfmt->sizeimage = 128 * 1024; + pixfmt->bytesperline = 0; } return 0; } @@ -496,11 +504,19 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_window *winfmt = &fmt->fmt.win; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; - fmt->fmt.win.chromakey = itv->osd_chroma_key; - fmt->fmt.win.global_alpha = itv->osd_global_alpha; + winfmt->chromakey = itv->osd_chroma_key; + winfmt->global_alpha = itv->osd_global_alpha; + winfmt->field = V4L2_FIELD_INTERLACED; + winfmt->clips = NULL; + winfmt->clipcount = 0; + winfmt->bitmap = NULL; + winfmt->w.top = winfmt->w.left = 0; + winfmt->w.width = itv->osd_rect.width; + winfmt->w.height = itv->osd_rect.height; return 0; } @@ -542,7 +558,8 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ /* set sliced VBI capture format */ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; if (vbifmt->service_set) ivtv_expand_service_set(vbifmt, itv->is_50hz); @@ -581,9 +598,14 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + u32 chromakey = fmt->fmt.win.chromakey; + u8 global_alpha = fmt->fmt.win.global_alpha; if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) return -EINVAL; + ivtv_g_fmt_vid_out_overlay(file, fh, fmt); + fmt->fmt.win.chromakey = chromakey; + fmt->fmt.win.global_alpha = global_alpha; return 0; } -- cgit v1.2.3 From 1a05221bc45ccb1b5c583a87dc3639bfc10c4f10 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 08:15:37 -0300 Subject: V4L/DVB (8081): ivtv: remove obsolete arrays. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 31 ------------------------------- 1 file changed, 31 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 584ffc61c982..e1a31830e9f6 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -128,37 +128,6 @@ u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) return set; } -static const struct { - v4l2_std_id std; - char *name; -} enum_stds[] = { - { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" }, - { V4L2_STD_PAL_DK, "PAL-DK" }, - { V4L2_STD_PAL_I, "PAL-I" }, - { V4L2_STD_PAL_M, "PAL-M" }, - { V4L2_STD_PAL_N, "PAL-N" }, - { V4L2_STD_PAL_Nc, "PAL-Nc" }, - { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" }, - { V4L2_STD_SECAM_DK, "SECAM-DK" }, - { V4L2_STD_SECAM_L, "SECAM-L" }, - { V4L2_STD_SECAM_LC, "SECAM-L'" }, - { V4L2_STD_NTSC_M, "NTSC-M" }, - { V4L2_STD_NTSC_M_JP, "NTSC-J" }, - { V4L2_STD_NTSC_M_KR, "NTSC-K" }, -}; - -static const struct v4l2_standard ivtv_std_60hz = -{ - .frameperiod = {.numerator = 1001, .denominator = 30000}, - .framelines = 525, -}; - -static const struct v4l2_standard ivtv_std_50hz = -{ - .frameperiod = {.numerator = 1, .denominator = 25}, - .framelines = 625, -}; - void ivtv_set_osd_alpha(struct ivtv *itv) { ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3, -- cgit v1.2.3 From 3b6fe58f0f18880200969e813d0181d1bdab0966 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sat, 21 Jun 2008 08:36:31 -0300 Subject: V4L/DVB (8082): cx18: convert to video_ioctl2() cx18: convert driver to use video_ioctl2(). Pushed down ioctl debug messages and priority checks as well. Still left serialization lock in place for now. #if 0'ed out sliced vbi ioctl code for now. Patch heavily based on similar changes made to ivtv by Hans Verkuil. Signed-off-by: Andy Walls Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-controls.c | 195 +++-- drivers/media/video/cx18/cx18-controls.h | 9 +- drivers/media/video/cx18/cx18-driver.c | 9 +- drivers/media/video/cx18/cx18-ioctl.c | 1211 ++++++++++++++++-------------- drivers/media/video/cx18/cx18-ioctl.h | 6 +- drivers/media/video/cx18/cx18-streams.c | 4 +- 6 files changed, 745 insertions(+), 689 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 87cf41021665..6eae75f4ee7c 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -51,8 +51,9 @@ static const u32 *ctrl_classes[] = { NULL }; -static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl) +int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) { + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; const char *name; CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); @@ -91,19 +92,28 @@ static int cx18_queryctrl(struct cx18 *cx, struct v4l2_queryctrl *qctrl) return 0; } -static int cx18_querymenu(struct cx18 *cx, struct v4l2_querymenu *qmenu) +int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_queryctrl qctrl; + CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); qctrl.id = qmenu->id; - cx18_queryctrl(cx, &qctrl); + cx18_queryctrl(file, fh, &qctrl); return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); } -static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) +int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; s32 v = vctrl->value; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; + CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); switch (vctrl->id) { @@ -129,8 +139,10 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) return 0; } -static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) +int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); switch (vctrl->id) { @@ -194,113 +206,100 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt return 0; } -int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg) +int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_control ctrl; - switch (cmd) { - case VIDIOC_QUERYMENU: - CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); - return cx18_querymenu(cx, arg); - - case VIDIOC_QUERYCTRL: - return cx18_queryctrl(cx, arg); - - case VIDIOC_S_CTRL: - return cx18_s_ctrl(cx, arg); - - case VIDIOC_G_CTRL: - return cx18_g_ctrl(cx, arg); - - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = cx18_s_ctrl(cx, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + ctrl.id = c->controls[i].id; + ctrl.value = c->controls[i].value; + err = cx18_g_ctrl(file, fh, &ctrl); + c->controls[i].value = ctrl.value; + if (err) { + c->error_idx = i; + break; } - return err; } - CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - struct cx2341x_mpeg_params p = cx->params; - int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd); + return err; + } + CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) + return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS); + return -EINVAL; +} - if (err) - return err; +int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; + struct v4l2_control ctrl; - if (p.video_encoding != cx->params.video_encoding) { - int is_mpeg1 = p.video_encoding == - V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_format fmt; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - /* fix videodecoder resolution */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = cx->params.width / (is_mpeg1 ? 2 : 1); - fmt.fmt.pix.height = cx->params.height; - cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + ctrl.id = c->controls[i].id; + ctrl.value = c->controls[i].value; + err = cx18_s_ctrl(file, fh, &ctrl); + c->controls[i].value = ctrl.value; + if (err) { + c->error_idx = i; + break; } - err = cx2341x_update(cx, cx18_api_func, &cx->params, &p); - if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt) - err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt); - cx->params = p; - cx->dualwatch_stereo_mode = p.audio_properties & 0x0300; - cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03); - return err; } - return -EINVAL; + return err; } + CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { + struct cx2341x_mpeg_params p = cx->params; + int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), + c, VIDIOC_S_EXT_CTRLS); - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = cx18_g_ctrl(cx, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } - } + if (err) return err; - } - CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&cx->params, 0, arg, cmd); - return -EINVAL; - } - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *c = arg; - - CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&cx->params, - atomic_read(&cx->ana_capturing), arg, cmd); - return -EINVAL; + if (p.video_encoding != cx->params.video_encoding) { + int is_mpeg1 = p.video_encoding == + V4L2_MPEG_VIDEO_ENCODING_MPEG_1; + struct v4l2_format fmt; + + /* fix videodecoder resolution */ + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt.fmt.pix.width = cx->params.width + / (is_mpeg1 ? 2 : 1); + fmt.fmt.pix.height = cx->params.height; + cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); + } + err = cx2341x_update(cx, cx18_api_func, &cx->params, &p); + if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt) + err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt); + cx->params = p; + cx->dualwatch_stereo_mode = p.audio_properties & 0x0300; + cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03); + return err; } + return -EINVAL; +} - default: - return -EINVAL; - } - return 0; +int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); + if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) + return cx2341x_ext_ctrls(&cx->params, + atomic_read(&cx->ana_capturing), + c, VIDIOC_TRY_EXT_CTRLS); + return -EINVAL; } diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h index 6e985cf422a0..81b8996e5860 100644 --- a/drivers/media/video/cx18/cx18-controls.h +++ b/drivers/media/video/cx18/cx18-controls.h @@ -21,4 +21,11 @@ * 02111-1307 USA */ -int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg); +int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); +int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); +int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); +int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); +int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); +int cx18_try_ext_ctrls(struct file *file, void *fh, + struct v4l2_ext_controls *a); +int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a); diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index d9178843e8d2..e9c7e07b9fed 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -818,6 +818,9 @@ int cx18_init_on_first_open(struct cx18 *cx) int video_input; int fw_retry_count = 3; struct v4l2_frequency vf; + struct cx18_open_id fh; + + fh.cx = cx; if (test_bit(CX18_F_I_FAILED, &cx->i_flags)) return -ENXIO; @@ -869,13 +872,13 @@ int cx18_init_on_first_open(struct cx18 *cx) video_input = cx->active_input; cx->active_input++; /* Force update of input */ - cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_INPUT, &video_input); + cx18_s_input(NULL, &fh, video_input); /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code in one place. */ cx->std++; /* Force full standard initialization */ - cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_STD, &cx->tuner_std); - cx18_v4l2_ioctls(cx, NULL, VIDIOC_S_FREQUENCY, &vf); + cx18_s_std(NULL, &fh, &cx->tuner_std); + cx18_s_frequency(NULL, &fh, &vf); return 0; } diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 4151f1e5493f..70afedf4763f 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -100,19 +100,6 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } -static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) -{ - int f, l; - u16 set = 0; - - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); - set |= fmt->service_lines[f][l]; - } - } - return set != 0; -} u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) { @@ -126,35 +113,6 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) return set; } -static const struct { - v4l2_std_id std; - char *name; -} enum_stds[] = { - { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" }, - { V4L2_STD_PAL_DK, "PAL-DK" }, - { V4L2_STD_PAL_I, "PAL-I" }, - { V4L2_STD_PAL_M, "PAL-M" }, - { V4L2_STD_PAL_N, "PAL-N" }, - { V4L2_STD_PAL_Nc, "PAL-Nc" }, - { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" }, - { V4L2_STD_SECAM_DK, "SECAM-DK" }, - { V4L2_STD_SECAM_L, "SECAM-L" }, - { V4L2_STD_SECAM_LC, "SECAM-L'" }, - { V4L2_STD_NTSC_M, "NTSC-M" }, - { V4L2_STD_NTSC_M_JP, "NTSC-J" }, - { V4L2_STD_NTSC_M_KR, "NTSC-K" }, -}; - -static const struct v4l2_standard cx18_std_60hz = { - .frameperiod = {.numerator = 1001, .denominator = 30000}, - .framelines = 525, -}; - -static const struct v4l2_standard cx18_std_50hz = { - .frameperiod = { .numerator = 1, .denominator = 25 }, - .framelines = 625, -}; - static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) { struct v4l2_register *regs = arg; @@ -174,665 +132,702 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) return 0; } -static int cx18_get_fmt(struct cx18 *cx, int streamtype, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - fmt->fmt.pix.width = cx->params.width; - fmt->fmt.pix.height = cx->params.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; - if (streamtype == CX18_ENC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); - } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; - } - break; +static int cx18_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; - case V4L2_BUF_TYPE_VBI_CAPTURE: - fmt->fmt.vbi.sampling_rate = 27000000; - fmt->fmt.vbi.offset = 248; - fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4; - fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - fmt->fmt.vbi.start[0] = cx->vbi.start[0]; - fmt->fmt.vbi.start[1] = cx->vbi.start[1]; - fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count; - break; + CX18_DEBUG_IOCTL("VIDIOC_G_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + + fmt->fmt.pix.width = cx->params.width; + fmt->fmt.pix.height = cx->params.height; + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; + fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + if (id->type == CX18_ENC_STREAM_TYPE_YUV) { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ + fmt->fmt.pix.sizeimage = + fmt->fmt.pix.height * fmt->fmt.pix.width + + fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + } else { + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + fmt->fmt.pix.sizeimage = 128 * 1024; + } + return 0; +} - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - { - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; +static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); - memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); + CX18_DEBUG_IOCTL("VIDIOC_G_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - cx18_av_cmd(cx, VIDIOC_G_FMT, fmt); - vbifmt->service_set = cx18_get_service_set(vbifmt); - break; - } - default: - return -EINVAL; - } + fmt->fmt.vbi.sampling_rate = 27000000; + fmt->fmt.vbi.offset = 248; + fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4; + fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; + fmt->fmt.vbi.start[0] = cx->vbi.start[0]; + fmt->fmt.vbi.start[1] = cx->vbi.start[1]; + fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count; return 0; } -static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, - struct v4l2_format *fmt, int set_fmt) +static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) { - struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; - u16 set; + return -EINVAL; +} - /* set window size */ - if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; +static int cx18_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; - if (w > 720) - w = 720; - else if (w < 1) - w = 1; - if (h > (cx->is_50hz ? 576 : 480)) - h = (cx->is_50hz ? 576 : 480); - else if (h < 2) - h = 2; - cx18_get_fmt(cx, streamtype, fmt); - fmt->fmt.pix.width = w; - fmt->fmt.pix.height = h; + int w = fmt->fmt.pix.width; + int h = fmt->fmt.pix.height; - if (!set_fmt || (cx->params.width == w && cx->params.height == h)) - return 0; - if (atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - cx->params.width = w; - cx->params.height = h; - if (w != 720 || h != (cx->is_50hz ? 576 : 480)) - cx->params.video_temporal_filter = 0; - else - cx->params.video_temporal_filter = 8; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); - return cx18_get_fmt(cx, streamtype, fmt); - } + CX18_DEBUG_IOCTL("VIDIOC_TRY_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - /* set raw VBI format */ - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI && - cx->vbi.sliced_in->service_set && - atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - if (set_fmt) { - cx->vbi.sliced_in->service_set = 0; - cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); - } - return cx18_get_fmt(cx, streamtype, fmt); - } + w = min(w, 720); + w = max(w, 1); + h = min(h, cx->is_50hz ? 576 : 480); + h = max(h, 2); + cx18_g_fmt_vid_cap(file, fh, fmt); + fmt->fmt.pix.width = w; + fmt->fmt.pix.height = h; + return 0; +} - /* any else but sliced VBI capture is an error */ - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; +static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - /* TODO: implement sliced VBI, for now silently return 0 */ - return 0; + CX18_DEBUG_IOCTL("VIDIOC_TRY_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); + + return cx18_g_fmt_vbi_cap(file, fh, fmt); +} + +static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + return -EINVAL; +} + +static int cx18_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; + int w = fmt->fmt.pix.width; + int h = fmt->fmt.pix.height; + + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - /* set sliced VBI capture format */ - vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; - memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); + CX18_DEBUG_IOCTL("VIDIOC_S_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - if (vbifmt->service_set) - cx18_expand_service_set(vbifmt, cx->is_50hz); - set = check_service_set(vbifmt, cx->is_50hz); - vbifmt->service_set = cx18_get_service_set(vbifmt); + ret = cx18_try_fmt_vid_cap(file, fh, fmt); + if (ret) + return ret; - if (!set_fmt) + if (cx->params.width == w && cx->params.height == h) return 0; - if (set == 0) - return -EINVAL; - if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0) + + if (atomic_read(&cx->ana_capturing) > 0) return -EBUSY; + + cx->params.width = w; + cx->params.height = h; + if (w != 720 || h != (cx->is_50hz ? 576 : 480)) + cx->params.video_temporal_filter = 0; + else + cx->params.video_temporal_filter = 8; cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); - memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); - return 0; + return cx18_g_fmt_vid_cap(file, fh, fmt); } -static int cx18_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) +static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) { - struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; + struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - struct v4l2_register *reg = arg; + int ret; - switch (cmd) { - /* ioctls to allow direct access to the encoder registers for testing */ - case VIDIOC_DBG_G_REGISTER: - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) - return cx18_cxc(cx, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, reg->match_chip, cmd, arg); - return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg); - - case VIDIOC_DBG_S_REGISTER: - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) - return cx18_cxc(cx, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, reg->match_chip, cmd, arg); - return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg); - - case VIDIOC_G_CHIP_IDENT: { - struct v4l2_chip_ident *chip = arg; - - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (reg->match_type == V4L2_CHIP_MATCH_HOST) { - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) { - struct v4l2_chip_ident *chip = arg; - - chip->ident = V4L2_IDENT_CX23418; - } - return 0; - } - if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) - return cx18_i2c_id(cx, reg->match_chip, cmd, arg); - if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR) - return cx18_call_i2c_client(cx, reg->match_chip, cmd, arg); - return -EINVAL; - } + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - case VIDIOC_INT_S_AUDIO_ROUTING: { - struct v4l2_routing *route = arg; + CX18_DEBUG_IOCTL("VIDIOC_S_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - cx18_audio_set_route(cx, route); - break; - } + if (id->type == CX18_ENC_STREAM_TYPE_VBI && + cx->vbi.sliced_in->service_set && + atomic_read(&cx->ana_capturing) > 0) + return -EBUSY; - default: - return -EINVAL; + cx->vbi.sliced_in->service_set = 0; + cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); + return cx18_g_fmt_vbi_cap(file, fh, fmt); +} + +static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, + struct v4l2_format *fmt) +{ + return -EINVAL; +} + +static int cx18_g_chip_ident(struct file *file, void *fh, + struct v4l2_chip_ident *chip) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_G_CHIP_IDENT\n"); + + chip->ident = V4L2_IDENT_NONE; + chip->revision = 0; + if (chip->match_type == V4L2_CHIP_MATCH_HOST) { + if (v4l2_chip_match_host(chip->match_type, chip->match_chip)) + chip->ident = V4L2_IDENT_CX23418; + return 0; } + if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return cx18_i2c_id(cx, chip->match_chip, VIDIOC_G_CHIP_IDENT, + chip); + if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR) + return cx18_call_i2c_client(cx, chip->match_chip, + VIDIOC_G_CHIP_IDENT, chip); + return -EINVAL; +} + +static int cx18_g_register(struct file *file, void *fh, + struct v4l2_register *reg) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_DBG_G_REGISTER\n"); + + if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); + if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, + reg); + return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_G_REGISTER, + reg); +} + +static int cx18_s_register(struct file *file, void *fh, + struct v4l2_register *reg) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_DBG_S_REGISTER\n"); + + if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) + return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); + if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) + return cx18_i2c_id(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, + reg); + return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, + reg); +} + +static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_G_PRIORITY\n"); + + *p = v4l2_prio_max(&cx->prio); return 0; } -int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg) +static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio) { - struct cx18_open_id *id = NULL; + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; - if (filp) - id = (struct cx18_open_id *)filp->private_data; + CX18_DEBUG_IOCTL("VIDIOC_S_PRIORITY\n"); - switch (cmd) { - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p = arg; + return v4l2_prio_change(&cx->prio, &id->prio, prio); +} - *p = v4l2_prio_max(&cx->prio); - break; - } +static int cx18_querycap(struct file *file, void *fh, + struct v4l2_capability *vcap) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *prio = arg; + CX18_DEBUG_IOCTL("VIDIOC_QUERYCAP\n"); - return v4l2_prio_change(&cx->prio, &id->prio, *prio); - } + strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); + strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); + strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); + vcap->version = CX18_DRIVER_VERSION; /* version */ + vcap->capabilities = cx->v4l2_cap; /* capabilities */ + return 0; +} - case VIDIOC_QUERYCAP:{ - struct v4l2_capability *vcap = arg; +static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - memset(vcap, 0, sizeof(*vcap)); - strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); - strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); - vcap->version = CX18_DRIVER_VERSION; /* version */ - vcap->capabilities = cx->v4l2_cap; /* capabilities */ + CX18_DEBUG_IOCTL("VIDIOC_ENUMAUDIO\n"); - /* reserved.. must set to 0! */ - vcap->reserved[0] = vcap->reserved[1] = - vcap->reserved[2] = vcap->reserved[3] = 0; - break; - } + return cx18_get_audio_input(cx, vin->index, vin); +} - case VIDIOC_ENUMAUDIO:{ - struct v4l2_audio *vin = arg; +static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - return cx18_get_audio_input(cx, vin->index, vin); - } + CX18_DEBUG_IOCTL("VIDIOC_G_AUDIO\n"); - case VIDIOC_G_AUDIO:{ - struct v4l2_audio *vin = arg; + vin->index = cx->audio_input; + return cx18_get_audio_input(cx, vin->index, vin); +} - vin->index = cx->audio_input; - return cx18_get_audio_input(cx, vin->index, vin); - } +static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - case VIDIOC_S_AUDIO:{ - struct v4l2_audio *vout = arg; + CX18_DEBUG_IOCTL("VIDIOC_S_AUDIO\n"); - if (vout->index >= cx->nof_audio_inputs) - return -EINVAL; - cx->audio_input = vout->index; - cx18_audio_set_io(cx); - break; - } + if (vout->index >= cx->nof_audio_inputs) + return -EINVAL; + cx->audio_input = vout->index; + cx18_audio_set_io(cx); + return 0; +} - case VIDIOC_ENUMINPUT:{ - struct v4l2_input *vin = arg; +static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - /* set it to defaults from our table */ - return cx18_get_input(cx, vin->index, vin); - } + CX18_DEBUG_IOCTL("VIDIOC_ENUMINPUT\n"); - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: { - struct v4l2_format *fmt = arg; + /* set it to defaults from our table */ + return cx18_get_input(cx, vin->index, vin); +} - return cx18_try_or_set_fmt(cx, id->type, fmt, cmd == VIDIOC_S_FMT); - } +static int cx18_cropcap(struct file *file, void *fh, + struct v4l2_cropcap *cropcap) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - case VIDIOC_G_FMT: { - struct v4l2_format *fmt = arg; - int type = fmt->type; + CX18_DEBUG_IOCTL("VIDIOC_CROPCAP\n"); - memset(fmt, 0, sizeof(*fmt)); - fmt->type = type; - return cx18_get_fmt(cx, id->type, fmt); - } + if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + cropcap->bounds.top = cropcap->bounds.left = 0; + cropcap->bounds.width = 720; + cropcap->bounds.height = cx->is_50hz ? 576 : 480; + cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; + cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; + cropcap->defrect = cropcap->bounds; + return 0; +} - case VIDIOC_CROPCAP: { - struct v4l2_cropcap *cropcap = arg; - - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = cx->is_50hz ? 576 : 480; - cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; - cropcap->defrect = cropcap->bounds; - return 0; - } +static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; - case VIDIOC_S_CROP: { - struct v4l2_crop *crop = arg; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_S_CROP, arg); - } + CX18_DEBUG_IOCTL("VIDIOC_S_CROP\n"); - case VIDIOC_G_CROP: { - struct v4l2_crop *crop = arg; + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); +} - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_G_CROP, arg); - } +static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - case VIDIOC_ENUM_FMT: { - static struct v4l2_fmtdesc formats[] = { - { 0, 0, 0, - "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, - { 0, 0, 0, 0 } - }, - { 1, 0, V4L2_FMT_FLAG_COMPRESSED, - "MPEG", V4L2_PIX_FMT_MPEG, - { 0, 0, 0, 0 } - } - }; - struct v4l2_fmtdesc *fmt = arg; - enum v4l2_buf_type type = fmt->type; - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - break; - default: - return -EINVAL; + CX18_DEBUG_IOCTL("VIDIOC_G_CROP\n"); + + if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); +} + +static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_fmtdesc *fmt) +{ + static struct v4l2_fmtdesc formats[] = { + { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0, + "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 } + }, + { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED, + "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 } } - if (fmt->index > 1) - return -EINVAL; - *fmt = formats[fmt->index]; - fmt->type = type; + }; + + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_ENUM_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + + if (fmt->index > 1) + return -EINVAL; + *fmt = formats[fmt->index]; + return 0; +} + +static int cx18_g_input(struct file *file, void *fh, unsigned int *i) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_G_INPUT\n"); + + *i = cx->active_input; + return 0; +} + +int cx18_s_input(struct file *file, void *fh, unsigned int inp) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; + + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; + + CX18_DEBUG_IOCTL("VIDIOC_S_INPUT\n"); + + if (inp < 0 || inp >= cx->nof_inputs) + return -EINVAL; + + if (inp == cx->active_input) { + CX18_DEBUG_INFO("Input unchanged\n"); return 0; } - case VIDIOC_G_INPUT:{ - *(int *)arg = cx->active_input; - break; - } + CX18_DEBUG_INFO("Changing input from %d to %d\n", + cx->active_input, inp); - case VIDIOC_S_INPUT:{ - int inp = *(int *)arg; + cx->active_input = inp; + /* Set the audio input to whatever is appropriate for the input type. */ + cx->audio_input = cx->card->video_inputs[inp].audio_index; - if (inp < 0 || inp >= cx->nof_inputs) - return -EINVAL; + /* prevent others from messing with the streams until + we're finished changing inputs. */ + cx18_mute(cx); + cx18_video_set_io(cx); + cx18_audio_set_io(cx); + cx18_unmute(cx); + return 0; +} - if (inp == cx->active_input) { - CX18_DEBUG_INFO("Input unchanged\n"); - break; - } - CX18_DEBUG_INFO("Changing input from %d to %d\n", - cx->active_input, inp); +static int cx18_g_frequency(struct file *file, void *fh, + struct v4l2_frequency *vf) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - cx->active_input = inp; - /* Set the audio input to whatever is appropriate for the - input type. */ - cx->audio_input = cx->card->video_inputs[inp].audio_index; + CX18_DEBUG_IOCTL("VIDIOC_G_FREQUENCY\n"); - /* prevent others from messing with the streams until - we're finished changing inputs. */ - cx18_mute(cx); - cx18_video_set_io(cx); - cx18_audio_set_io(cx); - cx18_unmute(cx); - break; - } + if (vf->tuner != 0) + return -EINVAL; - case VIDIOC_G_FREQUENCY:{ - struct v4l2_frequency *vf = arg; + cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf); + return 0; +} - if (vf->tuner != 0) - return -EINVAL; - cx18_call_i2c_clients(cx, cmd, arg); - break; - } +int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; - case VIDIOC_S_FREQUENCY:{ - struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - if (vf.tuner != 0) - return -EINVAL; + CX18_DEBUG_IOCTL("VIDIOC_S_FREQUENCY\n"); - cx18_mute(cx); - CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency); - cx18_call_i2c_clients(cx, cmd, &vf); - cx18_unmute(cx); - break; - } + if (vf->tuner != 0) + return -EINVAL; - case VIDIOC_ENUMSTD:{ - struct v4l2_standard *vs = arg; - int idx = vs->index; + cx18_mute(cx); + CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); + cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf); + cx18_unmute(cx); + return 0; +} - if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) - return -EINVAL; +static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - *vs = (enum_stds[idx].std & V4L2_STD_525_60) ? - cx18_std_60hz : cx18_std_50hz; - vs->index = idx; - vs->id = enum_stds[idx].std; - strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name)); - break; - } + CX18_DEBUG_IOCTL("VIDIOC_G_STD\n"); - case VIDIOC_G_STD:{ - *(v4l2_std_id *) arg = cx->std; - break; - } + *std = cx->std; + return 0; +} - case VIDIOC_S_STD: { - v4l2_std_id std = *(v4l2_std_id *) arg; +int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; - if ((std & V4L2_STD_ALL) == 0) - return -EINVAL; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; - if (std == cx->std) - break; + CX18_DEBUG_IOCTL("VIDIOC_S_STD\n"); - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || - atomic_read(&cx->ana_capturing) > 0) { - /* Switching standard would turn off the radio or mess - with already running streams, prevent that by - returning EBUSY. */ - return -EBUSY; - } + if ((*std & V4L2_STD_ALL) == 0) + return -EINVAL; - cx->std = std; - cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0; - cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; - cx->params.width = 720; - cx->params.height = cx->is_50hz ? 576 : 480; - cx->vbi.count = cx->is_50hz ? 18 : 12; - cx->vbi.start[0] = cx->is_50hz ? 6 : 10; - cx->vbi.start[1] = cx->is_50hz ? 318 : 273; - cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; - CX18_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)cx->std); - - /* Tuner */ - cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); - break; + if (*std == cx->std) + return 0; + + if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || + atomic_read(&cx->ana_capturing) > 0) { + /* Switching standard would turn off the radio or mess + with already running streams, prevent that by + returning EBUSY. */ + return -EBUSY; } - case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ - struct v4l2_tuner *vt = arg; + cx->std = *std; + cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; + cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; + cx->params.width = 720; + cx->params.height = cx->is_50hz ? 576 : 480; + cx->vbi.count = cx->is_50hz ? 18 : 12; + cx->vbi.start[0] = cx->is_50hz ? 6 : 10; + cx->vbi.start[1] = cx->is_50hz ? 318 : 273; + cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; + CX18_DEBUG_INFO("Switching standard to %llx.\n", + (unsigned long long) cx->std); + + /* Tuner */ + cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); + return 0; +} - if (vt->index != 0) - return -EINVAL; +static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; + int ret; - cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); - break; + ret = v4l2_prio_check(&cx->prio, &id->prio); + if (ret) + return ret; + + CX18_DEBUG_IOCTL("VIDIOC_S_TUNER\n"); + + if (vt->index != 0) + return -EINVAL; + + /* Setting tuner can only set audio mode */ + cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); + + return 0; +} + +static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + + CX18_DEBUG_IOCTL("VIDIOC_G_TUNER\n"); + + if (vt->index != 0) + return -EINVAL; + + cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); + + if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { + strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); + vt->type = V4L2_TUNER_RADIO; + } else { + strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); + vt->type = V4L2_TUNER_ANALOG_TV; } - case VIDIOC_G_TUNER: { - struct v4l2_tuner *vt = arg; + return 0; +} + +static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, + struct v4l2_sliced_vbi_cap *cap) +{ + return -EINVAL; +} - if (vt->index != 0) - return -EINVAL; +static int cx18_g_enc_index(struct file *file, void *fh, + struct v4l2_enc_idx *idx) +{ + return -EINVAL; +} - memset(vt, 0, sizeof(*vt)); - cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); +static int cx18_encoder_cmd(struct file *file, void *fh, + struct v4l2_encoder_cmd *enc) +{ + struct cx18_open_id *id = fh; + struct cx18 *cx = id->cx; - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { - strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_RADIO; - } else { - strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_ANALOG_TV; - } + CX18_DEBUG_IOCTL("VIDIOC_ENCODER_CMD:\n"); + + memset(&enc->raw, 0, sizeof(enc->raw)); + + switch (enc->cmd) { + case V4L2_ENC_CMD_START: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); + enc->flags = 0; + return cx18_start_capture(id); + + case V4L2_ENC_CMD_STOP: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); + enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; + cx18_stop_capture(id, + enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); break; - } - case VIDIOC_G_SLICED_VBI_CAP: { - struct v4l2_sliced_vbi_cap *cap = arg; - int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; - int f, l; - enum v4l2_buf_type type = cap->type; - - memset(cap, 0, sizeof(*cap)); - cap->type = type; - if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) { - if (valid_service_line(f, l, cx->is_50hz)) - cap->service_lines[f][l] = set; - } - } + case V4L2_ENC_CMD_PAUSE: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); + enc->flags = 0; + if (!atomic_read(&cx->ana_capturing)) + return -EPERM; + if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; - } + cx18_mute(cx); + cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); + break; + + case V4L2_ENC_CMD_RESUME: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); + enc->flags = 0; + if (!atomic_read(&cx->ana_capturing)) + return -EPERM; + if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) + return 0; + cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); + cx18_unmute(cx); + break; + + default: + CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); return -EINVAL; } + return 0; +} - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: { - struct v4l2_encoder_cmd *enc = arg; - int try = cmd == VIDIOC_TRY_ENCODER_CMD; - - memset(&enc->raw, 0, sizeof(enc->raw)); - switch (enc->cmd) { - case V4L2_ENC_CMD_START: - enc->flags = 0; - if (try) - return 0; - return cx18_start_capture(id); - - case V4L2_ENC_CMD_STOP: - enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; - if (try) - return 0; - cx18_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); - return 0; +static int cx18_try_encoder_cmd(struct file *file, void *fh, + struct v4l2_encoder_cmd *enc) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - case V4L2_ENC_CMD_PAUSE: - enc->flags = 0; - if (try) - return 0; - if (!atomic_read(&cx->ana_capturing)) - return -EPERM; - if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) - return 0; - cx18_mute(cx); - cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); - break; - - case V4L2_ENC_CMD_RESUME: - enc->flags = 0; - if (try) - return 0; - if (!atomic_read(&cx->ana_capturing)) - return -EPERM; - if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) - return 0; - cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); - cx18_unmute(cx); - break; - default: - return -EINVAL; - } + CX18_DEBUG_IOCTL("VIDIOC_TRY_ENCDOER_CMD:\n"); + + memset(&enc->raw, 0, sizeof(enc->raw)); + + switch (enc->cmd) { + case V4L2_ENC_CMD_START: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); + enc->flags = 0; break; - } - case VIDIOC_LOG_STATUS: - { - struct v4l2_input vidin; - struct v4l2_audio audin; - int i; + case V4L2_ENC_CMD_STOP: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); + enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; + break; - CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); - if (cx->hw_flags & CX18_HW_TVEEPROM) { - struct tveeprom tv; + case V4L2_ENC_CMD_PAUSE: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); + enc->flags = 0; + break; - cx18_read_eeprom(cx, &tv); - } - cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); - cx18_get_input(cx, cx->active_input, &vidin); - cx18_get_audio_input(cx, cx->audio_input, &audin); - CX18_INFO("Video Input: %s\n", vidin.name); - CX18_INFO("Audio Input: %s\n", audin.name); - CX18_INFO("Tuner: %s\n", - test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? - "Radio" : "TV"); - cx2341x_log_status(&cx->params, cx->name); - CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); - for (i = 0; i < CX18_MAX_STREAMS; i++) { - struct cx18_stream *s = &cx->streams[i]; - - if (s->v4l2dev == NULL || s->buffers == 0) - continue; - CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", - s->name, s->s_flags, - (s->buffers - s->q_free.buffers) * 100 / s->buffers, - (s->buffers * s->buf_size) / 1024, s->buffers); - } - CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", - (long long)cx->mpg_data_received, - (long long)cx->vbi_data_inserted); - CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); + case V4L2_ENC_CMD_RESUME: + CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); + enc->flags = 0; break; - } default: + CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); return -EINVAL; } return 0; } -static int cx18_v4l2_do_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, void *arg) +static int cx18_log_status(struct file *file, void *fh) { - struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; - struct cx18 *cx = id->cx; - int ret; + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + struct v4l2_input vidin; + struct v4l2_audio audin; + int i; - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - case VIDIOC_S_FMT: - case VIDIOC_S_CROP: - case VIDIOC_S_EXT_CTRLS: - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - } + CX18_DEBUG_IOCTL("VIDIOC_LOG_STATUS\n"); + CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); + if (cx->hw_flags & CX18_HW_TVEEPROM) { + struct tveeprom tv; + + cx18_read_eeprom(cx, &tv); + } + cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); + cx18_get_input(cx, cx->active_input, &vidin); + cx18_get_audio_input(cx, cx->audio_input, &audin); + CX18_INFO("Video Input: %s\n", vidin.name); + CX18_INFO("Audio Input: %s\n", audin.name); + CX18_INFO("Tuner: %s\n", + test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); + cx2341x_log_status(&cx->params, cx->name); + CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); + for (i = 0; i < CX18_MAX_STREAMS; i++) { + struct cx18_stream *s = &cx->streams[i]; + + if (s->v4l2dev == NULL || s->buffers == 0) + continue; + CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", + s->name, s->s_flags, + (s->buffers - s->q_free.buffers) * 100 / s->buffers, + (s->buffers * s->buf_size) / 1024, s->buffers); + } + CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", + (long long)cx->mpg_data_received, + (long long)cx->vbi_data_inserted); + CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); + return 0; +} + +static int cx18_default(struct file *file, void *fh, int cmd, void *arg) +{ + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; switch (cmd) { - case VIDIOC_DBG_G_REGISTER: - case VIDIOC_DBG_S_REGISTER: - case VIDIOC_G_CHIP_IDENT: - case VIDIOC_INT_S_AUDIO_ROUTING: - case VIDIOC_INT_RESET: - if (cx18_debug & CX18_DBGFLG_IOCTL) { - printk(KERN_INFO "cx18%d ioctl: ", cx->num); - v4l_printk_ioctl(cmd); - } - return cx18_debug_ioctls(filp, cmd, arg); - - case VIDIOC_G_PRIORITY: - case VIDIOC_S_PRIORITY: - case VIDIOC_QUERYCAP: - case VIDIOC_ENUMINPUT: - case VIDIOC_G_INPUT: - case VIDIOC_S_INPUT: - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - case VIDIOC_ENUM_FMT: - case VIDIOC_CROPCAP: - case VIDIOC_G_CROP: - case VIDIOC_S_CROP: - case VIDIOC_G_FREQUENCY: - case VIDIOC_S_FREQUENCY: - case VIDIOC_ENUMSTD: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_S_TUNER: - case VIDIOC_G_TUNER: - case VIDIOC_ENUMAUDIO: - case VIDIOC_S_AUDIO: - case VIDIOC_G_AUDIO: - case VIDIOC_G_SLICED_VBI_CAP: - case VIDIOC_LOG_STATUS: - case VIDIOC_G_ENC_INDEX: - case VIDIOC_ENCODER_CMD: - case VIDIOC_TRY_ENCODER_CMD: - if (cx18_debug & CX18_DBGFLG_IOCTL) { - printk(KERN_INFO "cx18%d ioctl: ", cx->num); - v4l_printk_ioctl(cmd); - } - return cx18_v4l2_ioctls(cx, filp, cmd, arg); - - case VIDIOC_QUERYMENU: - case VIDIOC_QUERYCTRL: - case VIDIOC_S_CTRL: - case VIDIOC_G_CTRL: - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_G_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: + case VIDIOC_INT_S_AUDIO_ROUTING: { + struct v4l2_routing *route = arg; + CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING (%d, %d)\n", + route->input, route->output); + cx18_audio_set_route(cx, route); + break; + } + case VIDIOC_INT_RESET: { + u32 val = *(u32 *)arg; + CX18_DEBUG_IOCTL("VIDIOC_INT_RESET (%#10x)\n", val); + /* No op right now */ + /* cx18_av_cmd(cx, cmd, arg) */ + /* cx18_call_i2c_clients(cx, cmd, arg) */ + break; + } + default: if (cx18_debug & CX18_DBGFLG_IOCTL) { - printk(KERN_INFO "cx18%d ioctl: ", cx->num); + printk(KERN_INFO "cx18%d ioctl: unsupported cmd: ", + cx->num); v4l_printk_ioctl(cmd); + printk("\n"); } - return cx18_control_ioctls(cx, cmd, arg); - - case 0x00005401: /* Handle isatty() calls */ return -EINVAL; - default: - return v4l_compat_translate_ioctl(inode, filp, cmd, arg, - cx18_v4l2_do_ioctl); } return 0; } @@ -845,7 +840,55 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, int res; mutex_lock(&cx->serialize_lock); - res = video_usercopy(inode, filp, cmd, arg, cx18_v4l2_do_ioctl); + res = video_ioctl2(inode, filp, cmd, arg); mutex_unlock(&cx->serialize_lock); return res; } + +void cx18_set_funcs(struct video_device *vdev) +{ + vdev->vidioc_querycap = cx18_querycap; + vdev->vidioc_g_priority = cx18_g_priority; + vdev->vidioc_s_priority = cx18_s_priority; + vdev->vidioc_s_audio = cx18_s_audio; + vdev->vidioc_g_audio = cx18_g_audio; + vdev->vidioc_enumaudio = cx18_enumaudio; + vdev->vidioc_enum_input = cx18_enum_input; + vdev->vidioc_cropcap = cx18_cropcap; + vdev->vidioc_s_crop = cx18_s_crop; + vdev->vidioc_g_crop = cx18_g_crop; + vdev->vidioc_g_input = cx18_g_input; + vdev->vidioc_s_input = cx18_s_input; + vdev->vidioc_g_frequency = cx18_g_frequency; + vdev->vidioc_s_frequency = cx18_s_frequency; + vdev->vidioc_s_tuner = cx18_s_tuner; + vdev->vidioc_g_tuner = cx18_g_tuner; + vdev->vidioc_g_enc_index = cx18_g_enc_index; + vdev->vidioc_g_std = cx18_g_std; + vdev->vidioc_s_std = cx18_s_std; + vdev->vidioc_log_status = cx18_log_status; + vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap; + vdev->vidioc_encoder_cmd = cx18_encoder_cmd; + vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd; + vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap; + vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap; + vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap; + vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap; + vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap; + vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap; + vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap; + vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap; + vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; + vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; + vdev->vidioc_g_chip_ident = cx18_g_chip_ident; + vdev->vidioc_g_register = cx18_g_register; + vdev->vidioc_s_register = cx18_s_register; + vdev->vidioc_default = cx18_default; + vdev->vidioc_queryctrl = cx18_queryctrl; + vdev->vidioc_querymenu = cx18_querymenu; + vdev->vidioc_g_ctrl = cx18_g_ctrl; + vdev->vidioc_s_ctrl = cx18_s_ctrl; + vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; + vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; + vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; +} diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h index 9f4c7eb2897f..2222f679d86d 100644 --- a/drivers/media/video/cx18/cx18-ioctl.h +++ b/drivers/media/video/cx18/cx18-ioctl.h @@ -24,7 +24,9 @@ u16 cx18_service2vbi(int type); void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt); +void cx18_set_funcs(struct video_device *vdev); +int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); +int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); +int cx18_s_input(struct file *file, void *fh, unsigned int inp); int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, - void *arg); diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 1b921a336092..805847370cba 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -39,6 +39,7 @@ static struct file_operations cx18_v4l2_enc_fops = { .owner = THIS_MODULE, .read = cx18_v4l2_read, .open = cx18_v4l2_open, + /* FIXME change to video_ioctl2 if serialization lock can be removed */ .ioctl = cx18_v4l2_ioctl, .compat_ioctl = v4l_compat_ioctl32, .release = cx18_v4l2_close, @@ -196,7 +197,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) s->v4l2dev->dev = &cx->dev->dev; s->v4l2dev->fops = cx18_stream_info[type].fops; s->v4l2dev->release = video_device_release; - + s->v4l2dev->tvnorms = V4L2_STD_ALL; + cx18_set_funcs(s->v4l2dev); return 0; } -- cgit v1.2.3 From 8bfb9b1ce62757b8dea07c239efbbeec7bac811a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 08:57:42 -0300 Subject: V4L/DVB (8083): videodev: zero fields for ENCODER_CMD and VIDIOC_G_SLICED_VBI_CAP This avoids the need of memsets in the ivtv/cx18 drivers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 9c539eb33811..0d56305c153e 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -1616,26 +1616,26 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_ENCODER_CMD: { - struct v4l2_encoder_cmd *p=arg; + struct v4l2_encoder_cmd *p = arg; if (!vfd->vidioc_encoder_cmd) break; - ret=vfd->vidioc_encoder_cmd(file, fh, p); + memset(&p->raw, 0, sizeof(p->raw)); + ret = vfd->vidioc_encoder_cmd(file, fh, p); if (!ret) - dbgarg (cmd, "cmd=%d, flags=%d\n", - p->cmd,p->flags); + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; } case VIDIOC_TRY_ENCODER_CMD: { - struct v4l2_encoder_cmd *p=arg; + struct v4l2_encoder_cmd *p = arg; if (!vfd->vidioc_try_encoder_cmd) break; - ret=vfd->vidioc_try_encoder_cmd(file, fh, p); + memset(&p->raw, 0, sizeof(p->raw)); + ret = vfd->vidioc_try_encoder_cmd(file, fh, p); if (!ret) - dbgarg (cmd, "cmd=%d, flags=%d\n", - p->cmd,p->flags); + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; } case VIDIOC_G_PARM: @@ -1738,12 +1738,17 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_G_SLICED_VBI_CAP: { - struct v4l2_sliced_vbi_cap *p=arg; + struct v4l2_sliced_vbi_cap *p = arg; + __u32 type = p->type; + if (!vfd->vidioc_g_sliced_vbi_cap) break; - ret=vfd->vidioc_g_sliced_vbi_cap(file, fh, p); + memset(p, 0, sizeof(*p)); + p->type = type; + ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); if (!ret) - dbgarg (cmd, "service_set=%d\n", p->service_set); + dbgarg(cmd, "type=%d, service_set=%d\n", + p->type, p->service_set); break; } case VIDIOC_LOG_STATUS: -- cgit v1.2.3 From 79afcb10dfdd3287875666de34c23510423058b8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 09:02:36 -0300 Subject: V4L/DVB (8084): ivtv/cx18: remove unnecessary memsets & KERNEL_VERSION tests Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 4 ---- drivers/media/video/ivtv/ivtv-ioctl.c | 22 +++++++--------------- 2 files changed, 7 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 70afedf4763f..395382798fb8 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -679,8 +679,6 @@ static int cx18_encoder_cmd(struct file *file, void *fh, CX18_DEBUG_IOCTL("VIDIOC_ENCODER_CMD:\n"); - memset(&enc->raw, 0, sizeof(enc->raw)); - switch (enc->cmd) { case V4L2_ENC_CMD_START: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); @@ -730,8 +728,6 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh, CX18_DEBUG_IOCTL("VIDIOC_TRY_ENCDOER_CMD:\n"); - memset(&enc->raw, 0, sizeof(enc->raw)); - switch (enc->cmd) { case V4L2_ENC_CMD_START: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index e1a31830e9f6..eb4485991a58 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -508,6 +508,11 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format ivtv_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; + if (itv->params.width != 720 || + itv->params.height != (itv->is_50hz ? 576 : 480)) + itv->params.video_temporal_filter = 0; + else + itv->params.video_temporal_filter = 8; return 0; } @@ -762,15 +767,11 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - memset(vcap, 0, sizeof(*vcap)); strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); vcap->version = IVTV_DRIVER_VERSION; /* version */ vcap->capabilities = itv->v4l2_cap; /* capabilities */ - /* reserved.. must set to 0! */ - vcap->reserved[0] = vcap->reserved[1] = - vcap->reserved[2] = vcap->reserved[3] = 0; return 0; } @@ -1168,7 +1169,6 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) if (vt->index != 0) return -EINVAL; - memset(vt, 0, sizeof(*vt)); ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { @@ -1187,11 +1187,8 @@ static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; int f, l; - enum v4l2_buf_type type = cap->type; - memset(cap, 0, sizeof(*cap)); - cap->type = type; - if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { + if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { for (f = 0; f < 2; f++) { for (l = 0; l < 24; l++) { if (valid_service_line(f, l, itv->is_50hz)) @@ -1200,7 +1197,7 @@ static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced } return 0; } - if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { + if (cap->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) return -EINVAL; if (itv->is_60hz) { @@ -1243,7 +1240,6 @@ static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; - memset(&enc->raw, 0, sizeof(enc->raw)); switch (enc->cmd) { case V4L2_ENC_CMD_START: @@ -1295,8 +1291,6 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - memset(&enc->raw, 0, sizeof(enc->raw)); - switch (enc->cmd) { case V4L2_ENC_CMD_START: IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); @@ -1349,8 +1343,6 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 0, }; - memset(fb, 0, sizeof(*fb)); - if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; -- cgit v1.2.3 From 5cf2cc4803a0415f7048951a727204df414325e6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 09:06:59 -0300 Subject: V4L/DVB (8085): ivtv: fill in all v4l2_framebuffer fields in VIDIOC_G/S_FBUF Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index eb4485991a58..d75c82e509f7 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1356,7 +1356,15 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) fb->fmt.pixelformat = pixel_format[pixfmt]; fb->fmt.width = itv->osd_rect.width; fb->fmt.height = itv->osd_rect.height; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->fmt.bytesperline = fb->fmt.width; + if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8) + fb->fmt.bytesperline *= 2; + if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 || + fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32) + fb->fmt.bytesperline *= 2; fb->base = (void *)itv->osd_video_pbase; + fb->flags = 0; if (itv->osd_chroma_key_state) fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; @@ -1404,8 +1412,7 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; ivtv_set_osd_alpha(itv); yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0; - - return 0; + return ivtv_g_fbuf(file, fh, fb); } static int ivtv_overlay(struct file *file, void *fh, unsigned int on) -- cgit v1.2.3 From e27bf207db4fc6dd500eb82611f102da85cfe7d0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 09:21:23 -0300 Subject: V4L/DVB (8086): ivtv/cx18: fix video_temporal_filter handling If the capture is scaled, then the video_temporal_filter is set to 0 by the cx2341x.c module since otherwise you would get ghosting. However, this was also done in the VIDIOC_S_FMT ioctl which meant that the video_temporal_filter control was reset to 0 or 8 each time S_FMT was called. This was old code that should have been removed a long time ago. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 4 ---- drivers/media/video/ivtv/ivtv-ioctl.c | 9 --------- 2 files changed, 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 395382798fb8..f66ca0b39520 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -244,10 +244,6 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, cx->params.width = w; cx->params.height = h; - if (w != 720 || h != (cx->is_50hz ? 576 : 480)) - cx->params.video_temporal_filter = 0; - else - cx->params.video_temporal_filter = 8; cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); return cx18_g_fmt_vid_cap(file, fh, fmt); } diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index d75c82e509f7..b1cda6cd5582 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -508,11 +508,6 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format ivtv_g_fmt_vid_cap(file, fh, fmt); fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; - if (itv->params.width != 720 || - itv->params.height != (itv->is_50hz ? 576 : 480)) - itv->params.video_temporal_filter = 0; - else - itv->params.video_temporal_filter = 8; return 0; } @@ -608,10 +603,6 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f p->width = w; p->height = h; - if (w != 720 || h != (itv->is_50hz ? 576 : 480)) - p->video_temporal_filter = 0; - else - p->video_temporal_filter = 8; if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) fmt->fmt.pix.width /= 2; itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); -- cgit v1.2.3 From 0b5a30e90ddcb0095a1bfc4b44eb3fd1e8ee9f3c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 09:22:19 -0300 Subject: V4L/DVB (8087): cx18: make sure all v4l2_format fields are filled in Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 44 ++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index f66ca0b39520..19618bdcdde1 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -137,22 +137,24 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; + struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; - CX18_DEBUG_IOCTL("VIDIOC_G_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - - fmt->fmt.pix.width = cx->params.width; - fmt->fmt.pix.height = cx->params.height; - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; - fmt->fmt.pix.field = V4L2_FIELD_INTERLACED; + pixfmt->width = cx->params.width; + pixfmt->height = cx->params.height; + pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; + pixfmt->field = V4L2_FIELD_INTERLACED; + pixfmt->priv = 0; if (id->type == CX18_ENC_STREAM_TYPE_YUV) { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12; + pixfmt->pixelformat = V4L2_PIX_FMT_HM12; /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - fmt->fmt.pix.sizeimage = - fmt->fmt.pix.height * fmt->fmt.pix.width + - fmt->fmt.pix.height * (fmt->fmt.pix.width / 2); + pixfmt->sizeimage = + pixfmt->height * pixfmt->width + + pixfmt->height * (pixfmt->width / 2); + pixfmt->bytesperline = 720; } else { - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - fmt->fmt.pix.sizeimage = 128 * 1024; + pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; + pixfmt->sizeimage = 128 * 1024; + pixfmt->bytesperline = 0; } return 0; } @@ -161,16 +163,20 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; CX18_DEBUG_IOCTL("VIDIOC_G_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - fmt->fmt.vbi.sampling_rate = 27000000; - fmt->fmt.vbi.offset = 248; - fmt->fmt.vbi.samples_per_line = cx->vbi.raw_decoder_line_size - 4; - fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - fmt->fmt.vbi.start[0] = cx->vbi.start[0]; - fmt->fmt.vbi.start[1] = cx->vbi.start[1]; - fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = cx->vbi.count; + vbifmt->sampling_rate = 27000000; + vbifmt->offset = 248; + vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; + vbifmt->sample_format = V4L2_PIX_FMT_GREY; + vbifmt->start[0] = cx->vbi.start[0]; + vbifmt->start[1] = cx->vbi.start[1]; + vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count; + vbifmt->flags = 0; + vbifmt->reserved[0] = 0; + vbifmt->reserved[1] = 0; return 0; } -- cgit v1.2.3 From 464e9f3a0cabce9a7cf51f382f129d464483b0d0 Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sat, 21 Jun 2008 09:25:23 -0300 Subject: V4L/DVB (8088): ivtv: yuv decoder lock fix write() operations to the yuv device may not always 'start' the decoder. Although yuv output will be correct, some functions which should be disabled while the decoder is in use remain enabled. This can result in hardware registers being corrupted, causing problems with the mpeg decoder. This patch simply moves the existing decoder 'start' sequence to earlier in the write() handler. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-fileops.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index db813e071ce6..7ec5c99f9ad1 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c @@ -582,6 +582,19 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c ivtv_queue_init(&q); set_bit(IVTV_F_S_APPL_IO, &s->s_flags); + /* Start decoder (returns 0 if already started) */ + mutex_lock(&itv->serialize_lock); + rc = ivtv_start_decoding(id, itv->speed); + mutex_unlock(&itv->serialize_lock); + if (rc) { + IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); + + /* failure, clean up */ + clear_bit(IVTV_F_S_STREAMING, &s->s_flags); + clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); + return rc; + } + retry: /* If possible, just DMA the entire frame - Check the data transfer size since we may get here before the stream has been fully set-up */ @@ -664,18 +677,6 @@ retry: ivtv_enqueue(s, buf, &s->q_full); } - /* Start decoder (returns 0 if already started) */ - mutex_lock(&itv->serialize_lock); - rc = ivtv_start_decoding(id, itv->speed); - mutex_unlock(&itv->serialize_lock); - if (rc) { - IVTV_DEBUG_WARN("Failed start decode stream %s\n", s->name); - - /* failure, clean up */ - clear_bit(IVTV_F_S_STREAMING, &s->s_flags); - clear_bit(IVTV_F_S_APPL_IO, &s->s_flags); - return rc; - } if (test_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags)) { if (s->q_full.length >= itv->dma_data_req_size) { int got_sig; -- cgit v1.2.3 From 03c2808503b102971226007070c57410267d0b9d Mon Sep 17 00:00:00 2001 From: Sri Deevi Date: Sat, 21 Jun 2008 11:06:44 -0300 Subject: V4L/DVB (8089): cx18: add support for Conexant Raptor PAL/SECAM card Patch provided courtesy of Conexant http://www.conexant.com. Signed-off-by: Srinivasa Deevi Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 55 ++++++++++++++++++++++++++++++++++ drivers/media/video/cx18/cx18-cards.h | 8 +++++ drivers/media/video/cx18/cx18-driver.c | 3 +- drivers/media/video/cx18/cx18-driver.h | 4 ++- drivers/media/video/cx18/cx18-gpio.c | 34 +++++++++++++++++++++ drivers/media/video/cx18/cx18-gpio.h | 1 + drivers/media/video/cx18/cx18-i2c.c | 20 ++++++++++++- 7 files changed, 122 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index c26e0ef5b075..90857bedccae 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -27,6 +27,8 @@ #include "cx18-i2c.h" #include +#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM) + /********************** card configuration *******************************/ /* usual i2c tuner addresses to probe */ @@ -232,11 +234,64 @@ static const struct cx18_card cx18_card_mpc718 = { .i2c = &cx18_i2c_std, }; +/* ------------------------------------------------------------------------- */ + +/* Conexant Raptor PAL/SECAM: note that this card is analog only! */ + +static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { + { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 }, + { 0, 0, 0 } +}; + +static const struct cx18_card cx18_card_cnxt_raptor_pal = { + .type = CX18_CARD_CNXT_RAPTOR_PAL, + .name = "Conexant Raptor PAL/SECAM", + .comment = "VBI is not yet supported\n", + .v4l2_capabilities = CX18_CAP_ENCODER, + .hw_audio_ctrl = CX18_HW_CX23418, + .hw_muxer = CX18_HW_GPIO, + .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, + .video_inputs = { + { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, + { CX18_CARD_INPUT_SVIDEO1, 1, + CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, + { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, + { CX18_CARD_INPUT_SVIDEO2, 2, + CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, + { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, + }, + .audio_inputs = { + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 1 }, + { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, + }, + .tuners = { + { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + }, + .ddr = { + /* MT 46V16M16 memory */ + .chip_config = 0x50306, + .refresh = 0x753, + .timing1 = 0x33220953, + .timing2 = 0x09, + .tune_lane = 0, + .initial_emrs = 0, + }, + .gpio_init.initial_value = 0x02, + .gpio_init.direction = 0x02, + .gpio_audio_input = { .mask = 0x02, .tuner = 0x02, .linein = 0x00 }, + .pci_list = cx18_pci_cnxt_raptor_pal, + .i2c = &cx18_i2c_std, +}; + +/* ------------------------------------------------------------------------- */ + static const struct cx18_card *cx18_card_list[] = { &cx18_card_hvr1600_esmt, &cx18_card_hvr1600_samsung, &cx18_card_h900, &cx18_card_mpc718, + &cx18_card_cnxt_raptor_pal, }; const struct cx18_card *cx18_get_card(u16 index) diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index dc2dd945d4c3..b5f894c0afa9 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -85,6 +85,13 @@ struct cx18_gpio_i2c_slave_reset { int msecs_recovery; /* time after deassert for chips to be ready */ }; +struct ivtv_gpio_audio_input { /* select tuner/line in input */ + u32 mask; /* leave to 0 if not supported */ + u32 tuner; + u32 linein; + u32 radio; +}; + struct cx18_card_tuner { v4l2_std_id std; /* standard for which the tuner is suitable */ int tuner; /* tuner ID (from tuner.h) */ @@ -123,6 +130,7 @@ struct cx18_card { u8 xceive_pin; /* XCeive tuner GPIO reset pin */ struct cx18_gpio_init gpio_init; struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; + struct ivtv_gpio_audio_input gpio_audio_input; struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; struct cx18_card_tuner_i2c *i2c; diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e9c7e07b9fed..71bb04ab91d7 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -120,6 +120,7 @@ MODULE_PARM_DESC(cardtype, "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n" "\t\t\t 3 = Compro VideoMate H900\n" "\t\t\t 4 = Yuan MPC718\n" + "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" "\t\t\t 0 = Autodetect (default)\n" "\t\t\t-1 = Ignore this card\n\t\t"); MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); @@ -435,7 +436,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) (cx->params.video_temporal_filter_mode << 1) | (cx->params.video_median_filter_type << 2); cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI; + cx->params.capabilities = 0; init_waitqueue_head(&cx->cap_w); init_waitqueue_head(&cx->mb_apu_waitq); init_waitqueue_head(&cx->mb_cpu_waitq); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index de14ab59a206..b421e0268b00 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -75,7 +75,8 @@ #define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */ #define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ #define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ -#define CX18_CARD_LAST 3 +#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ +#define CX18_CARD_LAST 4 #define CX18_ENC_STREAM_TYPE_MPG 0 #define CX18_ENC_STREAM_TYPE_TS 1 @@ -94,6 +95,7 @@ #define CX18_PCI_ID_HAUPPAUGE 0x0070 #define CX18_PCI_ID_COMPRO 0x185b #define CX18_PCI_ID_YUAN 0x12ab +#define CX18_PCI_ID_CONEXANT 0x14f1 /* ======================================================================== */ /* ========================== START USER SETTABLE DMA VARIABLES =========== */ diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index b302833f6f9d..089bad6d85a0 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -122,3 +122,37 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } + +int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) +{ + struct v4l2_routing *route = arg; + u32 mask, data; + + switch (command) { + case VIDIOC_INT_S_AUDIO_ROUTING: + if (route->input > 2) + return -EINVAL; + mask = cx->card->gpio_audio_input.mask; + switch (route->input) { + case 0: + data = cx->card->gpio_audio_input.tuner; + break; + case 1: + data = cx->card->gpio_audio_input.linein; + break; + case 2: + default: + data = cx->card->gpio_audio_input.radio; + break; + } + break; + + default: + return -EINVAL; + } + if (mask) { + cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); + gpio_write(cx); + } + return 0; +} diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index 525c328f748a..7447fed35767 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h @@ -23,3 +23,4 @@ void cx18_gpio_init(struct cx18 *cx); void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); int cx18_reset_tuner_gpio(void *dev, int cmd, int value); +int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 680bc4e35b79..bca905901d61 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -311,8 +311,12 @@ int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) { int addr; - if (hw == CX18_HW_GPIO || hw == 0) + if (hw == 0) return 0; + + if (hw == CX18_HW_GPIO) + return cx18_gpio(cx, cmd, arg); + if (hw == CX18_HW_CX23418) return cx18_av_cmd(cx, cmd, arg); @@ -350,6 +354,8 @@ void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) cx18_av_cmd(cx, cmd, arg); i2c_clients_command(&cx->i2c_adap[0], cmd, arg); i2c_clients_command(&cx->i2c_adap[1], cmd, arg); + if (cx->hw_flags & CX18_HW_GPIO) + cx18_gpio(cx, cmd, arg); } /* init + register i2c algo-bit adapter */ @@ -358,6 +364,18 @@ int init_cx18_i2c(struct cx18 *cx) int i; CX18_DEBUG_I2C("i2c init\n"); + /* Sanity checks for the I2C hardware arrays. They must be the + * same size and GPIO/CX23418 must be the last entries. + */ + if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || + ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || + CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) || + CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || + hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) { + CX18_ERR("Mismatched I2C hardware arrays\n"); + return -ENODEV; + } + for (i = 0; i < 2; i++) { memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template, sizeof(struct i2c_adapter)); -- cgit v1.2.3 From 42b03fe16fe8cc2cd6575e25ed1872fd6f5da56f Mon Sep 17 00:00:00 2001 From: Ian Armstrong Date: Sat, 21 Jun 2008 11:09:46 -0300 Subject: V4L/DVB (8090): ivtv: yuv decoder lock fix (2) The IVTV_IOC_DMA_FRAME ioctl fails to correctly 'start' the decoder. Although yuv output will be correct, some functions which should be disabled while the decoder is in use remain enabled. This can result in hardware registers being corrupted, causing problems with the mpeg decoder. This patch ensures the decoder 'start' sequence is called, disabling these functions until the device is closed. Signed-off-by: Ian Armstrong Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index b1cda6cd5582..aa222056dd47 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1539,7 +1539,7 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) return -EINVAL; if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL) return 0; - if (ivtv_claim_stream(id, id->type)) { + if (ivtv_start_decoding(id, id->type)) { return -EBUSY; } if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) { -- cgit v1.2.3 From 3d66c405708ee43b08788e89dbd63ebf3bbb5af1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 11:19:34 -0300 Subject: V4L/DVB (8091): cx18: show GPIO pins when VIDIOC_LOG_STATUS is called. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 19618bdcdde1..cfda54d022e0 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -777,6 +777,8 @@ static int cx18_log_status(struct file *file, void *fh) cx18_get_audio_input(cx, cx->audio_input, &audin); CX18_INFO("Video Input: %s\n", vidin.name); CX18_INFO("Audio Input: %s\n", audin.name); + CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", + cx->gpio_dir, cx->gpio_val); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&cx->params, cx->name); -- cgit v1.2.3 From fdea5d69c1d335a639e39e83990de84e10fb2057 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 21 Jun 2008 13:25:36 -0300 Subject: V4L/DVB (8093): cx18: fix prefix typo Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index b5f894c0afa9..dc283d756907 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -85,7 +85,7 @@ struct cx18_gpio_i2c_slave_reset { int msecs_recovery; /* time after deassert for chips to be ready */ }; -struct ivtv_gpio_audio_input { /* select tuner/line in input */ +struct cx18_gpio_audio_input { /* select tuner/line in input */ u32 mask; /* leave to 0 if not supported */ u32 tuner; u32 linein; @@ -130,7 +130,7 @@ struct cx18_card { u8 xceive_pin; /* XCeive tuner GPIO reset pin */ struct cx18_gpio_init gpio_init; struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; - struct ivtv_gpio_audio_input gpio_audio_input; + struct cx18_gpio_audio_input gpio_audio_input; struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; struct cx18_card_tuner_i2c *i2c; -- cgit v1.2.3 From fa1035997cbba4c348a88f8b94eb135222aaba12 Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 21 Jun 2008 14:30:33 -0300 Subject: V4L/DVB (8095): zoran_driver.c: Removed duplicated include Removed duplicated include file in drivers/media/video/zoran_driver.c. Signed-off-by: Huang Weiyi Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_driver.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 5394d7a5cfee..8764c352061d 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -94,7 +94,6 @@ V4L2_CAP_VIDEO_OVERLAY \ ) -#include #if defined(CONFIG_VIDEO_V4L1_COMPAT) #define ZFMT(pal, fcc, cs) \ -- cgit v1.2.3 From 7dc1b8844eb3e0a91911f20736db87f4876e14b4 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 21 Jun 2008 22:13:42 -0300 Subject: V4L/DVB (8098): xc5000: add module option to load firmware during driver attach The xc5000 firmware download process can be slow on certain devices. Add a module option, "init_fw" to perform the firmware download during xc5000_attach(), which would get the firmware download over with well before any tune request is made. When this option is enabled, it will reduce the time it takes to get a signal lock during the first tune after driver load, but will add a few seconds to the driver initialization. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/xc5000.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 4878d6477a8c..5f99de0ad612 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c @@ -36,6 +36,10 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +static int xc5000_load_fw_on_attach; +module_param_named(init_fw, xc5000_load_fw_on_attach, int, 0644); +MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization."); + #define dprintk(level,fmt, arg...) if (debug >= level) \ printk(KERN_INFO "%s: " fmt, "xc5000", ## arg) @@ -972,6 +976,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, fe->tuner_priv = priv; + if (xc5000_load_fw_on_attach) + xc5000_init(fe); + return fe; } EXPORT_SYMBOL(xc5000_attach); -- cgit v1.2.3 From 21575c13125f2ef790e192e2c70e446c6cfe0d7d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 22 Jun 2008 11:55:09 -0300 Subject: V4L/DVB (8103): videodev: fix/improve ioctl debugging Various ioctl debugging fixes and improvements: - use %x rather than %d for control IDs and bitmask fields - make two arrays const - show the whole control array for the ext_ctrl ioctls - print pix_fmt for V4L2_BUF_TYPE_VIDEO_OUTPUT - show full type name rather than an integer - fix CROPCAP debugging - fix G/S_TUNER debugging - show error code in case of an error - other small cleanups Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 259 +++++++++++++++++++++++------------------ include/media/v4l2-dev.h | 4 +- 2 files changed, 150 insertions(+), 113 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 0d56305c153e..91902d52d022 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -17,15 +17,19 @@ */ #define dbgarg(cmd, fmt, arg...) \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ printk(KERN_DEBUG "%s: ", vfd->name); \ v4l_printk_ioctl(cmd); \ printk(" " fmt, ## arg); \ - } + } \ + } while (0) #define dbgarg2(fmt, arg...) \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg); + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ + printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ + } while (0) #include #include @@ -138,7 +142,7 @@ EXPORT_SYMBOL(v4l2_video_std_construct); /* ----------------------------------------------------------------- */ /* some arrays for pretty-printing debug messages of enum types */ -char *v4l2_field_names[] = { +const char *v4l2_field_names[] = { [V4L2_FIELD_ANY] = "any", [V4L2_FIELD_NONE] = "none", [V4L2_FIELD_TOP] = "top", @@ -152,19 +156,19 @@ char *v4l2_field_names[] = { }; EXPORT_SYMBOL(v4l2_field_names); -char *v4l2_type_names[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "video-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "video-over", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "video-out", +const char *v4l2_type_names[] = { + [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", + [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", + [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "video-out-over", + [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", }; EXPORT_SYMBOL(v4l2_type_names); -static char *v4l2_memory_names[] = { +static const char *v4l2_memory_names[] = { [V4L2_MEMORY_MMAP] = "mmap", [V4L2_MEMORY_USERPTR] = "userptr", [V4L2_MEMORY_OVERLAY] = "overlay", @@ -660,7 +664,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, p->field, p->sequence, prt_names(p->memory, v4l2_memory_names), p->m.userptr, p->length); - dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " + dbgarg2("timecode=%02d:%02d:%02d type=%d, " "flags=0x%08d, frames=%d, userbits=0x%08x\n", tc->hours,tc->minutes,tc->seconds, tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); @@ -669,7 +673,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, static inline void dbgrect(struct video_device *vfd, char *s, struct v4l2_rect *r) { - dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top, + dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, r->width, r->height); }; @@ -687,6 +691,25 @@ static inline void v4l_print_pix_fmt (struct video_device *vfd, fmt->bytesperline, fmt->sizeimage, fmt->colorspace); }; +static inline void v4l_print_ext_ctrls(unsigned int cmd, + struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) +{ + __u32 i; + + if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) + return; + dbgarg(cmd, ""); + printk(KERN_CONT "class=0x%x", c->ctrl_class); + for (i = 0; i < c->count; i++) { + if (show_vals) + printk(KERN_CONT " id/val=0x%x/0x%x", + c->controls[i].id, c->controls[i].value); + else + printk(KERN_CONT " id=0x%x", c->controls[i].id); + } + printk(KERN_CONT "\n"); +}; + static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) { @@ -894,7 +917,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (vfd->vidioc_g_fmt_vid_cap) ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); if (!ret) - v4l_print_pix_fmt(vfd,&f->fmt.pix); + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_g_fmt_vid_overlay) @@ -904,6 +927,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_g_fmt_vid_out) ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_g_fmt_vid_out_overlay) @@ -942,12 +967,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_format *f = (struct v4l2_format *)arg; /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names)); + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - v4l_print_pix_fmt(vfd,&f->fmt.pix); + v4l_print_pix_fmt(vfd, &f->fmt.pix); if (vfd->vidioc_s_fmt_vid_cap) ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); break; @@ -957,6 +981,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: + v4l_print_pix_fmt(vfd, &f->fmt.pix); if (vfd->vidioc_s_fmt_vid_out) ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); break; @@ -1003,7 +1028,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (vfd->vidioc_try_fmt_vid_cap) ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); if (!ret) - v4l_print_pix_fmt(vfd,&f->fmt.pix); + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_try_fmt_vid_overlay) @@ -1013,6 +1038,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_try_fmt_vid_out) ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_try_fmt_vid_out_overlay) @@ -1123,29 +1150,29 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_G_FBUF: { - struct v4l2_framebuffer *p=arg; + struct v4l2_framebuffer *p = arg; + if (!vfd->vidioc_g_fbuf) break; - ret=vfd->vidioc_g_fbuf(file, fh, arg); + ret = vfd->vidioc_g_fbuf(file, fh, arg); if (!ret) { - dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", - p->capability,p->flags, + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, (unsigned long)p->base); - v4l_print_pix_fmt (vfd, &p->fmt); + v4l_print_pix_fmt(vfd, &p->fmt); } break; } case VIDIOC_S_FBUF: { - struct v4l2_framebuffer *p=arg; + struct v4l2_framebuffer *p = arg; + if (!vfd->vidioc_s_fbuf) break; - - dbgarg (cmd, "capability=%d, flags=%d, base=0x%08lx\n", - p->capability,p->flags,(unsigned long)p->base); - v4l_print_pix_fmt (vfd, &p->fmt); - ret=vfd->vidioc_s_fbuf(file, fh, arg); - + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, (unsigned long)p->base); + v4l_print_pix_fmt(vfd, &p->fmt); + ret = vfd->vidioc_s_fbuf(file, fh, arg); break; } case VIDIOC_STREAMON: @@ -1197,7 +1224,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, v4l2_video_std_construct(p, curr_id, descr); p->index = index; - dbgarg(cmd, "index=%d, id=%Ld, name=%s, fps=%d/%d, " + dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " "framelines=%d\n", p->index, (unsigned long long)p->id, p->name, p->frameperiod.numerator, @@ -1219,14 +1246,14 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, *id = vfd->current_norm; if (!ret) - dbgarg(cmd, "value=%08Lx\n", (long long unsigned)*id); + dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); break; } case VIDIOC_S_STD: { v4l2_std_id *id = arg,norm; - dbgarg (cmd, "value=%08Lx\n", (long long unsigned) *id); + dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); norm = (*id) & vfd->tvnorms; if ( vfd->tvnorms && !norm) /* Check if std is supported */ @@ -1315,8 +1342,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret = vfd->vidioc_enum_output(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " - "audioset=%d, " - "modulator=%d, std=%08Lx\n", + "audioset=0x%x, " + "modulator=%d, std=0x%08Lx\n", p->index, p->name, p->type, p->audioset, p->modulator, (unsigned long long)p->std); break; @@ -1346,19 +1373,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, /* --- controls ---------------------------------------------- */ case VIDIOC_QUERYCTRL: { - struct v4l2_queryctrl *p=arg; + struct v4l2_queryctrl *p = arg; if (!vfd->vidioc_queryctrl) break; - ret=vfd->vidioc_queryctrl(file, fh, p); - + ret = vfd->vidioc_queryctrl(file, fh, p); if (!ret) - dbgarg (cmd, "id=%d, type=%d, name=%s, " - "min/max=%d/%d," - " step=%d, default=%d, flags=0x%08x\n", - p->id,p->type,p->name,p->minimum, - p->maximum,p->step,p->default_value, - p->flags); + dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " + "step=%d, default=%d, flags=0x%08x\n", + p->id, p->type, p->name, + p->minimum, p->maximum, + p->step, p->default_value, p->flags); + else + dbgarg(cmd, "id=0x%x\n", p->id); break; } case VIDIOC_G_CTRL: @@ -1367,11 +1394,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_g_ctrl) break; - dbgarg(cmd, "Enum for index=%d\n", p->id); - ret=vfd->vidioc_g_ctrl(file, fh, p); + ret = vfd->vidioc_g_ctrl(file, fh, p); if (!ret) - dbgarg2 ( "id=%d, value=%d\n", p->id, p->value); + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); + else + dbgarg(cmd, "id=0x%x\n", p->id); break; } case VIDIOC_S_CTRL: @@ -1380,20 +1408,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_s_ctrl) break; - dbgarg (cmd, "id=%d, value=%d\n", p->id, p->value); + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - ret=vfd->vidioc_s_ctrl(file, fh, p); + ret = vfd->vidioc_s_ctrl(file, fh, p); break; } case VIDIOC_G_EXT_CTRLS: { struct v4l2_ext_controls *p = arg; - if (vfd->vidioc_g_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); - - ret=vfd->vidioc_g_ext_ctrls(file, fh, p); - } + if (!vfd->vidioc_g_ext_ctrls) + break; + ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; } case VIDIOC_S_EXT_CTRLS: @@ -1401,9 +1428,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; if (vfd->vidioc_s_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); + v4l_print_ext_ctrls(cmd, vfd, p, 1); - ret=vfd->vidioc_s_ext_ctrls(file, fh, p); + ret = vfd->vidioc_s_ext_ctrls(file, fh, p); } break; } @@ -1412,66 +1439,72 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; if (vfd->vidioc_try_ext_ctrls) { - dbgarg(cmd, "count=%d\n", p->count); + v4l_print_ext_ctrls(cmd, vfd, p, 1); - ret=vfd->vidioc_try_ext_ctrls(file, fh, p); + ret = vfd->vidioc_try_ext_ctrls(file, fh, p); } break; } case VIDIOC_QUERYMENU: { - struct v4l2_querymenu *p=arg; + struct v4l2_querymenu *p = arg; + if (!vfd->vidioc_querymenu) break; - ret=vfd->vidioc_querymenu(file, fh, p); + ret = vfd->vidioc_querymenu(file, fh, p); if (!ret) - dbgarg (cmd, "id=%d, index=%d, name=%s\n", - p->id,p->index,p->name); + dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", + p->id, p->index, p->name); + else + dbgarg(cmd, "id=0x%x, index=%d\n", + p->id, p->index); break; } /* --- audio ---------------------------------------------- */ case VIDIOC_ENUMAUDIO: { - struct v4l2_audio *p=arg; + struct v4l2_audio *p = arg; if (!vfd->vidioc_enumaudio) break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_enumaudio(file, fh, p); + ret = vfd->vidioc_enumaudio(file, fh, p); if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n",p->index,p->name, + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); break; } case VIDIOC_G_AUDIO: { - struct v4l2_audio *p=arg; - __u32 index=p->index; + struct v4l2_audio *p = arg; + __u32 index = p->index; if (!vfd->vidioc_g_audio) break; - memset(p,0,sizeof(*p)); - p->index=index; - dbgarg(cmd, "Get for index=%d\n", p->index); - ret=vfd->vidioc_g_audio(file, fh, p); + memset(p, 0, sizeof(*p)); + p->index = index; + ret = vfd->vidioc_g_audio(file, fh, p); if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n",p->index, - p->name,p->capability, p->mode); + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, + p->name, p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); break; } case VIDIOC_S_AUDIO: { - struct v4l2_audio *p=arg; + struct v4l2_audio *p = arg; if (!vfd->vidioc_s_audio) break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, p->capability, p->mode); - ret=vfd->vidioc_s_audio(file, fh, p); + ret = vfd->vidioc_s_audio(file, fh, p); break; } case VIDIOC_ENUMAUDOUT: @@ -1547,9 +1580,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_crop *p=arg; if (!vfd->vidioc_g_crop) break; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); ret=vfd->vidioc_g_crop(file, fh, p); if (!ret) { - dbgarg(cmd, "type=%d\n", p->type); dbgrect(vfd, "", &p->c); } break; @@ -1559,21 +1592,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_crop *p=arg; if (!vfd->vidioc_s_crop) break; - dbgarg(cmd, "type=%d\n", p->type); + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); dbgrect(vfd, "", &p->c); ret=vfd->vidioc_s_crop(file, fh, p); break; } case VIDIOC_CROPCAP: { - struct v4l2_cropcap *p=arg; + struct v4l2_cropcap *p = arg; + /*FIXME: Should also show v4l2_fract pixelaspect */ if (!vfd->vidioc_cropcap) break; - dbgarg(cmd, "type=%d\n", p->type); - dbgrect(vfd, "bounds ", &p->bounds); - dbgrect(vfd, "defrect ", &p->defrect); - ret=vfd->vidioc_cropcap(file, fh, p); + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + ret = vfd->vidioc_cropcap(file, fh, p); + if (!ret) { + dbgrect(vfd, "bounds ", &p->bounds); + dbgrect(vfd, "defrect ", &p->defrect); + } break; } case VIDIOC_G_JPEGCOMP: @@ -1675,40 +1711,42 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } case VIDIOC_G_TUNER: { - struct v4l2_tuner *p=arg; - __u32 index=p->index; + struct v4l2_tuner *p = arg; + __u32 index = p->index; if (!vfd->vidioc_g_tuner) break; - memset(p,0,sizeof(*p)); - p->index=index; + memset(p, 0, sizeof(*p)); + p->index = index; - ret=vfd->vidioc_g_tuner(file, fh, p); + ret = vfd->vidioc_g_tuner(file, fh, p); if (!ret) - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "capability=%d, rangelow=%d, " + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " "rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=%d, audmode=%d\n", + "rxsubchans=0x%x, audmode=%d\n", p->index, p->name, p->type, p->capability, p->rangelow, - p->rangehigh, p->rxsubchans, - p->audmode, p->signal, p->afc); + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); break; } case VIDIOC_S_TUNER: { - struct v4l2_tuner *p=arg; + struct v4l2_tuner *p = arg; + if (!vfd->vidioc_s_tuner) break; - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "capability=%d, rangelow=%d, rangehigh=%d, " - "signal=%d, afc=%d, rxsubchans=%d, " - "audmode=%d\n",p->index, p->name, p->type, - p->capability, p->rangelow,p->rangehigh, - p->rxsubchans, p->audmode, p->signal, - p->afc); - ret=vfd->vidioc_s_tuner(file, fh, p); + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " + "rxsubchans=0x%x, audmode=%d\n", + p->index, p->name, p->type, + p->capability, p->rangelow, + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); + ret = vfd->vidioc_s_tuner(file, fh, p); break; } case VIDIOC_G_FREQUENCY: @@ -1745,10 +1783,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, break; memset(p, 0, sizeof(*p)); p->type = type; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); if (!ret) - dbgarg(cmd, "type=%d, service_set=%d\n", - p->type, p->service_set); + dbgarg2("service_set=%d\n", p->service_set); break; } case VIDIOC_LOG_STATUS: @@ -1809,10 +1847,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, } /* switch */ if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { - if (ret<0) { - printk("%s: err: on ", vfd->name); + if (ret < 0) { v4l_print_ioctl(vfd->name, cmd); - printk("\n"); + printk(KERN_CONT " error %d\n", ret); } } diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 9e6e4f18e948..3c934142f7f9 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -59,8 +59,8 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local); /* names for fancy debug output */ -extern char *v4l2_field_names[]; -extern char *v4l2_type_names[]; +extern const char *v4l2_field_names[]; +extern const char *v4l2_type_names[]; /* Compatibility layer interface -- v4l1-compat module */ typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, -- cgit v1.2.3 From 37f89f9542c3945bddf46efc15a1b1e349af3f88 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 22 Jun 2008 11:57:31 -0300 Subject: V4L/DVB (8104): cx18/ivtv: ioctl debugging improvements Completely rely on the video_ioctl2 debugging facilities rather than doing it ourselves. Fill in some missing fields in ivtv with VIDIOC_G_FBUF. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-controls.c | 16 +----- drivers/media/video/cx18/cx18-ioctl.c | 87 +++----------------------------- drivers/media/video/cx18/cx18-streams.c | 4 +- drivers/media/video/ivtv/ivtv-controls.c | 16 +----- drivers/media/video/ivtv/ivtv-ioctl.c | 21 +++++--- drivers/media/video/ivtv/ivtv-streams.c | 4 +- drivers/media/video/ivtv/ivtvfb.c | 3 ++ 7 files changed, 33 insertions(+), 118 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 6eae75f4ee7c..01ba9ca37d09 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -56,8 +56,6 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; const char *name; - CX18_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); if (qctrl->id == 0) return -EINVAL; @@ -94,10 +92,8 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_queryctrl qctrl; - CX18_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); qctrl.id = qmenu->id; cx18_queryctrl(file, fh, &qctrl); return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); @@ -108,14 +104,11 @@ int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; int ret; - s32 v = vctrl->value; ret = v4l2_prio_check(&cx->prio, &id->prio); if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -133,7 +126,7 @@ int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl); default: - CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id); + CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); return -EINVAL; } return 0; @@ -143,8 +136,6 @@ int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -161,7 +152,7 @@ int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) case V4L2_CID_AUDIO_LOUDNESS: return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl); default: - CX18_DEBUG_IOCTL("invalid control %x\n", vctrl->id); + CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); return -EINVAL; } return 0; @@ -227,7 +218,6 @@ int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) } return err; } - CX18_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS); return -EINVAL; @@ -260,7 +250,6 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) } return err; } - CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { struct cx2341x_mpeg_params p = cx->params; int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), @@ -296,7 +285,6 @@ int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&cx->params, atomic_read(&cx->ana_capturing), diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index cfda54d022e0..7231f60a180b 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -165,8 +165,6 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; - CX18_DEBUG_IOCTL("VIDIOC_G_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - vbifmt->sampling_rate = 27000000; vbifmt->offset = 248; vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; @@ -195,8 +193,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; - CX18_DEBUG_IOCTL("VIDIOC_TRY_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - w = min(w, 720); w = max(w, 1); h = min(h, cx->is_50hz ? 576 : 480); @@ -210,10 +206,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - CX18_DEBUG_IOCTL("VIDIOC_TRY_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - return cx18_g_fmt_vbi_cap(file, fh, fmt); } @@ -236,8 +228,6 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - ret = cx18_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; @@ -265,8 +255,6 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_FMT: V4L2_BUF_TYPE_VBI_CAPTURE\n"); - if (id->type == CX18_ENC_STREAM_TYPE_VBI && cx->vbi.sliced_in->service_set && atomic_read(&cx->ana_capturing) > 0) @@ -288,8 +276,6 @@ static int cx18_g_chip_ident(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_CHIP_IDENT\n"); - chip->ident = V4L2_IDENT_NONE; chip->revision = 0; if (chip->match_type == V4L2_CHIP_MATCH_HOST) { @@ -311,8 +297,6 @@ static int cx18_g_register(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_DBG_G_REGISTER\n"); - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) @@ -327,8 +311,6 @@ static int cx18_s_register(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_DBG_S_REGISTER\n"); - if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER) @@ -342,8 +324,6 @@ static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_PRIORITY\n"); - *p = v4l2_prio_max(&cx->prio); return 0; } @@ -353,8 +333,6 @@ static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio) struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - CX18_DEBUG_IOCTL("VIDIOC_S_PRIORITY\n"); - return v4l2_prio_change(&cx->prio, &id->prio, prio); } @@ -363,8 +341,6 @@ static int cx18_querycap(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_QUERYCAP\n"); - strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); strlcpy(vcap->bus_info, pci_name(cx->dev), sizeof(vcap->bus_info)); @@ -377,8 +353,6 @@ static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_ENUMAUDIO\n"); - return cx18_get_audio_input(cx, vin->index, vin); } @@ -386,8 +360,6 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_AUDIO\n"); - vin->index = cx->audio_input; return cx18_get_audio_input(cx, vin->index, vin); } @@ -396,8 +368,6 @@ static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_S_AUDIO\n"); - if (vout->index >= cx->nof_audio_inputs) return -EINVAL; cx->audio_input = vout->index; @@ -409,8 +379,6 @@ static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_ENUMINPUT\n"); - /* set it to defaults from our table */ return cx18_get_input(cx, vin->index, vin); } @@ -420,8 +388,6 @@ static int cx18_cropcap(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_CROPCAP\n"); - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; cropcap->bounds.top = cropcap->bounds.left = 0; @@ -443,8 +409,6 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_CROP\n"); - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); @@ -454,8 +418,6 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_CROP\n"); - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); @@ -473,10 +435,6 @@ static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, } }; - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - CX18_DEBUG_IOCTL("VIDIOC_ENUM_FMT: V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - if (fmt->index > 1) return -EINVAL; *fmt = formats[fmt->index]; @@ -487,8 +445,6 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_INPUT\n"); - *i = cx->active_input; return 0; } @@ -503,8 +459,6 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp) if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_INPUT\n"); - if (inp < 0 || inp >= cx->nof_inputs) return -EINVAL; @@ -534,8 +488,6 @@ static int cx18_g_frequency(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_FREQUENCY\n"); - if (vf->tuner != 0) return -EINVAL; @@ -553,8 +505,6 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_FREQUENCY\n"); - if (vf->tuner != 0) return -EINVAL; @@ -569,8 +519,6 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_STD\n"); - *std = cx->std; return 0; } @@ -585,8 +533,6 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_STD\n"); - if ((*std & V4L2_STD_ALL) == 0) return -EINVAL; @@ -628,8 +574,6 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) if (ret) return ret; - CX18_DEBUG_IOCTL("VIDIOC_S_TUNER\n"); - if (vt->index != 0) return -EINVAL; @@ -643,8 +587,6 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_G_TUNER\n"); - if (vt->index != 0) return -EINVAL; @@ -679,8 +621,6 @@ static int cx18_encoder_cmd(struct file *file, void *fh, struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - CX18_DEBUG_IOCTL("VIDIOC_ENCODER_CMD:\n"); - switch (enc->cmd) { case V4L2_ENC_CMD_START: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); @@ -728,8 +668,6 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh, { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - CX18_DEBUG_IOCTL("VIDIOC_TRY_ENCDOER_CMD:\n"); - switch (enc->cmd) { case V4L2_ENC_CMD_START: CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); @@ -765,7 +703,6 @@ static int cx18_log_status(struct file *file, void *fh) struct v4l2_audio audin; int i; - CX18_DEBUG_IOCTL("VIDIOC_LOG_STATUS\n"); CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); if (cx->hw_flags & CX18_HW_TVEEPROM) { struct tveeprom tv; @@ -807,26 +744,13 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg) switch (cmd) { case VIDIOC_INT_S_AUDIO_ROUTING: { struct v4l2_routing *route = arg; - CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING (%d, %d)\n", - route->input, route->output); + + CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", + route->input, route->output); cx18_audio_set_route(cx, route); break; } - case VIDIOC_INT_RESET: { - u32 val = *(u32 *)arg; - CX18_DEBUG_IOCTL("VIDIOC_INT_RESET (%#10x)\n", val); - /* No op right now */ - /* cx18_av_cmd(cx, cmd, arg) */ - /* cx18_call_i2c_clients(cx, cmd, arg) */ - break; - } default: - if (cx18_debug & CX18_DBGFLG_IOCTL) { - printk(KERN_INFO "cx18%d ioctl: unsupported cmd: ", - cx->num); - v4l_printk_ioctl(cmd); - printk("\n"); - } return -EINVAL; } return 0; @@ -835,12 +759,17 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg) int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { + struct video_device *vfd = video_devdata(filp); struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; struct cx18 *cx = id->cx; int res; mutex_lock(&cx->serialize_lock); + + if (cx18_debug & CX18_DBGFLG_IOCTL) + vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; res = video_ioctl2(inode, filp, cmd, arg); + vfd->debug = 0; mutex_unlock(&cx->serialize_lock); return res; } diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 805847370cba..f3d20509a8bd 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -190,8 +190,8 @@ static int cx18_prep_dev(struct cx18 *cx, int type) s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18%d %s", - cx->num, s->name); + snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", + cx->num); s->v4l2dev->minor = minor; s->v4l2dev->dev = &cx->dev->dev; diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index 06723bac99c5..2df9b0668f1f 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -53,8 +53,6 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; const char *name; - IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); if (qctrl->id == 0) return -EINVAL; @@ -91,10 +89,8 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { - struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct v4l2_queryctrl qctrl; - IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); qctrl.id = qmenu->id; ivtv_queryctrl(file, fh, &qctrl); return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); @@ -103,9 +99,6 @@ int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - s32 v = vctrl->value; - - IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); switch (vctrl->id) { /* Standard V4L2 controls */ @@ -124,7 +117,7 @@ int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl); default: - IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id); + IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); return -EINVAL; } return 0; @@ -134,8 +127,6 @@ int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -152,7 +143,7 @@ int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) case V4L2_CID_AUDIO_LOUDNESS: return ivtv_i2c_hw(itv, itv->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl); default: - IVTV_DEBUG_IOCTL("invalid control %x\n", vctrl->id); + IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); return -EINVAL; } return 0; @@ -219,7 +210,6 @@ int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) } return err; } - IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS); return -EINVAL; @@ -246,7 +236,6 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) } return err; } - IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { static u32 freqs[3] = { 44100, 48000, 32000 }; struct cx2341x_mpeg_params p = itv->params; @@ -286,7 +275,6 @@ int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS); return -EINVAL; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index aa222056dd47..8d602cb6ba68 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1336,6 +1336,8 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; + if (!itv->osd_video_pbase) + return -EINVAL; fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_GLOBAL_ALPHA; @@ -1349,11 +1351,15 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) fb->fmt.height = itv->osd_rect.height; fb->fmt.field = V4L2_FIELD_INTERLACED; fb->fmt.bytesperline = fb->fmt.width; + fb->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; + fb->fmt.field = V4L2_FIELD_INTERLACED; + fb->fmt.priv = 0; if (fb->fmt.pixelformat != V4L2_PIX_FMT_PAL8) fb->fmt.bytesperline *= 2; if (fb->fmt.pixelformat == V4L2_PIX_FMT_RGB32 || fb->fmt.pixelformat == V4L2_PIX_FMT_YUV32) fb->fmt.bytesperline *= 2; + fb->fmt.sizeimage = fb->fmt.bytesperline * fb->fmt.height; fb->base = (void *)itv->osd_video_pbase; fb->flags = 0; @@ -1396,6 +1402,8 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) return -EINVAL; + if (!itv->osd_video_pbase) + return -EINVAL; itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = @@ -1744,6 +1752,7 @@ static int ivtv_default(struct file *file, void *fh, int cmd, void *arg) static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { + struct video_device *vfd = video_devdata(filp); struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; int ret; @@ -1812,13 +1821,11 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f return ret; } - if (ivtv_debug & IVTV_DBGFLG_IOCTL) { - printk(KERN_INFO "ivtv%d ioctl: ", itv->num); - v4l_printk_ioctl(cmd); - printk("\n"); - } - - return video_ioctl2(inode, filp, cmd, arg); + if (ivtv_debug & IVTV_DBGFLG_IOCTL) + vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; + ret = video_ioctl2(inode, filp, cmd, arg); + vfd->debug = 0; + return ret; } int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index f8883b487f4a..8e3addd45090 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -213,8 +213,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { s->v4l2dev->type |= VID_TYPE_MPEG_DECODER; } - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", - itv->num, s->name); + snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d", + itv->num); s->v4l2dev->minor = minor; s->v4l2dev->dev = &itv->dev->dev; diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index e8dbee443946..14f93341f061 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -789,6 +789,9 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv) else var->pixclock = pixclock; + itv->osd_rect.width = var->xres; + itv->osd_rect.height = var->yres; + IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n", var->xres, var->yres, var->xres_virtual, var->yres_virtual, -- cgit v1.2.3 From e0e31cdb91cddc4cfbf6d5ffa8212f694723269b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 22 Jun 2008 12:03:28 -0300 Subject: V4L/DVB (8105): cx2341x: add TS capability The cx18 can support transport streams with newer firmwares. Add a TS capability to the generic cx2341x module. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-controls.c | 4 +++- drivers/media/video/cx2341x.c | 29 ++++++++++++++++++++--------- drivers/media/video/cx23885/cx23885-417.c | 2 +- drivers/media/video/cx88/cx88-blackbird.c | 3 ++- drivers/media/video/ivtv/ivtv-controls.c | 4 +++- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 3 ++- include/media/cx2341x.h | 7 ++++--- 7 files changed, 35 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 01ba9ca37d09..855313359370 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -92,11 +92,13 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { + struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; struct v4l2_queryctrl qctrl; qctrl.id = qmenu->id; cx18_queryctrl(file, fh, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + cx2341x_ctrl_get_menu(&cx->params, qmenu->id)); } int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index c592899a2317..5e40c6bd69b6 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -80,7 +80,7 @@ EXPORT_SYMBOL(cx2341x_mpeg_ctrls); /* Map the control ID to the correct field in the cx2341x_mpeg_params struct. Return -EINVAL if the ID is unknown, else return 0. */ -static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params, +static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params, struct v4l2_ext_control *ctrl) { switch (ctrl->id) { @@ -420,7 +420,7 @@ static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, return 0; } -int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, +int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl) { int err; @@ -580,9 +580,9 @@ int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, } EXPORT_SYMBOL(cx2341x_ctrl_query); -const char **cx2341x_ctrl_get_menu(u32 id) +const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id) { - static const char *mpeg_stream_type[] = { + static const char *mpeg_stream_type_without_ts[] = { "MPEG-2 Program Stream", "", "MPEG-1 System Stream", @@ -592,6 +592,16 @@ const char **cx2341x_ctrl_get_menu(u32 id) NULL }; + static const char *mpeg_stream_type_with_ts[] = { + "MPEG-2 Program Stream", + "MPEG-2 Transport Stream", + "MPEG-1 System Stream", + "MPEG-2 DVD-compatible Stream", + "MPEG-1 VCD-compatible Stream", + "MPEG-2 SVCD-compatible Stream", + NULL + }; + static const char *cx2341x_video_spatial_filter_mode_menu[] = { "Manual", "Auto", @@ -630,7 +640,8 @@ const char **cx2341x_ctrl_get_menu(u32 id) switch (id) { case V4L2_CID_MPEG_STREAM_TYPE: - return mpeg_stream_type; + return (p->capabilities & CX2341X_CAP_HAS_TS) ? + mpeg_stream_type_with_ts : mpeg_stream_type_without_ts; case V4L2_CID_MPEG_AUDIO_L1_BITRATE: case V4L2_CID_MPEG_AUDIO_L3_BITRATE: return NULL; @@ -690,7 +701,7 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, if (err) break; if (qctrl.type == V4L2_CTRL_TYPE_MENU) - menu_items = cx2341x_ctrl_get_menu(qctrl.id); + menu_items = cx2341x_ctrl_get_menu(params, qctrl.id); err = v4l2_ctrl_check(ctrl, &qctrl, menu_items); if (err) break; @@ -933,9 +944,9 @@ int cx2341x_update(void *priv, cx2341x_mbox_func func, } EXPORT_SYMBOL(cx2341x_update); -static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id) +static const char *cx2341x_menu_item(const struct cx2341x_mpeg_params *p, u32 id) { - const char **menu = cx2341x_ctrl_get_menu(id); + const char **menu = cx2341x_ctrl_get_menu(p, id); struct v4l2_ext_control ctrl; if (menu == NULL) @@ -952,7 +963,7 @@ invalid: return ""; } -void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) +void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix) { int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; int temporal = p->video_temporal_filter; diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index acdd3b6b3e7c..0f50c377aa7c 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1173,7 +1173,7 @@ static int cx23885_querymenu(struct cx23885_dev *dev, qctrl.id = qmenu->id; cx23885_queryctrl(dev, &qctrl); return v4l2_ctrl_query_menu(qmenu, &qctrl, - cx2341x_ctrl_get_menu(qmenu->id)); + cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); } int cx23885_do_ioctl(struct inode *inode, struct file *file, int radio, diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index fb67e4188b2f..bfdca5847764 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -715,7 +715,8 @@ static int vidioc_querymenu (struct file *file, void *priv, qctrl.id = qmenu->id; blackbird_queryctrl(dev, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + cx2341x_ctrl_get_menu(&dev->params, qmenu->id)); } static int vidioc_querycap (struct file *file, void *priv, diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index 2df9b0668f1f..6a5b70912959 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -89,11 +89,13 @@ int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) { + struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct v4l2_queryctrl qctrl; qctrl.id = qmenu->id; ivtv_queryctrl(file, fh, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + cx2341x_ctrl_get_menu(&itv->params, qmenu->id)); } int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index f30e13f6ee74..6517ba81bd4b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2013,7 +2013,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, case V4L2_CTRL_TYPE_MENU: ciptr->type = pvr2_ctl_enum; ciptr->def.type_enum.value_names = - cx2341x_ctrl_get_menu(ciptr->v4l_id); + cx2341x_ctrl_get_menu(&hdw->enc_ctl_state, + ciptr->v4l_id); for (cnt1 = 0; ciptr->def.type_enum.value_names[cnt1] != NULL; cnt1++) { } diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h index 5f4608e88476..9ec4d5889ef5 100644 --- a/include/media/cx2341x.h +++ b/include/media/cx2341x.h @@ -27,6 +27,7 @@ enum cx2341x_port { enum cx2341x_cap { CX2341X_CAP_HAS_SLICED_VBI = 1 << 0, + CX2341X_CAP_HAS_TS = 1 << 1, }; struct cx2341x_mpeg_params { @@ -88,13 +89,13 @@ typedef int (*cx2341x_mbox_func)(void *priv, u32 cmd, int in, int out, int cx2341x_update(void *priv, cx2341x_mbox_func func, const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new); -int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, +int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl); -const char **cx2341x_ctrl_get_menu(u32 id); +const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id); int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy, struct v4l2_ext_controls *ctrls, unsigned int cmd); void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p); -void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix); +void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix); /* Firmware names */ #define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw" -- cgit v1.2.3 From 156f194b9df243b4c347a62b37258cb088f20297 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 22 Jun 2008 12:08:16 -0300 Subject: V4L/DVB (8106): ivtv/cx18: improve tuner std check in card definitions. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 4 ++-- drivers/media/video/ivtv/ivtv-cards.c | 34 +++++++++++++++++----------------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 90857bedccae..e4295989829b 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -27,7 +27,7 @@ #include "cx18-i2c.h" #include -#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM) +#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM) /********************** card configuration *******************************/ @@ -266,7 +266,7 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, .ddr = { /* MT 46V16M16 memory */ diff --git a/drivers/media/video/ivtv/ivtv-cards.c b/drivers/media/video/ivtv/ivtv-cards.c index dc3fbb320684..4e05f91a9100 100644 --- a/drivers/media/video/ivtv/ivtv-cards.c +++ b/drivers/media/video/ivtv/ivtv-cards.c @@ -40,7 +40,7 @@ #define MSP_MONO MSP_INPUT(MSP_IN_MONO, MSP_IN_TUNER1, \ MSP_DSP_IN_SCART, MSP_DSP_IN_SCART) -#define V4L2_STD_NOT_MN (V4L2_STD_PAL|V4L2_STD_SECAM) +#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM) /* usual i2c tuner addresses to probe */ static struct ivtv_card_tuner_i2c ivtv_i2c_std = { @@ -300,7 +300,7 @@ static const struct ivtv_card ivtv_card_mpg600 = { .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, .tuners = { /* The PAL tuner is confirmed */ - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_mpg600, @@ -341,7 +341,7 @@ static const struct ivtv_card ivtv_card_mpg160 = { .lang1 = 0x0004, .lang2 = 0x0000, .both = 0x0008 }, .gpio_audio_detect = { .mask = 0x0900, .stereo = 0x0100 }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_mpg160, @@ -377,7 +377,7 @@ static const struct ivtv_card ivtv_card_pg600 = { { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL }, }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FQ1216ME }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FQ1216ME }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_pg600, @@ -418,7 +418,7 @@ static const struct ivtv_card ivtv_card_avc2410 = { on the country/region setting of the user to decide which tuner is available. */ .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_ALL - V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FM1236_MK3 }, { .std = V4L2_STD_NTSC_M_JP, .tuner = TUNER_PHILIPS_FQ1286 }, @@ -492,7 +492,7 @@ static const struct ivtv_card ivtv_card_tg5000tv = { .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, .composite = 0x0010, .svideo = 0x0020 }, .tuners = { - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_tg5000tv, .i2c = &ivtv_i2c_std, @@ -523,7 +523,7 @@ static const struct ivtv_card ivtv_card_va2000 = { { IVTV_CARD_INPUT_AUD_TUNER, MSP_TUNER }, }, .tuners = { - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_va2000, .i2c = &ivtv_i2c_std, @@ -567,7 +567,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc = { .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, .f44100 = 0x4000, .f48000 = 0x8000 }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, }, .pci_list = ivtv_pci_cx23416gyc, @@ -599,7 +599,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogr = { .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, .f44100 = 0x4000, .f48000 = 0x8000 }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, }, .i2c = &ivtv_i2c_std, @@ -629,7 +629,7 @@ static const struct ivtv_card ivtv_card_cx23416gyc_nogrycs = { .gpio_audio_freq = { .mask = 0xc000, .f32000 = 0x0000, .f44100 = 0x4000, .f48000 = 0x8000 }, .tuners = { - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, { .std = V4L2_STD_ALL, .tuner = TUNER_PHILIPS_FM1236_MK3 }, }, .i2c = &ivtv_i2c_std, @@ -669,7 +669,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx = { .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, .tuners = { /* This card has the Panasonic VP27 tuner */ - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, }, .pci_list = ivtv_pci_gv_mvprx, .i2c = &ivtv_i2c_std, @@ -706,7 +706,7 @@ static const struct ivtv_card ivtv_card_gv_mvprx2e = { .gpio_audio_input = { .mask = 0xffff, .tuner = 0x0200, .linein = 0x0300 }, .tuners = { /* This card has the Panasonic VP27 tuner */ - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PANASONIC_VP27 }, }, .pci_list = ivtv_pci_gv_mvprx2e, .i2c = &ivtv_i2c_std, @@ -741,7 +741,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd = { .gpio_init = { .direction = 0xf000, .initial_value = 0xA000 }, .tuners = { /* This card has a Philips FQ1216ME MK3 tuner */ - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, .pci_list = ivtv_pci_gotview_pci_dvd, .i2c = &ivtv_i2c_std, @@ -780,7 +780,7 @@ static const struct ivtv_card ivtv_card_gotview_pci_dvd2 = { .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, .tuners = { /* This card has a Philips FQ1216ME MK5 tuner */ - { .std = V4L2_STD_NOT_MN, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, + { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, .pci_list = ivtv_pci_gotview_pci_dvd2, .i2c = &ivtv_i2c_std, @@ -858,7 +858,7 @@ static const struct ivtv_card ivtv_card_dctmvtvp1 = { .gpio_video_input = { .mask = 0x0030, .tuner = 0x0000, .composite = 0x0010, .svideo = 0x0020}, .tuners = { - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FQ1286 }, }, .pci_list = ivtv_pci_dctmvtvp1, .i2c = &ivtv_i2c_std, @@ -1000,7 +1000,7 @@ static const struct ivtv_card ivtv_card_aver_pvr150 = { .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 }, .tuners = { /* This card has a Partsnic PTI-5NF05 tuner */ - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_TCL_2002N }, + { .std = V4L2_STD_MN, .tuner = TUNER_TCL_2002N }, }, .pci_list = ivtv_pci_aver_pvr150, .i2c = &ivtv_i2c_radio, @@ -1068,7 +1068,7 @@ static const struct ivtv_card ivtv_card_asus_falcon2 = { }, .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER }, .tuners = { - { .std = V4L2_STD_525_60|V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, + { .std = V4L2_STD_MN, .tuner = TUNER_PHILIPS_FM1236_MK3 }, }, .pci_list = ivtv_pci_asus_falcon2, .i2c = &ivtv_i2c_std, -- cgit v1.2.3 From f24648e42fd4b7d3ad5af6eaefe0214426933954 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 22 Jun 2008 12:11:13 -0300 Subject: V4L/DVB (8107): cx18: improve support for the Raptor board. - add radio definition - reset the audio firmware (required for this board, harmless for the others) Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 1 + drivers/media/video/cx18/cx18-firmware.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index e4295989829b..456fc924cf8c 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -268,6 +268,7 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { .tuners = { { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, .ddr = { /* MT 46V16M16 memory */ .chip_config = 0x50306, diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 2694ce350631..2c280728dd7e 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -345,6 +345,11 @@ int cx18_firmware_init(struct cx18 *cx) int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx, CX18_FW_APU_SIZE); + write_enc(0xE51FF004, 0); + write_enc(0xa00000, 4); /* todo: not hardcoded */ + write_reg(0x00010000, CX18_PROC_SOFT_RESET); /* Start APU */ + cx18_msleep_timeout(500, 0); + sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx, CX18_FW_CPU_SIZE); -- cgit v1.2.3 From 1d0a436256dc1aecfad901bcd4432dac1cabe6b2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jun 2008 12:31:29 -0300 Subject: V4L/DVB (8110): bttv: allow debug ioctl's Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index c4aa802494ff..06c40c91a6f7 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4188,6 +4188,7 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->dev = &btv->c.pci->dev; vfd->release = video_device_release; vfd->type = type; + vfd->debug = bttv_debug; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", type_name, bttv_tvcards[btv->c.type].name); -- cgit v1.2.3 From 36ecd4955a5ebee6135e2bcc997712fad4ac9b69 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Jun 2008 06:00:17 -0300 Subject: V4L/DVB (8111): ivtv/cx18: fix compile error when CONFIG_VIDEO_ADV_DEBUG is not defined. Thanks to Randy Dunlap for reporting this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-ioctl.c | 42 ++++++++++++++----------- drivers/media/video/ivtv/ivtv-ioctl.c | 59 ++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 47 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 7231f60a180b..017b13efc072 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -113,25 +113,6 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) return set; } -static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct v4l2_register *regs = arg; - unsigned long flags; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) - return -EINVAL; - - spin_lock_irqsave(&cx18_cards_lock, flags); - if (cmd == VIDIOC_DBG_G_REGISTER) - regs->val = read_enc(regs->reg); - else - write_enc(regs->val, regs->reg); - spin_unlock_irqrestore(&cx18_cards_lock, flags); - return 0; -} - static int cx18_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) { @@ -292,6 +273,26 @@ static int cx18_g_chip_ident(struct file *file, void *fh, return -EINVAL; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) +{ + struct v4l2_register *regs = arg; + unsigned long flags; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) + return -EINVAL; + + spin_lock_irqsave(&cx18_cards_lock, flags); + if (cmd == VIDIOC_DBG_G_REGISTER) + regs->val = read_enc(regs->reg); + else + write_enc(regs->val, regs->reg); + spin_unlock_irqrestore(&cx18_cards_lock, flags); + return 0; +} + static int cx18_g_register(struct file *file, void *fh, struct v4l2_register *reg) { @@ -319,6 +320,7 @@ static int cx18_s_register(struct file *file, void *fh, return cx18_call_i2c_client(cx, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); } +#endif static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) { @@ -810,8 +812,10 @@ void cx18_set_funcs(struct video_device *vdev) vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; vdev->vidioc_g_chip_ident = cx18_g_chip_ident; +#ifdef CONFIG_VIDEO_ADV_DEBUG vdev->vidioc_g_register = cx18_g_register; vdev->vidioc_s_register = cx18_s_register; +#endif vdev->vidioc_default = cx18_default; vdev->vidioc_queryctrl = cx18_queryctrl; vdev->vidioc_querymenu = cx18_querymenu; diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 8d602cb6ba68..42443b42336d 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -314,34 +314,6 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id, return 0; } -static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) -{ - struct v4l2_register *regs = arg; - unsigned long flags; - volatile u8 __iomem *reg_start; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) - reg_start = itv->reg_mem - IVTV_REG_OFFSET; - else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && - regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) - reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; - else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) - reg_start = itv->enc_mem; - else - return -EINVAL; - - spin_lock_irqsave(&ivtv_cards_lock, flags); - if (cmd == VIDIOC_DBG_G_REGISTER) { - regs->val = readl(regs->reg + reg_start); - } else { - writel(regs->val, regs->reg + reg_start); - } - spin_unlock_irqrestore(&ivtv_cards_lock, flags); - return 0; -} - static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; @@ -715,6 +687,34 @@ static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident return -EINVAL; } +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) +{ + struct v4l2_register *regs = arg; + unsigned long flags; + u8 __iomem *reg_start; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE) + reg_start = itv->reg_mem - IVTV_REG_OFFSET; + else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET && + regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE) + reg_start = itv->dec_mem - IVTV_DECODER_OFFSET; + else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE) + reg_start = itv->enc_mem; + else + return -EINVAL; + + spin_lock_irqsave(&ivtv_cards_lock, flags); + if (cmd == VIDIOC_DBG_G_REGISTER) + regs->val = readl(regs->reg + reg_start); + else + writel(regs->val, regs->reg + reg_start); + spin_unlock_irqrestore(&ivtv_cards_lock, flags); + return 0; +} + static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; @@ -736,6 +736,7 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *re return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg); } +#endif static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p) { @@ -1896,8 +1897,10 @@ void ivtv_set_funcs(struct video_device *vdev) vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; +#ifdef CONFIG_VIDEO_ADV_DEBUG vdev->vidioc_g_register = ivtv_g_register; vdev->vidioc_s_register = ivtv_s_register; +#endif vdev->vidioc_default = ivtv_default; vdev->vidioc_queryctrl = ivtv_queryctrl; vdev->vidioc_querymenu = ivtv_querymenu; -- cgit v1.2.3 From d8799b4699af008290e141804b40c5ebf3d7dc35 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Jun 2008 06:29:01 -0300 Subject: V4L/DVB (8112): videodev: improve extended control support in video_ioctl2() - add sanity checks for the extended controls argument. - if the driver only supports extended controls, then convert old-style controls to an extended control callback. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 85 +++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 91902d52d022..5bf2256fedeb 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -710,6 +710,29 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd, printk(KERN_CONT "\n"); }; +static inline int check_ext_ctrls(struct v4l2_ext_controls *c) +{ + __u32 i; + + /* zero the reserved fields */ + c->reserved[0] = c->reserved[1] = 0; + for (i = 0; i < c->count; i++) { + c->controls[i].reserved2[0] = 0; + c->controls[i].reserved2[1] = 0; + } + /* V4L2_CID_PRIVATE_BASE cannot be used as control class + * when using extended controls. */ + if (c->ctrl_class == V4L2_CID_PRIVATE_BASE) + return 0; + /* Check that all controls are from the same control class. */ + for (i = 0; i < c->count; i++) { + if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { + c->error_idx = i; + return 0; + } + } + return 1; +} static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) { @@ -1392,10 +1415,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_control *p = arg; - if (!vfd->vidioc_g_ctrl) + if (vfd->vidioc_g_ctrl) + ret = vfd->vidioc_g_ctrl(file, fh, p); + else if (vfd->vidioc_g_ext_ctrls) { + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls)) { + ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); + if (ret == 0) + p->value = ctrl.value; + } + } else break; - - ret = vfd->vidioc_g_ctrl(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); else @@ -1405,21 +1442,39 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, case VIDIOC_S_CTRL: { struct v4l2_control *p = arg; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; - if (!vfd->vidioc_s_ctrl) + if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) break; + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - ret = vfd->vidioc_s_ctrl(file, fh, p); + if (vfd->vidioc_s_ctrl) { + ret = vfd->vidioc_s_ctrl(file, fh, p); + break; + } + if (!vfd->vidioc_s_ext_ctrls) + break; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls)) + ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); break; } case VIDIOC_G_EXT_CTRLS: { struct v4l2_ext_controls *p = arg; + p->error_idx = p->count; if (!vfd->vidioc_g_ext_ctrls) break; - ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + if (check_ext_ctrls(p)) + ret = vfd->vidioc_g_ext_ctrls(file, fh, p); v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; } @@ -1427,22 +1482,24 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_ext_controls *p = arg; - if (vfd->vidioc_s_ext_ctrls) { - v4l_print_ext_ctrls(cmd, vfd, p, 1); - + p->error_idx = p->count; + if (!vfd->vidioc_s_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p)) ret = vfd->vidioc_s_ext_ctrls(file, fh, p); - } break; } case VIDIOC_TRY_EXT_CTRLS: { struct v4l2_ext_controls *p = arg; - if (vfd->vidioc_try_ext_ctrls) { - v4l_print_ext_ctrls(cmd, vfd, p, 1); - + p->error_idx = p->count; + if (!vfd->vidioc_try_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p)) ret = vfd->vidioc_try_ext_ctrls(file, fh, p); - } break; } case VIDIOC_QUERYMENU: -- cgit v1.2.3 From adb65bc71c8fef53822870cc9018f05b11131233 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Jun 2008 06:32:44 -0300 Subject: V4L/DVB (8113): ivtv/cx18: remove s/g_ctrl, now all controls are handled through s/g_ext_ctrl videodev converts old-style controls to an extended control so the ivtv and cx18 drivers no longer have to handle both. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-controls.c | 43 +++++++++++++++++++++++--------- drivers/media/video/cx18/cx18-controls.h | 2 -- drivers/media/video/cx18/cx18-ioctl.c | 2 -- drivers/media/video/ivtv/ivtv-controls.c | 39 +++++++++++++++++++++++------ drivers/media/video/ivtv/ivtv-controls.h | 2 -- drivers/media/video/ivtv/ivtv-ioctl.c | 4 +-- 6 files changed, 64 insertions(+), 28 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c index 855313359370..f46c7e5ed747 100644 --- a/drivers/media/video/cx18/cx18-controls.c +++ b/drivers/media/video/cx18/cx18-controls.c @@ -101,16 +101,24 @@ int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) cx2341x_ctrl_get_menu(&cx->params, qmenu->id)); } -int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int cx18_try_ctrl(struct file *file, void *fh, + struct v4l2_ext_control *vctrl) { - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; + struct v4l2_queryctrl qctrl; + const char **menu_items = NULL; + int err; - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; + qctrl.id = vctrl->id; + err = cx18_queryctrl(file, fh, &qctrl); + if (err) + return err; + if (qctrl.type == V4L2_CTRL_TYPE_MENU) + menu_items = v4l2_ctrl_get_menu(qctrl.id); + return v4l2_ctrl_check(vctrl, &qctrl, menu_items); +} +static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) +{ switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -134,10 +142,8 @@ int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return 0; } -int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) { - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -211,7 +217,7 @@ int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = cx18_g_ctrl(file, fh, &ctrl); + err = cx18_g_ctrl(cx, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -243,7 +249,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = cx18_s_ctrl(file, fh, &ctrl); + err = cx18_s_ctrl(cx, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -287,6 +293,19 @@ int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + err = cx18_try_ctrl(file, fh, &c->controls[i]); + if (err) { + c->error_idx = i; + break; + } + } + return err; + } if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&cx->params, atomic_read(&cx->ana_capturing), diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h index 81b8996e5860..e46323700b81 100644 --- a/drivers/media/video/cx18/cx18-controls.h +++ b/drivers/media/video/cx18/cx18-controls.h @@ -22,8 +22,6 @@ */ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); -int cx18_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); -int cx18_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int cx18_try_ext_ctrls(struct file *file, void *fh, diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 017b13efc072..6eaf77b99e9d 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -819,8 +819,6 @@ void cx18_set_funcs(struct video_device *vdev) vdev->vidioc_default = cx18_default; vdev->vidioc_queryctrl = cx18_queryctrl; vdev->vidioc_querymenu = cx18_querymenu; - vdev->vidioc_g_ctrl = cx18_g_ctrl; - vdev->vidioc_s_ctrl = cx18_s_ctrl; vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c index 6a5b70912959..48e103be7183 100644 --- a/drivers/media/video/ivtv/ivtv-controls.c +++ b/drivers/media/video/ivtv/ivtv-controls.c @@ -98,10 +98,24 @@ int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) cx2341x_ctrl_get_menu(&itv->params, qmenu->id)); } -int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int ivtv_try_ctrl(struct file *file, void *fh, + struct v4l2_ext_control *vctrl) { - struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + struct v4l2_queryctrl qctrl; + const char **menu_items = NULL; + int err; + + qctrl.id = vctrl->id; + err = ivtv_queryctrl(file, fh, &qctrl); + if (err) + return err; + if (qctrl.type == V4L2_CTRL_TYPE_MENU) + menu_items = v4l2_ctrl_get_menu(qctrl.id); + return v4l2_ctrl_check(vctrl, &qctrl, menu_items); +} +static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) +{ switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -125,10 +139,8 @@ int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) return 0; } -int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl) +static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) { - struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; - switch (vctrl->id) { /* Standard V4L2 controls */ case V4L2_CID_BRIGHTNESS: @@ -203,7 +215,7 @@ int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = ivtv_g_ctrl(file, fh, &ctrl); + err = ivtv_g_ctrl(itv, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -229,7 +241,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) for (i = 0; i < c->count; i++) { ctrl.id = c->controls[i].id; ctrl.value = c->controls[i].value; - err = ivtv_s_ctrl(file, fh, &ctrl); + err = ivtv_s_ctrl(itv, &ctrl); c->controls[i].value = ctrl.value; if (err) { c->error_idx = i; @@ -277,6 +289,19 @@ int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) { struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; + if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { + int i; + int err = 0; + + for (i = 0; i < c->count; i++) { + err = ivtv_try_ctrl(file, fh, &c->controls[i]); + if (err) { + c->error_idx = i; + break; + } + } + return err; + } if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS); return -EINVAL; diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h index 304204be6b0d..1c7721e23c9b 100644 --- a/drivers/media/video/ivtv/ivtv-controls.h +++ b/drivers/media/video/ivtv/ivtv-controls.h @@ -22,8 +22,6 @@ #define IVTV_CONTROLS_H int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); -int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *a); -int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *a); int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 42443b42336d..52e00a7f3110 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -692,7 +692,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg) { struct v4l2_register *regs = arg; unsigned long flags; - u8 __iomem *reg_start; + volatile u8 __iomem *reg_start; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1904,8 +1904,6 @@ void ivtv_set_funcs(struct video_device *vdev) vdev->vidioc_default = ivtv_default; vdev->vidioc_queryctrl = ivtv_queryctrl; vdev->vidioc_querymenu = ivtv_querymenu; - vdev->vidioc_g_ctrl = ivtv_g_ctrl; - vdev->vidioc_s_ctrl = ivtv_s_ctrl; vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; -- cgit v1.2.3 From c5588b5c473c3d496a2f94b80ea8254110866506 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 25 Jun 2008 00:24:21 -0300 Subject: V4L/DVB (8114): cx18: Improve Raptor card audio input routing defintions cx18: Improved Raptor card audio input routing defintions, so that muxer values matched cx18_gpio() values for tuner, line in 1, and radio and added LED indication of selected audio input. Audio line in 2 doesn't work as it uses the not yet supported 2nd I2S port. Tuner/FM Radio AF is mono until SIF support is fixed. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 456fc924cf8c..0b892aacabef 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -261,14 +261,14 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 1 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 1 }, + { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 1 }, }, .tuners = { { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 2 }, .ddr = { /* MT 46V16M16 memory */ .chip_config = 0x50306, @@ -278,9 +278,12 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { .tune_lane = 0, .initial_emrs = 0, }, - .gpio_init.initial_value = 0x02, - .gpio_init.direction = 0x02, - .gpio_audio_input = { .mask = 0x02, .tuner = 0x02, .linein = 0x00 }, + .gpio_init.initial_value = 0x1002, + .gpio_init.direction = 0xf002, + .gpio_audio_input = { .mask = 0xf002, + .tuner = 0x1002, /* LED D1 Tuner AF */ + .linein = 0x2000, /* LED D2 Line In 1 */ + .radio = 0x4002 }, /* LED D3 Tuner AF */ .pci_list = cx18_pci_cnxt_raptor_pal, .i2c = &cx18_i2c_std, }; -- cgit v1.2.3 From 6264c80661eaa2df793dd71d4956f371be955aa2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 25 Jun 2008 06:54:05 -0300 Subject: V4L/DVB (8116): videodev: allow PRIVATE_BASE controls when called through VIDIOC_G/S_CTRL. V4L2_CID_PRIVATE_BASE controls are not allowed when called from VIDIOC_S/G_EXT_CTRL as extended controls use a better mechanism for private controls. But still allow it when called from the VIDIOC_G/S_CTRL to extended control conversion in video_ioctl2() for backwards compatibility. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 5bf2256fedeb..d54ca6c802db 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -710,7 +710,7 @@ static inline void v4l_print_ext_ctrls(unsigned int cmd, printk(KERN_CONT "\n"); }; -static inline int check_ext_ctrls(struct v4l2_ext_controls *c) +static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) { __u32 i; @@ -721,8 +721,11 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c) c->controls[i].reserved2[1] = 0; } /* V4L2_CID_PRIVATE_BASE cannot be used as control class - * when using extended controls. */ - if (c->ctrl_class == V4L2_CID_PRIVATE_BASE) + when using extended controls. + Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL + is it allowed for backwards compatibility. + */ + if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) return 0; /* Check that all controls are from the same control class. */ for (i = 0; i < c->count; i++) { @@ -1426,7 +1429,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls)) { + if (check_ext_ctrls(&ctrls, 1)) { ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); if (ret == 0) p->value = ctrl.value; @@ -1462,7 +1465,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrls.controls = &ctrl; ctrl.id = p->id; ctrl.value = p->value; - if (check_ext_ctrls(&ctrls)) + if (check_ext_ctrls(&ctrls, 1)) ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); break; } @@ -1473,7 +1476,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, p->error_idx = p->count; if (!vfd->vidioc_g_ext_ctrls) break; - if (check_ext_ctrls(p)) + if (check_ext_ctrls(p, 0)) ret = vfd->vidioc_g_ext_ctrls(file, fh, p); v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; @@ -1486,7 +1489,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_s_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); - if (check_ext_ctrls(p)) + if (check_ext_ctrls(p, 0)) ret = vfd->vidioc_s_ext_ctrls(file, fh, p); break; } @@ -1498,7 +1501,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!vfd->vidioc_try_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); - if (check_ext_ctrls(p)) + if (check_ext_ctrls(p, 0)) ret = vfd->vidioc_try_ext_ctrls(file, fh, p); break; } -- cgit v1.2.3 From 9c7ecaf5ace4dba94b4c75afa395440acfb2e36c Mon Sep 17 00:00:00 2001 From: Dan Taylor Date: Fri, 27 Jun 2008 13:29:41 -0300 Subject: V4L/DVB (8117): saa7134: Avermedia A16D composite input Signed-off-by: Star Trac by Unisen, Inc. Dan Taylor Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 6c53168f20f7..a37e5c64f44b 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4207,6 +4207,10 @@ struct saa7134_board saa7134_boards[] = { .name = name_svideo, .vmux = 8, .amux = LINE1, + }, { + .name = name_comp, + .vmux = 0, + .amux = LINE1, } }, .radio = { .name = name_radio, @@ -4229,6 +4233,10 @@ struct saa7134_board saa7134_boards[] = { .name = name_svideo, .vmux = 8, .amux = LINE1, + }, { + .name = name_comp, + .vmux = 0, + .amux = LINE1, } }, .radio = { .name = name_radio, -- cgit v1.2.3 From 305519c924d8f2f2f85c390c6d456dc41dbe0284 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Fri, 27 Jun 2008 04:15:38 -0300 Subject: V4L/DVB (8120): cx23885-417: Replace cx23885_do_ioctl to use video_ioctl2 Convert cx23885-417 to use video_ioctl2 Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-417.c | 699 ++++++++++++++++-------------- 1 file changed, 375 insertions(+), 324 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 0f50c377aa7c..e7ef093265af 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1176,376 +1176,401 @@ static int cx23885_querymenu(struct cx23885_dev *dev, cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); } -int cx23885_do_ioctl(struct inode *inode, struct file *file, int radio, - struct cx23885_dev *dev, unsigned int cmd, void *arg, - v4l2_kioctl driver_ioctl) +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) { - int err; + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + unsigned int i; - switch (cmd) { - /* ---------- tv norms ---------- */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *e = arg; - unsigned int i; - - i = e->index; - if (i >= ARRAY_SIZE(cx23885_tvnorms)) - return -EINVAL; - err = v4l2_video_std_construct(e, - cx23885_tvnorms[e->index].id, - cx23885_tvnorms[e->index].name); - e->index = i; - if (err < 0) - return err; - return 0; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; + for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) + if (*id & cx23885_tvnorms[i].id) + break; + if (i == ARRAY_SIZE(cx23885_tvnorms)) + return -EINVAL; + dev->encodernorm = cx23885_tvnorms[i]; + return 0; +} - *id = dev->encodernorm.id; - return 0; - } - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - unsigned int i; +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + struct cx23885_input *input; + unsigned int n; - for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) - if (*id & cx23885_tvnorms[i].id) - break; - if (i == ARRAY_SIZE(cx23885_tvnorms)) - return -EINVAL; - dev->encodernorm = cx23885_tvnorms[i]; + n = i->index; - return 0; - } + if (n >= 4) + return -EINVAL; - /* ------ input switching ---------- */ - case VIDIOC_ENUMINPUT: - { - struct cx23885_input *input; - struct v4l2_input *i = arg; - unsigned int n; - - n = i->index; - if (n >= 4) - return -EINVAL; - input = &cx23885_boards[dev->board].input[n]; - if (input->type == 0) - return -EINVAL; - memset(i, 0, sizeof(*i)); - i->index = n; - /* FIXME - * strcpy(i->name, input->name); */ - strcpy(i->name, "unset"); - if (input->type == CX23885_VMUX_TELEVISION || - input->type == CX23885_VMUX_CABLE) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; + input = &cx23885_boards[dev->board].input[n]; - for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++) - i->std |= cx23885_tvnorms[n].id; - return 0; - } - case VIDIOC_G_INPUT: - { - unsigned int *i = arg; + if (input->type == 0) + return -EINVAL; - *i = dev->input; - return 0; - } - case VIDIOC_S_INPUT: - { - unsigned int *i = arg; + memset(i, 0, sizeof(*i)); + i->index = n; - if (*i >= 4) - return -EINVAL; + /* FIXME + * strcpy(i->name, input->name); */ + strcpy(i->name, "unset"); - return 0; - } + if (input->type == CX23885_VMUX_TELEVISION || + input->type == CX23885_VMUX_CABLE) + i->type = V4L2_INPUT_TYPE_TUNER; + else + i->type = V4L2_INPUT_TYPE_CAMERA; - /* --- tuner ioctls ------------------------------------------ */ - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; + for (n = 0; n < ARRAY_SIZE(cx23885_tvnorms); n++) + i->std |= cx23885_tvnorms[n].id; + return 0; +} - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Television"); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t); - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; - dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); + *i = dev->input; + return 0; +} - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i >= 4) + return -EINVAL; - if (UNSET == dev->tuner_type) - return -EINVAL; + return 0; +} - /* Update the A/V core */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t); +static int vidioc_g_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; + if (UNSET == dev->tuner_type) + return -EINVAL; + if (0 != t->index) + return -EINVAL; + memset(t, 0, sizeof(*t)); + strcpy(t->name, "Television"); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t); - memset(f, 0, sizeof(*f)); - if (UNSET == dev->tuner_type) - return -EINVAL; - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; + dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - /* Assumption that tuner is always on bus 1 */ - cx23885_call_i2c_clients(&dev->i2c_bus[1], - VIDIOC_G_FREQUENCY, f); + return 0; +} - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n", - dev->tuner_type); - dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n", - f->tuner, f->type); - if (UNSET == dev->tuner_type) - return -EINVAL; - if (f->tuner != 0) - return -EINVAL; - if (f->type != V4L2_TUNER_ANALOG_TV) - return -EINVAL; - dev->freq = f->frequency; - - /* Assumption that tuner is always on bus 1 */ - cx23885_call_i2c_clients(&dev->i2c_bus[1], - VIDIOC_S_FREQUENCY, f); - return 0; - } - case VIDIOC_S_CTRL: - { - /* Update the A/V core */ - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, arg); - return 0; - } - default: - /* Convert V4L ioctl to V4L2 and call mpeg_do_ioctl - * (driver_ioctl) */ - return v4l_compat_translate_ioctl(inode, file, cmd, arg, - driver_ioctl); - } +static int vidioc_s_tuner(struct file *file, void *priv, + struct v4l2_tuner *t) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + + if (UNSET == dev->tuner_type) + return -EINVAL; + + /* Update the A/V core */ + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t); + + return 0; +} + +static int vidioc_g_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + + memset(f, 0, sizeof(*f)); + if (UNSET == dev->tuner_type) + return -EINVAL; + f->type = V4L2_TUNER_ANALOG_TV; + f->frequency = dev->freq; + + /* Assumption that tuner is always on bus 1 */ + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f); + + return 0; +} + +static int vidioc_s_frequency(struct file *file, void *priv, + struct v4l2_frequency *f) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + + cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, + CX23885_END_NOW, CX23885_MPEG_CAPTURE, + CX23885_RAW_BITS_NONE); + + dprintk(1, "VIDIOC_S_FREQUENCY: dev type %d, f\n", + dev->tuner_type); + dprintk(1, "VIDIOC_S_FREQUENCY: f tuner %d, f type %d\n", + f->tuner, f->type); + if (UNSET == dev->tuner_type) + return -EINVAL; + if (f->tuner != 0) + return -EINVAL; + if (f->type != V4L2_TUNER_ANALOG_TV) + return -EINVAL; + dev->freq = f->frequency; + + /* Assumption that tuner is always on bus 1 */ + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f); + + cx23885_initialize_codec(dev); return 0; } -static int mpeg_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctl) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; + + /* Update the A/V core */ + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl); + return 0; +} + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { struct cx23885_fh *fh = file->private_data; struct cx23885_dev *dev = fh->dev; struct cx23885_tsport *tsport = &dev->ts1; - if (v4l_debug > 1) - v4l_print_ioctl(dev->name, cmd); + memset(cap, 0, sizeof(*cap)); + strcpy(cap->driver, dev->name); + strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, + sizeof(cap->card)); + sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); + cap->version = CX23885_VERSION_CODE; + cap->capabilities = + V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING | + 0; + if (UNSET != dev->tuner_type) + cap->capabilities |= V4L2_CAP_TUNER; - switch (cmd) { + return 0; +} - /* --- capabilities ------------------------------------------ */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memset(cap, 0, sizeof(*cap)); - strcpy(cap->driver, dev->name); - strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->version = CX23885_VERSION_CODE; - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - 0; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; - - return 0; - } +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + int index; - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - int index; - - index = f->index; - if (index != 0) - return -EINVAL; - - memset(f, 0, sizeof(*f)); - f->index = index; - strlcpy(f->description, "MPEG", sizeof(f->description)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->pixelformat = V4L2_PIX_FMT_MPEG; - return 0; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = dev->ts1.width; - f->fmt.pix.height = dev->ts1.height; - f->fmt.pix.field = fh->mpegq.field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = arg; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.sizeimage = - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - - f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - return 0; - } + index = f->index; + if (index != 0) + return -EINVAL; - /* --- streaming capture ------------------------------------- */ - case VIDIOC_REQBUFS: - return videobuf_reqbufs(&fh->mpegq, arg); + memset(f, 0, sizeof(*f)); + f->index = index; + strlcpy(f->description, "MPEG", sizeof(f->description)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->pixelformat = V4L2_PIX_FMT_MPEG; - case VIDIOC_QUERYBUF: - return videobuf_querybuf(&fh->mpegq, arg); + return 0; +} - case VIDIOC_QBUF: - return videobuf_qbuf(&fh->mpegq, arg); +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; - case VIDIOC_DQBUF: - return videobuf_dqbuf(&fh->mpegq, arg, - file->f_flags & O_NONBLOCK); + memset(f, 0, sizeof(*f)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.bytesperline = 0; + f->fmt.pix.sizeimage = + dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; + f->fmt.pix.colorspace = 0; + f->fmt.pix.width = dev->ts1.width; + f->fmt.pix.height = dev->ts1.height; + f->fmt.pix.field = fh->mpegq.field; + dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", + dev->ts1.width, dev->ts1.height, fh->mpegq.field); + return 0; +} - case VIDIOC_STREAMON: - return videobuf_streamon(&fh->mpegq); +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; - case VIDIOC_STREAMOFF: - return videobuf_streamoff(&fh->mpegq); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.bytesperline = 0; + f->fmt.pix.sizeimage = + dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; + f->fmt.pix.sizeimage = + f->fmt.pix.colorspace = 0; + dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", + dev->ts1.width, dev->ts1.height, fh->mpegq.field); + return 0; +} - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *f = arg; +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct cx23885_fh *fh = file->private_data; + struct cx23885_dev *dev = fh->dev; - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, cmd); - } - case VIDIOC_S_EXT_CTRLS: - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *f = arg; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, cmd); - if (err == 0 && cmd == VIDIOC_S_EXT_CTRLS) { - err = cx2341x_update(dev, cx23885_mbox_func, - &dev->mpeg_params, &p); - dev->mpeg_params = p; - } - return err; - } - case VIDIOC_S_FREQUENCY: - { - cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX23885_END_NOW, CX23885_MPEG_CAPTURE, - CX23885_RAW_BITS_NONE); - cx23885_do_ioctl(inode, file, 0, dev, cmd, arg, - mpeg_do_ioctl); - cx23885_initialize_codec(dev); - - return 0; - } - case VIDIOC_LOG_STATUS: - { - char name[32 + 2]; - - snprintf(name, sizeof(name), "%s/2", dev->name); - printk(KERN_INFO - "%s/2: ============ START LOG STATUS ============\n", - dev->name); - cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS, - NULL); - cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS, - NULL); - cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS, - NULL); - cx2341x_log_status(&dev->mpeg_params, name); - printk(KERN_INFO - "%s/2: ============= END LOG STATUS =============\n", - dev->name); - return 0; - } - case VIDIOC_QUERYMENU: - return cx23885_querymenu(dev, arg); - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *c = arg; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; + f->fmt.pix.bytesperline = 0; + f->fmt.pix.sizeimage = + dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; + f->fmt.pix.colorspace = 0; + dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", + f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); + return 0; +} - return cx23885_queryctrl(dev, c); - } +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + struct cx23885_fh *fh = file->private_data; - default: - return cx23885_do_ioctl(inode, file, 0, dev, cmd, arg, - mpeg_do_ioctl); + return videobuf_reqbufs(&fh->mpegq, p); +} + +static int vidioc_querybuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct cx23885_fh *fh = file->private_data; + + return videobuf_querybuf(&fh->mpegq, p); +} + +static int vidioc_qbuf(struct file *file, void *priv, + struct v4l2_buffer *p) +{ + struct cx23885_fh *fh = file->private_data; + + return videobuf_qbuf(&fh->mpegq, p); +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) +{ + struct cx23885_fh *fh = priv; + + return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK); +} + + +static int vidioc_streamon(struct file *file, void *priv, + enum v4l2_buf_type i) +{ + struct cx23885_fh *fh = file->private_data; + + return videobuf_streamon(&fh->mpegq); +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + struct cx23885_fh *fh = file->private_data; + + return videobuf_streamoff(&fh->mpegq); +} + +static int vidioc_g_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS); +} + +static int vidioc_s_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + struct cx2341x_mpeg_params p; + int err; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + + p = dev->mpeg_params; + err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS); + + if (err == 0) { + err = cx2341x_update(dev, cx23885_mbox_func, + &dev->mpeg_params, &p); + dev->mpeg_params = p; } + return err; +} + +static int vidioc_try_ext_ctrls(struct file *file, void *priv, + struct v4l2_ext_controls *f) +{ + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + struct cx2341x_mpeg_params p; + int err; + + if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + + p = dev->mpeg_params; + err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); + return err; +} + +static int vidioc_log_status(struct file *file, void *priv) +{ + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + char name[32 + 2]; + + snprintf(name, sizeof(name), "%s/2", dev->name); + printk(KERN_INFO + "%s/2: ============ START LOG STATUS ============\n", + dev->name); + cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS, + NULL); + cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS, + NULL); + cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS, + NULL); + cx2341x_log_status(&dev->mpeg_params, name); + printk(KERN_INFO + "%s/2: ============= END LOG STATUS =============\n", + dev->name); return 0; } -static int mpeg_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static int vidioc_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *a) +{ + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + + return cx23885_querymenu(dev, a); +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *c) { - return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); + struct cx23885_fh *fh = priv; + struct cx23885_dev *dev = fh->dev; + + return cx23885_queryctrl(dev, c); } static int mpeg_open(struct inode *inode, struct file *file) @@ -1670,7 +1695,7 @@ static struct file_operations mpeg_fops = { .read = mpeg_read, .poll = mpeg_poll, .mmap = mpeg_mmap, - .ioctl = mpeg_ioctl, + .ioctl = video_ioctl2, .llseek = no_llseek, }; @@ -1682,6 +1707,32 @@ static struct video_device cx23885_mpeg_template = { VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, .minor = -1, + .vidioc_s_std = vidioc_s_std, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_g_tuner = vidioc_g_tuner, + .vidioc_s_tuner = vidioc_s_tuner, + .vidioc_g_frequency = vidioc_g_frequency, + .vidioc_s_frequency = vidioc_s_frequency, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, + .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, + .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, + .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, + .vidioc_log_status = vidioc_log_status, + .vidioc_querymenu = vidioc_querymenu, + .vidioc_queryctrl = vidioc_queryctrl, }; void cx23885_417_unregister(struct cx23885_dev *dev) -- cgit v1.2.3 From a9fc52bcbeb5245b58d23c558f3e3e8f18bebbc3 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 28 Jun 2008 08:57:06 -0300 Subject: V4L/DVB (8123): Add support for em2860 based PointNix Intra-Oral Camera em28xx-cards.c em28xx-input.c em28xx-video.c em28xx.h - Add support for the PointNix Intra-Oral Camera, which required addition of a construct for reading the "snapshot" button (provided on the em2860 and em2880 chips, but this is the first case where I have seen it actually used in a product). The button is wired to pin 56 on the em2880. http://www.pointnix.com/ENG/dental/product_02.asp Thanks to Roberto Mantovani for testing the changes Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 18 +++++++ drivers/media/video/em28xx/em28xx-input.c | 87 +++++++++++++++++++++++++++++++ drivers/media/video/em28xx/em28xx-video.c | 2 + drivers/media/video/em28xx/em28xx.h | 10 ++++ 5 files changed, 118 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index c7e23942c1dc..10591467ef16 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -17,3 +17,4 @@ 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] + 19 -> PointNix Intra-Oral Camera (em2860) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 938c51e1c86d..05f0d5a15058 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -426,6 +426,19 @@ struct em28xx_board em28xx_boards[] = { .amux = EM28XX_AMUX_LINE_IN, } }, }, + [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { + .name = "PointNix Intra-Oral Camera", + .has_snapshot_button = 1, + .vchannels = 1, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 0, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -522,6 +535,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash [] = { static struct em28xx_hash_table em28xx_i2c_hash[] = { {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, + {0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT}, }; int em28xx_tuner_callback(void *ptr, int command, int arg) @@ -554,6 +568,7 @@ static void em28xx_set_model(struct em28xx *dev) dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; dev->has_dvb = em28xx_boards[dev->model].has_dvb; + dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; } /* Since em28xx_pre_card_setup() requires a proper dev->model, @@ -841,6 +856,9 @@ void em28xx_card_setup(struct em28xx *dev) em28xx_set_model(dev); } + if (dev->has_snapshot_button) + em28xx_register_snapshot_button(dev); + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index bb5807159b8d..eab3d9511af3 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -30,6 +30,10 @@ #include "em28xx.h" +#define EM28XX_SNAPSHOT_KEY KEY_CAMERA +#define EM28XX_SBUTTON_QUERY_INTERVAL 500 +#define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 + static unsigned int ir_debug; module_param(ir_debug, int, 0644); MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); @@ -124,6 +128,89 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, return 1; } +static void em28xx_query_sbutton(struct work_struct *work) +{ + /* Poll the register and see if the button is depressed */ + struct em28xx *dev = + container_of(work, struct em28xx, sbutton_query_work.work); + int ret; + + ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP); + + if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) { + u8 cleared; + /* Button is depressed, clear the register */ + cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT; + em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1); + + /* Not emulate the keypress */ + input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, + 1); + /* Now unpress the key */ + input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, + 0); + } + + /* Schedule next poll */ + schedule_delayed_work(&dev->sbutton_query_work, + msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); +} + +void em28xx_register_snapshot_button(struct em28xx *dev) +{ + struct input_dev *input_dev; + int err; + + em28xx_info("Registering snapshot button...\n"); + input_dev = input_allocate_device(); + if (!input_dev) { + em28xx_errdev("input_allocate_device failed\n"); + return; + } + + usb_make_path(dev->udev, dev->snapshot_button_path, + sizeof(dev->snapshot_button_path)); + strlcat(dev->snapshot_button_path, "/sbutton", + sizeof(dev->snapshot_button_path)); + INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton); + + input_dev->name = "em28xx snapshot button"; + input_dev->phys = dev->snapshot_button_path; + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit); + input_dev->keycodesize = 0; + input_dev->keycodemax = 0; + input_dev->id.bustype = BUS_USB; + input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); + input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); + input_dev->id.version = 1; + input_dev->dev.parent = &dev->udev->dev; + + err = input_register_device(input_dev); + if (err) { + em28xx_errdev("input_register_device failed\n"); + input_free_device(input_dev); + return; + } + + dev->sbutton_input_dev = input_dev; + schedule_delayed_work(&dev->sbutton_query_work, + msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); + return; + +} + +void em28xx_deregister_snapshot_button(struct em28xx *dev) +{ + if (dev->sbutton_input_dev != NULL) { + em28xx_info("Deregistering snapshot button\n"); + cancel_rearming_delayed_work(&dev->sbutton_query_work); + input_unregister_device(dev->sbutton_input_dev); + dev->sbutton_input_dev = NULL; + } + return; +} + /* ---------------------------------------------------------------------- * Local variables: * c-basic-offset: 8 diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 1c3e8b6291ea..2d9f14d2a00b 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1590,6 +1590,8 @@ static void em28xx_release_resources(struct em28xx *dev) dev->vdev->minor-MINOR_VFL_TYPE_GRABBER_MIN, dev->vbi_dev->minor-MINOR_VFL_TYPE_VBI_MIN); list_del(&dev->devlist); + if (dev->sbutton_input_dev) + em28xx_deregister_snapshot_button(dev); if (dev->radio_dev) { if (-1 != dev->radio_dev->minor) video_unregister_device(dev->radio_dev); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index cff618b2d13c..89842c5d64a1 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -57,6 +57,7 @@ #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 +#define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 @@ -249,6 +250,7 @@ struct em28xx_board { unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_snapshot_button:1; enum em28xx_decoder decoder; @@ -328,6 +330,7 @@ struct em28xx { unsigned int has_12mhz_i2s:1; unsigned int max_range_640_480:1; unsigned int has_dvb:1; + unsigned int has_snapshot_button:1; /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; @@ -418,6 +421,11 @@ struct em28xx { /* Caches GPO and GPIO registers */ unsigned char reg_gpo, reg_gpio; + /* Snapshot button */ + char snapshot_button_path[30]; /* path of the input dev */ + struct input_dev *sbutton_input_dev; + struct delayed_work sbutton_query_work; + struct em28xx_dvb *dvb; }; @@ -483,6 +491,8 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); +void em28xx_register_snapshot_button(struct em28xx *dev); +void em28xx_deregister_snapshot_button(struct em28xx *dev); /* printk macros */ -- cgit v1.2.3 From bfda3a0b3276cda7f2da1dcd98bd060b60954cbb Mon Sep 17 00:00:00 2001 From: Daniel Gimpelevich Date: Sat, 28 Jun 2008 01:45:26 -0300 Subject: V4L/DVB (8124): Add LifeVideo To-Go Cardbus PCI ID Signed-off-by: Daniel Gimpelevich Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 2 +- drivers/media/video/saa7134/saa7134-cards.c | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 4c8a86f24dbe..f58192276017 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -37,7 +37,7 @@ 36 -> UPMOST PURPLE TV [12ab:0800] 37 -> Items MuchTV Plus / IT-005 38 -> Terratec Cinergy 200 TV [153b:1152] - 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212] + 39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212,5169:1502] 40 -> Compro VideoMate TV PVR/FM [185b:c100] 41 -> Compro VideoMate TV Gold+ [185b:c100] 42 -> Sabrent SBT-TVFM (saa7130) diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index a37e5c64f44b..348c8635f19f 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5368,6 +5368,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x185b, .subdevice = 0xc900, .driver_data = SAA7134_BOARD_VIDEOMATE_T750, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x5169, + .subdevice = 0x1502, + .driver_data = SAA7134_BOARD_FLYTVPLATINUM_MINI, }, { .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, -- cgit v1.2.3 From 38f993ad8b1fe4caf9e989caf6e2a25aff3bbaf7 Mon Sep 17 00:00:00 2001 From: Dean Anderson Date: Thu, 26 Jun 2008 23:15:51 -0300 Subject: V4L/DVB (8125): This driver adds support for the Sensoray 2255 devices. It was primarily developed by Dean Anderson with only a little bit of guidance and cleanup by Greg. Signed-off-by: Dean Anderson Signed-off-by: Greg Kroah-Hartman [mchehab@infradead.org: fixed renamed callbacks] Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 9 + drivers/media/video/Makefile | 1 + drivers/media/video/s2255drv.c | 2486 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2496 insertions(+) create mode 100644 drivers/media/video/s2255drv.c (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 5ccb0aeca8cc..8fca90b75e79 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -905,6 +905,15 @@ config USB_STKWEBCAM To compile this driver as a module, choose M here: the module will be called stkwebcam. +config USB_S2255 + tristate "USB Sensoray 2255 video capture device" + depends on VIDEO_V4L2 + select VIDEOBUF_VMALLOC + default n + help + Say Y here if you want support for the Sensoray 2255 USB device. + This driver can be compiled as a module, called s2255drv. + endif # V4L_USB_DRIVERS config SOC_CAMERA diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index ecbbfaab24d5..2ec920dc32e0 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -122,6 +122,7 @@ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ obj-$(CONFIG_USB_VICAM) += usbvideo/ obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ +obj-$(CONFIG_USB_S2255) += s2255drv.o obj-$(CONFIG_VIDEO_IVTV) += ivtv/ obj-$(CONFIG_VIDEO_CX18) += cx18/ diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c new file mode 100644 index 000000000000..6d5fbad95c29 --- /dev/null +++ b/drivers/media/video/s2255drv.c @@ -0,0 +1,2486 @@ +/* + * s2255drv.c - a driver for the Sensoray 2255 USB video capture device + * + * Copyright (C) 2007-2008 by Sensoray Company Inc. + * Dean Anderson + * + * Some video buffer code based on vivi driver: + * + * Sensoray 2255 device supports 4 simultaneous channels. + * The channels are not "crossbar" inputs, they are physically + * attached to separate video decoders. + * + * Because of USB2.0 bandwidth limitations. There is only a + * certain amount of data which may be transferred at one time. + * + * Example maximum bandwidth utilization: + * + * -full size, color mode YUYV or YUV422P: 2 channels at once + * + * -full or half size Grey scale: all 4 channels at once + * + * -half size, color mode YUYV or YUV422P: all 4 channels at once + * + * -full size, color mode YUYV or YUV422P 1/2 frame rate: all 4 channels + * at once. + * (TODO: Incorporate videodev2 frame rate(FR) enumeration, + * which is currently experimental.) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FIRMWARE_FILE_NAME "f2255usb.bin" + + + +/* vendor request in */ +#define S2255_VR_IN 0 +/* vendor request out */ +#define S2255_VR_OUT 1 +/* firmware query */ +#define S2255_VR_FW 0x30 +/* USB endpoint number for configuring the device */ +#define S2255_CONFIG_EP 2 +/* maximum time for DSP to start responding after last FW word loaded(ms) */ +#define S2255_DSP_BOOTTIME 400 +/* maximum time to wait for firmware to load (ms) */ +#define S2255_LOAD_TIMEOUT (5000+S2255_DSP_BOOTTIME) +#define S2255_DEF_BUFS 16 +#define MAX_CHANNELS 4 +#define FRAME_MARKER 0x2255DA4AL +#define MAX_PIPE_USBBLOCK (40*1024) +#define DEFAULT_PIPE_USBBLOCK (16*1024) +#define MAX_CHANNELS 4 +#define MAX_PIPE_BUFFERS 1 +#define SYS_FRAMES 4 +/* maximum size is PAL full size plus room for the marker header(s) */ +#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) +#define DEF_USB_BLOCK (4096) +#define LINE_SZ_4CIFS_NTSC 640 +#define LINE_SZ_2CIFS_NTSC 640 +#define LINE_SZ_1CIFS_NTSC 320 +#define LINE_SZ_4CIFS_PAL 704 +#define LINE_SZ_2CIFS_PAL 704 +#define LINE_SZ_1CIFS_PAL 352 +#define NUM_LINES_4CIFS_NTSC 240 +#define NUM_LINES_2CIFS_NTSC 240 +#define NUM_LINES_1CIFS_NTSC 240 +#define NUM_LINES_4CIFS_PAL 288 +#define NUM_LINES_2CIFS_PAL 288 +#define NUM_LINES_1CIFS_PAL 288 +#define LINE_SZ_DEF 640 +#define NUM_LINES_DEF 240 + + +/* predefined settings */ +#define FORMAT_NTSC 1 +#define FORMAT_PAL 2 + +#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */ +#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */ +#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */ + +#define COLOR_YUVPL 1 /* YUV planar */ +#define COLOR_YUVPK 2 /* YUV packed */ +#define COLOR_Y8 4 /* monochrome */ + +/* frame decimation. Not implemented by V4L yet(experimental in V4L) */ +#define FDEC_1 1 /* capture every frame. default */ +#define FDEC_2 2 /* capture every 2nd frame */ +#define FDEC_3 3 /* capture every 3rd frame */ +#define FDEC_5 5 /* capture every 5th frame */ + +/*------------------------------------------------------- + * Default mode parameters. + *-------------------------------------------------------*/ +#define DEF_SCALE SCALE_4CIFS +#define DEF_COLOR COLOR_YUVPL +#define DEF_FDEC FDEC_1 +#define DEF_BRIGHT 0 +#define DEF_CONTRAST 0x5c +#define DEF_SATURATION 0x80 +#define DEF_HUE 0 + +/* usb config commands */ +#define IN_DATA_TOKEN 0x2255c0de +#define CMD_2255 0xc2255000 +#define CMD_SET_MODE (CMD_2255 | 0x10) +#define CMD_START (CMD_2255 | 0x20) +#define CMD_STOP (CMD_2255 | 0x30) +#define CMD_STATUS (CMD_2255 | 0x40) + +struct s2255_mode { + u32 format; /* input video format (NTSC, PAL) */ + u32 scale; /* output video scale */ + u32 color; /* output video color format */ + u32 fdec; /* frame decimation */ + u32 bright; /* brightness */ + u32 contrast; /* contrast */ + u32 saturation; /* saturation */ + u32 hue; /* hue (NTSC only)*/ + u32 single; /* capture 1 frame at a time (!=0), continuously (==0)*/ + u32 usb_block; /* block size. should be 4096 of DEF_USB_BLOCK */ + u32 restart; /* if DSP requires restart */ +}; + +/* frame structure */ +#define FRAME_STATE_UNUSED 0 +#define FRAME_STATE_FILLING 1 +#define FRAME_STATE_FULL 2 + + +struct s2255_framei { + unsigned long size; + + unsigned long ulState; /* ulState ==0 unused, 1 being filled, 2 full */ + void *lpvbits; /* image data */ + unsigned long cur_size; /* current data copied to it */ +}; + +/* image buffer structure */ +struct s2255_bufferi { + unsigned long dwFrames; /* number of frames in buffer */ + struct s2255_framei frame[SYS_FRAMES]; /* array of FRAME structures */ +}; + +#define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \ + DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \ + DEF_HUE, 0, DEF_USB_BLOCK, 0 } + +struct s2255_dmaqueue { + struct list_head active; + /* thread for acquisition */ + struct task_struct *kthread; + int frame; + struct s2255_dev *dev; + int channel; +}; + +/* for firmware loading, fw_state */ +#define S2255_FW_NOTLOADED 0 +#define S2255_FW_LOADED_DSPWAIT 1 +#define S2255_FW_SUCCESS 2 +#define S2255_FW_FAILED 3 + +struct s2255_fw { + int fw_loaded; + int fw_size; + struct urb *fw_urb; + atomic_t fw_state; + void *pfw_data; + wait_queue_head_t wait_fw; + struct timer_list dsp_wait; + const struct firmware *fw; +}; + +struct s2255_pipeinfo { + u32 max_transfer_size; + u32 cur_transfer_size; + u8 *transfer_buffer; + u32 transfer_flags;; + u32 state; + u32 prev_state; + u32 urb_size; + void *stream_urb; + void *dev; /* back pointer to s2255_dev struct*/ + u32 err_count; + u32 buf_index; + u32 idx; + u32 priority_set; +}; + +struct s2255_fmt; /*forward declaration */ + +struct s2255_dev { + int frames; + int users[MAX_CHANNELS]; + struct mutex lock; + struct mutex open_lock; + int resources[MAX_CHANNELS]; + struct usb_device *udev; + struct usb_interface *interface; + u8 read_endpoint; + + struct s2255_dmaqueue vidq[MAX_CHANNELS]; + struct video_device *vdev[MAX_CHANNELS]; + struct list_head s2255_devlist; + struct timer_list timer; + struct s2255_fw *fw_data; + int board_num; + int is_open; + struct s2255_pipeinfo pipes[MAX_PIPE_BUFFERS]; + struct s2255_bufferi buffer[MAX_CHANNELS]; + struct s2255_mode mode[MAX_CHANNELS]; + const struct s2255_fmt *cur_fmt[MAX_CHANNELS]; + int cur_frame[MAX_CHANNELS]; + int last_frame[MAX_CHANNELS]; + u32 cc; /* current channel */ + int b_acquire[MAX_CHANNELS]; + unsigned long req_image_size[MAX_CHANNELS]; + int bad_payload[MAX_CHANNELS]; + unsigned long frame_count[MAX_CHANNELS]; + int frame_ready; + struct kref kref; + spinlock_t slock; +}; +#define to_s2255_dev(d) container_of(d, struct s2255_dev, kref) + +struct s2255_fmt { + char *name; + u32 fourcc; + int depth; +}; + +/* buffer for one video frame */ +struct s2255_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + const struct s2255_fmt *fmt; +}; + +struct s2255_fh { + struct s2255_dev *dev; + unsigned int resources; + const struct s2255_fmt *fmt; + unsigned int width; + unsigned int height; + struct videobuf_queue vb_vidq; + enum v4l2_buf_type type; + int channel; + /* mode below is the desired mode. + mode in s2255_dev is the current mode that was last set */ + struct s2255_mode mode; +}; + +#define S2255_MAX_USERS 1 + +#define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ +#define S2255_MAJOR_VERSION 1 +#define S2255_MINOR_VERSION 13 +#define S2255_RELEASE 0 +#define S2255_VERSION KERNEL_VERSION(S2255_MAJOR_VERSION, \ + S2255_MINOR_VERSION, \ + S2255_RELEASE) + +/* vendor ids */ +#define USB_S2255_VENDOR_ID 0x1943 +#define USB_S2255_PRODUCT_ID 0x2255 +#define S2255_NORMS (V4L2_STD_PAL | V4L2_STD_NTSC) +/* frame prefix size (sent once every frame) */ +#define PREFIX_SIZE 512 + +/* Channels on box are in reverse order */ +static unsigned long G_chnmap[MAX_CHANNELS] = { 3, 2, 1, 0 }; + +static LIST_HEAD(s2255_devlist); + +static int debug; +static int *s2255_debug = &debug; + +static int s2255_start_readpipe(struct s2255_dev *dev); +static void s2255_stop_readpipe(struct s2255_dev *dev); +static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn); +static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn); +static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, + int chn); +static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, + struct s2255_mode *mode); +static int s2255_board_shutdown(struct s2255_dev *dev); +static void s2255_exit_v4l(struct s2255_dev *dev); +static void s2255_fwload_start(struct s2255_dev *dev); + +#define dprintk(level, fmt, arg...) \ + do { \ + if (*s2255_debug >= (level)) { \ + printk(KERN_DEBUG "s2255: " fmt, ##arg); \ + } \ + } while (0) + + +static struct usb_driver s2255_driver; + + +/* Declare static vars that will be used as parameters */ +static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ + +/* start video number */ +static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ + +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); +module_param(vid_limit, int, 0); +MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); +module_param(video_nr, int, 0); +MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); + +/* USB device table */ +static struct usb_device_id s2255_table[] = { + {USB_DEVICE(USB_S2255_VENDOR_ID, USB_S2255_PRODUCT_ID)}, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, s2255_table); + + +#define BUFFER_TIMEOUT msecs_to_jiffies(400) + +/* supported controls */ +static struct v4l2_queryctrl s2255_qctrl[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = -127, + .maximum = 128, + .step = 1, + .default_value = 0, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 0x1, + .default_value = DEF_CONTRAST, + .flags = 0, + }, { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 0x1, + .default_value = DEF_SATURATION, + .flags = 0, + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 255, + .step = 0x1, + .default_value = DEF_HUE, + .flags = 0, + } +}; + +static int qctl_regs[ARRAY_SIZE(s2255_qctrl)]; + +/* image formats. */ +static const struct s2255_fmt formats[] = { + { + .name = "4:2:2, planar, YUV422P", + .fourcc = V4L2_PIX_FMT_YUV422P, + .depth = 16 + + }, { + .name = "4:2:2, packed, YUYV", + .fourcc = V4L2_PIX_FMT_YUYV, + .depth = 16 + + }, { + .name = "4:2:2, packed, UYVY", + .fourcc = V4L2_PIX_FMT_UYVY, + .depth = 16 + }, { + .name = "8bpp GREY", + .fourcc = V4L2_PIX_FMT_GREY, + .depth = 8 + } +}; + +static int norm_maxw(struct video_device *vdev) +{ + return (vdev->current_norm & V4L2_STD_NTSC) ? + LINE_SZ_4CIFS_NTSC : LINE_SZ_4CIFS_PAL; +} + +static int norm_maxh(struct video_device *vdev) +{ + return (vdev->current_norm & V4L2_STD_NTSC) ? + (NUM_LINES_1CIFS_NTSC * 2) : (NUM_LINES_1CIFS_PAL * 2); +} + +static int norm_minw(struct video_device *vdev) +{ + return (vdev->current_norm & V4L2_STD_NTSC) ? + LINE_SZ_1CIFS_NTSC : LINE_SZ_1CIFS_PAL; +} + +static int norm_minh(struct video_device *vdev) +{ + return (vdev->current_norm & V4L2_STD_NTSC) ? + (NUM_LINES_1CIFS_NTSC) : (NUM_LINES_1CIFS_PAL); +} + + +/* converts 2255 planar format to yuyv or uyvy */ +static void planar422p_to_yuv_packed(const unsigned char *in, + unsigned char *out, + int width, int height, + int fmt) +{ + unsigned char *pY; + unsigned char *pCb; + unsigned char *pCr; + unsigned long size = height * width; + unsigned int i; + pY = (unsigned char *)in; + pCr = (unsigned char *)in + height * width; + pCb = (unsigned char *)in + height * width + (height * width / 2); + for (i = 0; i < size * 2; i += 4) { + out[i] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCr++; + out[i + 1] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCr++ : *pY++; + out[i + 2] = (fmt == V4L2_PIX_FMT_YUYV) ? *pY++ : *pCb++; + out[i + 3] = (fmt == V4L2_PIX_FMT_YUYV) ? *pCb++ : *pY++; + } + return; +} + + +/* kickstarts the firmware loading. from probe + */ +static void s2255_timer(unsigned long user_data) +{ + struct s2255_fw *data = (struct s2255_fw *)user_data; + dprintk(100, "s2255 timer\n"); + if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { + printk(KERN_ERR "s2255: can't submit urb\n"); + if (data->fw) { + release_firmware(data->fw); + data->fw = NULL; + } + return; + } +} + +/* called when DSP is up and running. DSP is guaranteed to + be running after S2255_DSP_BOOTTIME */ +static void s2255_dsp_running(unsigned long user_data) +{ + struct s2255_fw *data = (struct s2255_fw *)user_data; + dprintk(1, "dsp running\n"); + atomic_set(&data->fw_state, S2255_FW_SUCCESS); + wake_up(&data->wait_fw); + printk(KERN_INFO "s2255: firmware loaded successfully\n"); + return; +} + + +/* this loads the firmware asynchronously. + Originally this was done synchroously in probe. + But it is better to load it asynchronously here than block + inside the probe function. Blocking inside probe affects boot time. + FW loading is triggered by the timer in the probe function +*/ +static void s2255_fwchunk_complete(struct urb *urb) +{ + struct s2255_fw *data = urb->context; + struct usb_device *udev = urb->dev; + int len; + dprintk(100, "udev %p urb %p", udev, urb); + + if (urb->status) { + dev_err(&udev->dev, "URB failed with status %d", urb->status); + return; + } + if (data->fw_urb == NULL) { + dev_err(&udev->dev, "early disconncect\n"); + return; + } +#define CHUNK_SIZE 512 + /* all USB transfers must be done with continuous kernel memory. + can't allocate more than 128k in current linux kernel, so + upload the firmware in chunks + */ + if (data->fw_loaded < data->fw_size) { + len = (data->fw_loaded + CHUNK_SIZE) > data->fw_size ? + data->fw_size % CHUNK_SIZE : CHUNK_SIZE; + + if (len < CHUNK_SIZE) + memset(data->pfw_data, 0, CHUNK_SIZE); + + dprintk(100, "completed len %d, loaded %d \n", len, + data->fw_loaded); + + memcpy(data->pfw_data, + (char *) data->fw->data + data->fw_loaded, len); + + usb_fill_bulk_urb(data->fw_urb, udev, usb_sndbulkpipe(udev, 2), + data->pfw_data, CHUNK_SIZE, + s2255_fwchunk_complete, data); + if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { + dev_err(&udev->dev, "failed submit URB\n"); + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); + return; + } + data->fw_loaded += len; + } else { + init_timer(&data->dsp_wait); + data->dsp_wait.function = s2255_dsp_running; + data->dsp_wait.data = (unsigned long)data; + atomic_set(&data->fw_state, S2255_FW_LOADED_DSPWAIT); + mod_timer(&data->dsp_wait, msecs_to_jiffies(S2255_DSP_BOOTTIME) + + jiffies); + } + dprintk(100, "2255 complete done\n"); + return; + +} + +static int s2255_got_frame(struct s2255_dev *dev, int chn) +{ + struct s2255_dmaqueue *dma_q = &dev->vidq[chn]; + struct s2255_buffer *buf; + unsigned long flags = 0; + int rc = 0; + dprintk(2, "wakeup: %p channel: %d\n", &dma_q, chn); + spin_lock_irqsave(&dev->slock, flags); + + if (list_empty(&dma_q->active)) { + dprintk(1, "No active queue to serve\n"); + rc = -1; + goto unlock; + } + buf = list_entry(dma_q->active.next, + struct s2255_buffer, vb.queue); + + if (!waitqueue_active(&buf->vb.done)) { + /* no one active */ + rc = -1; + goto unlock; + } + list_del(&buf->vb.queue); + do_gettimeofday(&buf->vb.ts); + dprintk(100, "[%p/%d] wakeup\n", buf, buf->vb.i); + + s2255_fillbuff(dev, buf, dma_q->channel); + wake_up(&buf->vb.done); + dprintk(2, "wakeup [buf/i] [%p/%d]\n", buf, buf->vb.i); +unlock: + spin_unlock_irqrestore(&dev->slock, flags); + return 0; +} + + +static const struct s2255_fmt *format_by_fourcc(int fourcc) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); i++) { + if (-1 == formats[i].fourcc) + continue; + if (formats[i].fourcc == fourcc) + return formats + i; + } + return NULL; +} + + + + +/* video buffer vmalloc implementation based partly on VIVI driver which is + * Copyright (c) 2006 by + * Mauro Carvalho Chehab + * Ted Walther + * John Sokol + * http://v4l.videotechnology.com/ + * + */ +static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf, + int chn) +{ + int pos = 0; + struct timeval ts; + const char *tmpbuf; + char *vbuf = videobuf_to_vmalloc(&buf->vb); + unsigned long last_frame; + struct s2255_framei *frm; + + if (!vbuf) + return; + + last_frame = dev->last_frame[chn]; + if (last_frame != -1) { + frm = &dev->buffer[chn].frame[last_frame]; + tmpbuf = + (const char *)dev->buffer[chn].frame[last_frame].lpvbits; + switch (buf->fmt->fourcc) { + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + planar422p_to_yuv_packed((const unsigned char *)tmpbuf, + vbuf, buf->vb.width, + buf->vb.height, + buf->fmt->fourcc); + break; + case V4L2_PIX_FMT_GREY: + memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height); + break; + case V4L2_PIX_FMT_YUV422P: + memcpy(vbuf, tmpbuf, + buf->vb.width * buf->vb.height * 2); + break; + default: + printk(KERN_DEBUG "s2255: unknown format?\n"); + } + dev->last_frame[chn] = -1; + /* done with the frame, free it */ + frm->ulState = 0; + dprintk(4, "freeing buffer\n"); + } else { + printk(KERN_ERR "s2255: =======no frame\n"); + return; + + } + dprintk(2, "s2255fill at : Buffer 0x%08lx size= %d\n", + (unsigned long)vbuf, pos); + /* tell v4l buffer was filled */ + + buf->vb.field_count++; + do_gettimeofday(&ts); + buf->vb.ts = ts; + buf->vb.state = VIDEOBUF_DONE; +} + + +/* ------------------------------------------------------------------ + Videobuf operations + ------------------------------------------------------------------*/ + +static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct s2255_fh *fh = vq->priv_data; + + *size = fh->width * fh->height * (fh->fmt->depth >> 3); + + if (0 == *count) + *count = S2255_DEF_BUFS; + + while (*size * *count > vid_limit * 1024 * 1024) + (*count)--; + + return 0; +} + +static void free_buffer(struct videobuf_queue *vq, struct s2255_buffer *buf) +{ + dprintk(4, "%s\n", __func__); + + videobuf_waiton(&buf->vb, 0, 0); + videobuf_vmalloc_free(&buf->vb); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct s2255_fh *fh = vq->priv_data; + struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); + int rc; + dprintk(4, "%s, field=%d\n", __func__, field); + if (fh->fmt == NULL) + return -EINVAL; + + if ((fh->width < norm_minw(fh->dev->vdev[fh->channel])) || + (fh->width > norm_maxw(fh->dev->vdev[fh->channel])) || + (fh->height < norm_minh(fh->dev->vdev[fh->channel])) || + (fh->height > norm_maxh(fh->dev->vdev[fh->channel]))) { + dprintk(4, "invalid buffer prepare\n"); + return -EINVAL; + } + + buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3); + + if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) { + dprintk(4, "invalid buffer prepare\n"); + return -EINVAL; + } + + buf->fmt = fh->fmt; + buf->vb.width = fh->width; + buf->vb.height = fh->height; + buf->vb.field = field; + + + if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { + rc = videobuf_iolock(vq, &buf->vb, NULL); + if (rc < 0) + goto fail; + } + + buf->vb.state = VIDEOBUF_PREPARED; + return 0; +fail: + free_buffer(vq, buf); + return rc; +} + +static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) +{ + struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); + struct s2255_fh *fh = vq->priv_data; + struct s2255_dev *dev = fh->dev; + struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel]; + + dprintk(1, "%s\n", __func__); + + buf->vb.state = VIDEOBUF_QUEUED; + list_add_tail(&buf->vb.queue, &vidq->active); +} + +static void buffer_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb); + struct s2255_fh *fh = vq->priv_data; + dprintk(4, "%s %d\n", __func__, fh->channel); + free_buffer(vq, buf); +} + +static struct videobuf_queue_ops s2255_video_qops = { + .buf_setup = buffer_setup, + .buf_prepare = buffer_prepare, + .buf_queue = buffer_queue, + .buf_release = buffer_release, +}; + + +static int res_get(struct s2255_dev *dev, struct s2255_fh *fh) +{ + /* is it free? */ + mutex_lock(&dev->lock); + if (dev->resources[fh->channel]) { + /* no, someone else uses it */ + mutex_unlock(&dev->lock); + return 0; + } + /* it's free, grab it */ + dev->resources[fh->channel] = 1; + dprintk(1, "res: get\n"); + mutex_unlock(&dev->lock); + return 1; +} + +static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh) +{ + return (dev->resources[fh->channel]); +} + +static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) +{ + dev->resources[fh->channel] = 0; + dprintk(1, "res: put\n"); +} + + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct s2255_fh *fh = file->private_data; + struct s2255_dev *dev = fh->dev; + strlcpy(cap->driver, "s2255", sizeof(cap->driver)); + strlcpy(cap->card, "s2255", sizeof(cap->card)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); + cap->version = S2255_VERSION; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + return 0; +} + +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + int index = 0; + if (f) + index = f->index; + + if (index >= ARRAY_SIZE(formats)) + return -EINVAL; + + dprintk(4, "name %s\n", formats[index].name); + strlcpy(f->description, formats[index].name, sizeof(f->description)); + f->pixelformat = formats[index].fourcc; + return 0; +} + +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct s2255_fh *fh = priv; + + f->fmt.pix.width = fh->width; + f->fmt.pix.height = fh->height; + f->fmt.pix.field = fh->vb_vidq.field; + f->fmt.pix.pixelformat = fh->fmt->fourcc; + f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3); + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + + return (0); +} + +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + const struct s2255_fmt *fmt; + enum v4l2_field field; + int b_any_field = 0; + struct s2255_fh *fh = priv; + struct s2255_dev *dev = fh->dev; + int is_ntsc; + + is_ntsc = + (dev->vdev[fh->channel]->current_norm & V4L2_STD_NTSC) ? 1 : 0; + + fmt = format_by_fourcc(f->fmt.pix.pixelformat); + + if (fmt == NULL) + return -EINVAL; + + field = f->fmt.pix.field; + if (field == V4L2_FIELD_ANY) + b_any_field = 1; + + dprintk(4, "try format %d \n", is_ntsc); + /* supports 3 sizes. see s2255drv.h */ + dprintk(50, "width test %d, height %d\n", + f->fmt.pix.width, f->fmt.pix.height); + if (is_ntsc) { + /* NTSC */ + if (f->fmt.pix.height >= NUM_LINES_1CIFS_NTSC * 2) { + f->fmt.pix.height = NUM_LINES_1CIFS_NTSC * 2; + if (b_any_field) { + field = V4L2_FIELD_SEQ_TB; + } else if (!((field == V4L2_FIELD_INTERLACED) || + (field == V4L2_FIELD_SEQ_TB) || + (field == V4L2_FIELD_INTERLACED_TB))) { + dprintk(1, "unsupported field setting\n"); + return -EINVAL; + } + } else { + f->fmt.pix.height = NUM_LINES_1CIFS_NTSC; + if (b_any_field) { + field = V4L2_FIELD_TOP; + } else if (!((field == V4L2_FIELD_TOP) || + (field == V4L2_FIELD_BOTTOM))) { + dprintk(1, "unsupported field setting\n"); + return -EINVAL; + } + + } + if (f->fmt.pix.width >= LINE_SZ_4CIFS_NTSC) + f->fmt.pix.width = LINE_SZ_4CIFS_NTSC; + else if (f->fmt.pix.width >= LINE_SZ_2CIFS_NTSC) + f->fmt.pix.width = LINE_SZ_2CIFS_NTSC; + else if (f->fmt.pix.width >= LINE_SZ_1CIFS_NTSC) + f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; + else + f->fmt.pix.width = LINE_SZ_1CIFS_NTSC; + } else { + /* PAL */ + if (f->fmt.pix.height >= NUM_LINES_1CIFS_PAL * 2) { + f->fmt.pix.height = NUM_LINES_1CIFS_PAL * 2; + if (b_any_field) { + field = V4L2_FIELD_SEQ_TB; + } else if (!((field == V4L2_FIELD_INTERLACED) || + (field == V4L2_FIELD_SEQ_TB) || + (field == V4L2_FIELD_INTERLACED_TB))) { + dprintk(1, "unsupported field setting\n"); + return -EINVAL; + } + } else { + f->fmt.pix.height = NUM_LINES_1CIFS_PAL; + if (b_any_field) { + field = V4L2_FIELD_TOP; + } else if (!((field == V4L2_FIELD_TOP) || + (field == V4L2_FIELD_BOTTOM))) { + dprintk(1, "unsupported field setting\n"); + return -EINVAL; + } + } + if (f->fmt.pix.width >= LINE_SZ_4CIFS_PAL) { + dprintk(50, "pal 704\n"); + f->fmt.pix.width = LINE_SZ_4CIFS_PAL; + field = V4L2_FIELD_SEQ_TB; + } else if (f->fmt.pix.width >= LINE_SZ_2CIFS_PAL) { + dprintk(50, "pal 352A\n"); + f->fmt.pix.width = LINE_SZ_2CIFS_PAL; + field = V4L2_FIELD_TOP; + } else if (f->fmt.pix.width >= LINE_SZ_1CIFS_PAL) { + dprintk(50, "pal 352B\n"); + f->fmt.pix.width = LINE_SZ_1CIFS_PAL; + field = V4L2_FIELD_TOP; + } else { + dprintk(50, "pal 352C\n"); + f->fmt.pix.width = LINE_SZ_1CIFS_PAL; + field = V4L2_FIELD_TOP; + } + } + + dprintk(50, "width %d height %d field %d \n", f->fmt.pix.width, + f->fmt.pix.height, f->fmt.pix.field); + f->fmt.pix.field = field; + f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3; + f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; + return 0; +} + +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct s2255_fh *fh = priv; + const struct s2255_fmt *fmt; + struct videobuf_queue *q = &fh->vb_vidq; + int ret; + int norm; + + ret = vidioc_try_fmt_vid_cap(file, fh, f); + + if (ret < 0) + return (ret); + + fmt = format_by_fourcc(f->fmt.pix.pixelformat); + + if (fmt == NULL) + return -EINVAL; + + mutex_lock(&q->vb_lock); + + if (videobuf_queue_is_busy(&fh->vb_vidq)) { + dprintk(1, "queue busy\n"); + ret = -EBUSY; + goto out_s_fmt; + } + + if (res_locked(fh->dev, fh)) { + dprintk(1, "can't change format after started\n"); + ret = -EBUSY; + goto out_s_fmt; + } + + fh->fmt = fmt; + fh->width = f->fmt.pix.width; + fh->height = f->fmt.pix.height; + fh->vb_vidq.field = f->fmt.pix.field; + fh->type = f->type; + norm = norm_minw(fh->dev->vdev[fh->channel]); + if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) { + if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) + fh->mode.scale = SCALE_4CIFS; + else + fh->mode.scale = SCALE_2CIFS; + + } else { + fh->mode.scale = SCALE_1CIFS; + } + + /* color mode */ + switch (fh->fmt->fourcc) { + case V4L2_PIX_FMT_GREY: + fh->mode.color = COLOR_Y8; + break; + case V4L2_PIX_FMT_YUV422P: + fh->mode.color = COLOR_YUVPL; + break; + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + default: + fh->mode.color = COLOR_YUVPK; + break; + } + ret = 0; +out_s_fmt: + mutex_unlock(&q->vb_lock); + return ret; +} + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *p) +{ + int rc; + struct s2255_fh *fh = priv; + rc = videobuf_reqbufs(&fh->vb_vidq, p); + return rc; +} + +static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + int rc; + struct s2255_fh *fh = priv; + rc = videobuf_querybuf(&fh->vb_vidq, p); + return rc; +} + +static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + int rc; + struct s2255_fh *fh = priv; + rc = videobuf_qbuf(&fh->vb_vidq, p); + return rc; +} + +static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) +{ + int rc; + struct s2255_fh *fh = priv; + rc = videobuf_dqbuf(&fh->vb_vidq, p, file->f_flags & O_NONBLOCK); + return rc; +} + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidioc_cgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) +{ + struct s2255_fh *fh = priv; + + return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); +} +#endif + +/* write to the configuration pipe, synchronously */ +static int s2255_write_config(struct usb_device *udev, unsigned char *pbuf, + int size) +{ + int pipe; + int done; + long retval = -1; + if (udev) { + pipe = usb_sndbulkpipe(udev, S2255_CONFIG_EP); + retval = usb_bulk_msg(udev, pipe, pbuf, size, &done, 500); + } + return retval; +} + +static u32 get_transfer_size(struct s2255_mode *mode) +{ + int linesPerFrame = LINE_SZ_DEF; + int pixelsPerLine = NUM_LINES_DEF; + u32 outImageSize; + u32 usbInSize; + unsigned int mask_mult; + + if (mode == NULL) + return 0; + + if (mode->format == FORMAT_NTSC) { + switch (mode->scale) { + case SCALE_4CIFS: + linesPerFrame = NUM_LINES_4CIFS_NTSC * 2; + pixelsPerLine = LINE_SZ_4CIFS_NTSC; + break; + case SCALE_2CIFS: + linesPerFrame = NUM_LINES_2CIFS_NTSC; + pixelsPerLine = LINE_SZ_2CIFS_NTSC; + break; + case SCALE_1CIFS: + linesPerFrame = NUM_LINES_1CIFS_NTSC; + pixelsPerLine = LINE_SZ_1CIFS_NTSC; + break; + default: + break; + } + } else if (mode->format == FORMAT_PAL) { + switch (mode->scale) { + case SCALE_4CIFS: + linesPerFrame = NUM_LINES_4CIFS_PAL * 2; + pixelsPerLine = LINE_SZ_4CIFS_PAL; + break; + case SCALE_2CIFS: + linesPerFrame = NUM_LINES_2CIFS_PAL; + pixelsPerLine = LINE_SZ_2CIFS_PAL; + break; + case SCALE_1CIFS: + linesPerFrame = NUM_LINES_1CIFS_PAL; + pixelsPerLine = LINE_SZ_1CIFS_PAL; + break; + default: + break; + } + } + outImageSize = linesPerFrame * pixelsPerLine; + if (mode->color != COLOR_Y8) { + /* 2 bytes/pixel if not monochrome */ + outImageSize *= 2; + } + + /* total bytes to send including prefix and 4K padding; + must be a multiple of USB_READ_SIZE */ + usbInSize = outImageSize + PREFIX_SIZE; /* always send prefix */ + mask_mult = 0xffffffffUL - DEF_USB_BLOCK + 1; + /* if size not a multiple of USB_READ_SIZE */ + if (usbInSize & ~mask_mult) + usbInSize = (usbInSize & mask_mult) + (DEF_USB_BLOCK); + return usbInSize; +} + +static void dump_verify_mode(struct s2255_dev *sdev, struct s2255_mode *mode) +{ + struct device *dev = &sdev->udev->dev; + dev_info(dev, "------------------------------------------------\n"); + dev_info(dev, "verify mode\n"); + dev_info(dev, "format: %d\n", mode->format); + dev_info(dev, "scale: %d\n", mode->scale); + dev_info(dev, "fdec: %d\n", mode->fdec); + dev_info(dev, "color: %d\n", mode->color); + dev_info(dev, "bright: 0x%x\n", mode->bright); + dev_info(dev, "restart: 0x%x\n", mode->restart); + dev_info(dev, "usb_block: 0x%x\n", mode->usb_block); + dev_info(dev, "single: 0x%x\n", mode->single); + dev_info(dev, "------------------------------------------------\n"); +} + +/* + * set mode is the function which controls the DSP. + * the restart parameter in struct s2255_mode should be set whenever + * the image size could change via color format, video system or image + * size. + * When the restart parameter is set, we sleep for ONE frame to allow the + * DSP time to get the new frame + */ +static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn, + struct s2255_mode *mode) +{ + int res; + u32 *buffer; + unsigned long chn_rev; + + chn_rev = G_chnmap[chn]; + dprintk(3, "mode scale [%ld] %p %d\n", chn, mode, mode->scale); + dprintk(3, "mode scale [%ld] %p %d\n", chn, &dev->mode[chn], + dev->mode[chn].scale); + dprintk(2, "mode contrast %x\n", mode->contrast); + + /* save the mode */ + dev->mode[chn] = *mode; + dev->req_image_size[chn] = get_transfer_size(mode); + dprintk(1, "transfer size %ld\n", dev->req_image_size[chn]); + + buffer = kzalloc(512, GFP_KERNEL); + if (buffer == NULL) { + dev_err(&dev->udev->dev, "out of mem\n"); + return -ENOMEM; + } + + /* set the mode */ + buffer[0] = IN_DATA_TOKEN; + buffer[1] = (u32) chn_rev; + buffer[2] = CMD_SET_MODE; + memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode)); + res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); + if (debug) + dump_verify_mode(dev, mode); + kfree(buffer); + dprintk(1, "set mode done chn %lu, %d\n", chn, res); + + /* wait at least 3 frames before continuing */ + if (mode->restart) + msleep(125); + + /* clear the restart flag */ + dev->mode[chn].restart = 0; + + return res; +} + +static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) +{ + int res; + struct s2255_fh *fh = priv; + struct s2255_dev *dev = fh->dev; + struct s2255_mode *new_mode; + struct s2255_mode *old_mode; + int chn; + int j; + dprintk(4, "%s\n", __func__); + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + dev_err(&dev->udev->dev, "invalid fh type0\n"); + return -EINVAL; + } + if (i != fh->type) { + dev_err(&dev->udev->dev, "invalid fh type1\n"); + return -EINVAL; + } + + if (!res_get(dev, fh)) { + dev_err(&dev->udev->dev, "res get busy\n"); + return -EBUSY; + } + + /* send a set mode command everytime with restart. + in case we switch resolutions or other parameters */ + chn = fh->channel; + new_mode = &fh->mode; + old_mode = &fh->dev->mode[chn]; + + if (new_mode->color != old_mode->color) + new_mode->restart = 1; + else if (new_mode->scale != old_mode->scale) + new_mode->restart = 1; + else if (new_mode->format != old_mode->format) + new_mode->restart = 1; + + s2255_set_mode(dev, chn, new_mode); + new_mode->restart = 0; + *old_mode = *new_mode; + dev->cur_fmt[chn] = fh->fmt; + dprintk(1, "%s[%d]\n", __func__, chn); + dev->last_frame[chn] = -1; + dev->bad_payload[chn] = 0; + dev->cur_frame[chn] = 0; + for (j = 0; j < SYS_FRAMES; j++) { + dev->buffer[chn].frame[j].ulState = 0; + dev->buffer[chn].frame[j].cur_size = 0; + } + res = videobuf_streamon(&fh->vb_vidq); + if (res == 0) { + s2255_start_acquire(dev, chn); + dev->b_acquire[chn] = 1; + } else { + res_free(dev, fh); + } + return res; +} + +static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) +{ + int res; + struct s2255_fh *fh = priv; + struct s2255_dev *dev = fh->dev; + + dprintk(4, "%s\n, channel: %d", __func__, fh->channel); + if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + printk(KERN_ERR "invalid fh type0\n"); + return -EINVAL; + } + if (i != fh->type) { + printk(KERN_ERR "invalid type i\n"); + return -EINVAL; + } + s2255_stop_acquire(dev, fh->channel); + res = videobuf_streamoff(&fh->vb_vidq); + res_free(dev, fh); + return res; +} + +static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) +{ + struct s2255_fh *fh = priv; + struct s2255_mode *mode; + struct videobuf_queue *q = &fh->vb_vidq; + int ret = 0; + + mutex_lock(&q->vb_lock); + if (videobuf_queue_is_busy(q)) { + dprintk(1, "queue busy\n"); + ret = -EBUSY; + goto out_s_std; + } + + if (res_locked(fh->dev, fh)) { + dprintk(1, "can't change standard after started\n"); + ret = -EBUSY; + goto out_s_std; + } + mode = &fh->mode; + + if (*i & V4L2_STD_NTSC) { + dprintk(4, "vidioc_s_std NTSC\n"); + mode->format = FORMAT_NTSC; + } else if (*i & V4L2_STD_PAL) { + dprintk(4, "vidioc_s_std PAL\n"); + mode->format = FORMAT_PAL; + } else { + ret = -EINVAL; + } +out_s_std: + mutex_unlock(&q->vb_lock); + return ret; +} + +/* Sensoray 2255 is a multiple channel capture device. + It does not have a "crossbar" of inputs. + We use one V4L device per channel. The user must + be aware that certain combinations are not allowed. + For instance, you cannot do full FPS on more than 2 channels(2 videodevs) + at once in color(you can do full fps on 4 channels with greyscale. +*/ +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + if (inp->index != 0) + return -EINVAL; + + inp->type = V4L2_INPUT_TYPE_CAMERA; + inp->std = S2255_NORMS; + strlcpy(inp->name, "Camera", sizeof(inp->name)); + return (0); +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i > 0) + return -EINVAL; + return 0; +} + +/* --- controls ---------------------------------------------- */ +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *qc) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) + if (qc->id && qc->id == s2255_qctrl[i].id) { + memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc)); + return (0); + } + + dprintk(4, "query_ctrl -EINVAL %d\n", qc->id); + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) + if (ctrl->id == s2255_qctrl[i].id) { + ctrl->value = qctl_regs[i]; + return (0); + } + dprintk(4, "g_ctrl -EINVAL\n"); + + return -EINVAL; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + int i; + struct s2255_fh *fh = priv; + struct s2255_dev *dev = fh->dev; + struct s2255_mode *mode; + mode = &fh->mode; + dprintk(4, "vidioc_s_ctrl\n"); + for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) { + if (ctrl->id == s2255_qctrl[i].id) { + if (ctrl->value < s2255_qctrl[i].minimum || + ctrl->value > s2255_qctrl[i].maximum) + return (-ERANGE); + + qctl_regs[i] = ctrl->value; + /* update the mode to the corresponding value */ + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + mode->bright = ctrl->value; + break; + case V4L2_CID_CONTRAST: + mode->contrast = ctrl->value; + break; + case V4L2_CID_HUE: + mode->hue = ctrl->value; + break; + case V4L2_CID_SATURATION: + mode->saturation = ctrl->value; + break; + } + mode->restart = 0; + /* set mode here. Note: stream does not need restarted. + some V4L programs restart stream unnecessarily + after a s_crtl. + */ + s2255_set_mode(dev, fh->channel, mode); + return 0; + } + } + return -EINVAL; +} + +static int s2255_open(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + struct s2255_dev *h, *dev = NULL; + struct s2255_fh *fh; + struct list_head *list; + enum v4l2_buf_type type = 0; + int i = 0; + int cur_channel = -1; + dprintk(1, "s2255: open called (minor=%d)\n", minor); + + list_for_each(list, &s2255_devlist) { + h = list_entry(list, struct s2255_dev, s2255_devlist); + for (i = 0; i < MAX_CHANNELS; i++) { + if (h->vdev[i]->minor == minor) { + cur_channel = i; + dev = h; + type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + } + } + } + + if ((NULL == dev) || (cur_channel == -1)) { + dprintk(1, "s2255: openv4l no dev\n"); + return -ENODEV; + } + + mutex_lock(&dev->open_lock); + + dev->users[cur_channel]++; + if (dev->users[cur_channel] > S2255_MAX_USERS) { + dev->users[cur_channel]--; + mutex_unlock(&dev->open_lock); + printk(KERN_INFO "s2255drv: too many open handles!\n"); + return -EBUSY; + } + + if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) { + err("2255 firmware load failed. retrying.\n"); + s2255_fwload_start(dev); + wait_event_timeout(dev->fw_data->wait_fw, + (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_NOTLOADED), + msecs_to_jiffies(S2255_LOAD_TIMEOUT)); + if (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_SUCCESS) { + printk(KERN_INFO "2255 FW load failed after 2 tries\n"); + mutex_unlock(&dev->open_lock); + return -EFAULT; + } + } else if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_NOTLOADED) { + /* give S2255_LOAD_TIMEOUT time for firmware to load in case + driver loaded and then device immediately opened */ + printk(KERN_INFO "%s waiting for firmware load\n", __func__); + wait_event_timeout(dev->fw_data->wait_fw, + (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_NOTLOADED), + msecs_to_jiffies(S2255_LOAD_TIMEOUT)); + if (atomic_read(&dev->fw_data->fw_state) + != S2255_FW_SUCCESS) { + printk(KERN_INFO "2255 firmware not loaded" + "try again\n"); + mutex_unlock(&dev->open_lock); + return -EBUSY; + } + } + + /* allocate + initialize per filehandle data */ + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (NULL == fh) { + mutex_unlock(&dev->open_lock); + return -ENOMEM; + } + + file->private_data = fh; + fh->dev = dev; + fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fh->mode = dev->mode[cur_channel]; + fh->fmt = dev->cur_fmt[cur_channel]; + /* default 4CIF NTSC */ + fh->width = LINE_SZ_4CIFS_NTSC; + fh->height = NUM_LINES_4CIFS_NTSC * 2; + fh->channel = cur_channel; + + /* Put all controls at a sane state */ + for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) + qctl_regs[i] = s2255_qctrl[i].default_value; + + dprintk(1, "s2255drv: open minor=%d type=%s users=%d\n", + minor, v4l2_type_names[type], dev->users[cur_channel]); + dprintk(2, "s2255drv: open: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", + (unsigned long)fh, (unsigned long)dev, + (unsigned long)&dev->vidq[cur_channel]); + dprintk(4, "s2255drv: open: list_empty active=%d\n", + list_empty(&dev->vidq[cur_channel].active)); + + videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops, + NULL, &dev->slock, + fh->type, + V4L2_FIELD_INTERLACED, + sizeof(struct s2255_buffer), fh); + + kref_get(&dev->kref); + mutex_unlock(&dev->open_lock); + return 0; +} + + +static unsigned int s2255_poll(struct file *file, + struct poll_table_struct *wait) +{ + struct s2255_fh *fh = file->private_data; + int rc; + dprintk(100, "%s\n", __func__); + + if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) + return POLLERR; + + rc = videobuf_poll_stream(file, &fh->vb_vidq, wait); + return rc; +} + +static void s2255_destroy(struct kref *kref) +{ + struct s2255_dev *dev = to_s2255_dev(kref); + if (!dev) { + printk(KERN_ERR "s2255drv: kref problem\n"); + return; + } + /* prevent s2255_disconnect from racing s2255_open */ + mutex_lock(&dev->open_lock); + s2255_exit_v4l(dev); + /* device unregistered so no longer possible to open. open_mutex + can be unlocked */ + mutex_unlock(&dev->open_lock); + + /* board shutdown stops the read pipe if it is running */ + s2255_board_shutdown(dev); + + /* make sure firmware still not trying to load */ + if (dev->fw_data->fw_urb) { + dprintk(2, "kill fw_urb\n"); + usb_kill_urb(dev->fw_data->fw_urb); + usb_free_urb(dev->fw_data->fw_urb); + dev->fw_data->fw_urb = NULL; + } + + /* make sure we aren't waiting for the DSP */ + if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) { + /* if we are, wait for the wakeup for fw_success or timeout */ + wait_event_timeout(dev->fw_data->wait_fw, + (atomic_read(&dev->fw_data->fw_state) + == S2255_FW_SUCCESS), + msecs_to_jiffies(S2255_LOAD_TIMEOUT)); + } + + if (dev->fw_data) { + kfree(dev->fw_data->pfw_data); + kfree(dev->fw_data); + } + + if (dev->fw_data->fw) { + release_firmware(dev->fw_data->fw); + dev->fw_data->fw = NULL; + } + + usb_put_dev(dev->udev); + dprintk(1, "%s", __func__); + kfree(dev); +} + +static int s2255_close(struct inode *inode, struct file *file) +{ + struct s2255_fh *fh = file->private_data; + struct s2255_dev *dev = fh->dev; + int minor = iminor(inode); + if (!dev) + return -ENODEV; + + mutex_lock(&dev->open_lock); + + if (dev->b_acquire[fh->channel]) + s2255_stop_acquire(dev, fh->channel); + res_free(dev, fh); + videobuf_mmap_free(&fh->vb_vidq); + kfree(fh); + dev->users[fh->channel]--; + mutex_unlock(&dev->open_lock); + + kref_put(&dev->kref, s2255_destroy); + dprintk(1, "s2255: close called (minor=%d, users=%d)\n", + minor, dev->users[fh->channel]); + return 0; +} + +static int s2255_mmap_v4l(struct file *file, struct vm_area_struct *vma) +{ + struct s2255_fh *fh = file->private_data; + int ret; + + if (!fh) + return -ENODEV; + dprintk(4, "mmap called, vma=0x%08lx\n", (unsigned long)vma); + + ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); + + dprintk(4, "vma start=0x%08lx, size=%ld, ret=%d\n", + (unsigned long)vma->vm_start, + (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, ret); + + return ret; +} + +static const struct file_operations s2255_fops_v4l = { + .owner = THIS_MODULE, + .open = s2255_open, + .release = s2255_close, + .poll = s2255_poll, + .ioctl = video_ioctl2, /* V4L2 ioctl handler */ + .compat_ioctl = v4l_compat_ioctl32, + .mmap = s2255_mmap_v4l, + .llseek = no_llseek, +}; + +static struct video_device template = { + .name = "s2255v", + .type = VID_TYPE_CAPTURE, + .fops = &s2255_fops_v4l, + .minor = -1, + .release = video_device_release, + .vidioc_querycap = vidioc_querycap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_s_std = vidioc_s_std, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_streamon = vidioc_streamon, + .vidioc_streamoff = vidioc_streamoff, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidioc_cgmbuf, +#endif + .tvnorms = S2255_NORMS, + .current_norm = V4L2_STD_NTSC_M, +}; + +static int s2255_probe_v4l(struct s2255_dev *dev) +{ + int ret; + int i; + int cur_nr = video_nr; + + /* initialize all video 4 linux */ + list_add_tail(&dev->s2255_devlist, &s2255_devlist); + /* register 4 video devices */ + for (i = 0; i < MAX_CHANNELS; i++) { + INIT_LIST_HEAD(&dev->vidq[i].active); + dev->vidq[i].dev = dev; + dev->vidq[i].channel = i; + dev->vidq[i].kthread = NULL; + /* register 4 video devices */ + dev->vdev[i] = video_device_alloc(); + memcpy(dev->vdev[i], &template, sizeof(struct video_device)); + dev->vdev[i]->dev = &dev->interface->dev; + if (video_nr == -1) + ret = video_register_device(dev->vdev[i], + VFL_TYPE_GRABBER, + video_nr); + else + ret = video_register_device(dev->vdev[i], + VFL_TYPE_GRABBER, + cur_nr + i); + dev->vdev[i]->priv = dev; + + if (ret != 0) { + dev_err(&dev->udev->dev, + "failed to register video device!\n"); + return ret; + } + } + printk(KERN_INFO "Sensoray 2255 V4L driver\n"); + return ret; +} + +static void s2255_exit_v4l(struct s2255_dev *dev) +{ + struct list_head *list; + int i; + /* unregister the video devices */ + while (!list_empty(&s2255_devlist)) { + list = s2255_devlist.next; + list_del(list); + } + for (i = 0; i < MAX_CHANNELS; i++) { + if (-1 != dev->vdev[i]->minor) + video_unregister_device(dev->vdev[i]); + else + video_device_release(dev->vdev[i]); + } +} + +/* this function moves the usb stream read pipe data + * into the system buffers. + * returns 0 on success, EAGAIN if more data to process( call this + * function again). + * + * Received frame structure: + * bytes 0-3: marker : 0x2255DA4AL (FRAME_MARKER) + * bytes 4-7: channel: 0-3 + * bytes 8-11: payload size: size of the frame + * bytes 12-payloadsize+12: frame data + */ +static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info) +{ + static int dbgsync; /* = 0; */ + char *pdest; + u32 offset = 0; + int bsync = 0; + int btrunc = 0; + char *psrc; + unsigned long copy_size; + unsigned long size; + s32 idx = -1; + struct s2255_framei *frm; + unsigned char *pdata; + unsigned long cur_size; + int bsearch = 0; + struct s2255_bufferi *buf; + dprintk(100, "buffer to user\n"); + + idx = dev->cur_frame[dev->cc]; + buf = &dev->buffer[dev->cc]; + frm = &buf->frame[idx]; + + if (frm->ulState == 0) { + frm->ulState = 1; + frm->cur_size = 0; + bsearch = 1; + } else if (frm->ulState == 2) { + /* system frame was not freed */ + dprintk(2, "sys frame not free. overrun ringbuf\n"); + bsearch = 1; + frm->ulState = 1; + frm->cur_size = 0; + } + + if (bsearch) { + if (*(s32 *) pipe_info->transfer_buffer != FRAME_MARKER) { + u32 jj; + if (dbgsync == 0) { + dprintk(3, "not synched, discarding all packets" + "until marker\n"); + + dbgsync++; + } + pdata = (unsigned char *)pipe_info->transfer_buffer; + for (jj = 0; jj < (pipe_info->cur_transfer_size - 12); + jj++) { + if (*(s32 *) pdata == FRAME_MARKER) { + int cc; + dprintk(3, + "found frame marker at offset:" + " %d [%x %x]\n", jj, pdata[0], + pdata[1]); + offset = jj; + bsync = 1; + cc = *(u32 *) (pdata + sizeof(u32)); + if (cc >= MAX_CHANNELS) { + printk(KERN_ERR + "bad channel\n"); + return -EINVAL; + } + /* reverse it */ + dev->cc = G_chnmap[cc]; + break; + } + pdata++; + } + if (bsync == 0) + return -EINVAL; + } else { + u32 *pword; + u32 payload; + int cc; + dbgsync = 0; + bsync = 1; + pword = (u32 *) pipe_info->transfer_buffer; + cc = pword[1]; + + if (cc >= MAX_CHANNELS) { + printk("invalid channel found. " + "throwing out data!\n"); + return -EINVAL; + } + dev->cc = G_chnmap[cc]; + payload = pword[2]; + if (payload != dev->req_image_size[dev->cc]) { + dprintk(1, "[%d][%d]unexpected payload: %d" + "required: %lu \n", cc, dev->cc, + payload, dev->req_image_size[dev->cc]); + dev->bad_payload[dev->cc]++; + /* discard the bad frame */ + return -EINVAL; + } + + } + } + /* search done. now find out if should be acquiring + on this channel */ + if (!dev->b_acquire[dev->cc]) { + frm->ulState = 0; + return -EINVAL; + } + + idx = dev->cur_frame[dev->cc]; + frm = &dev->buffer[dev->cc].frame[idx]; + + if (frm->ulState == 0) { + frm->ulState = 1; + frm->cur_size = 0; + } else if (frm->ulState == 2) { + /* system frame ring buffer overrun */ + dprintk(2, "sys frame overrun. overwriting frame %d %d\n", + dev->cc, idx); + frm->ulState = 1; + frm->cur_size = 0; + } + + if (bsync) { + /* skip the marker 512 bytes (and offset if out of sync) */ + psrc = (u8 *)pipe_info->transfer_buffer + offset + PREFIX_SIZE; + } else { + psrc = (u8 *)pipe_info->transfer_buffer; + } + + if (frm->lpvbits == NULL) { + dprintk(1, "s2255 frame buffer == NULL.%p %p %d %d", + frm, dev, dev->cc, idx); + return -ENOMEM; + } + + pdest = frm->lpvbits + frm->cur_size; + + if (bsync) { + copy_size = + (pipe_info->cur_transfer_size - offset) - PREFIX_SIZE; + if (copy_size > pipe_info->cur_transfer_size) { + printk("invalid copy size, overflow!\n"); + return -ENOMEM; + } + } else { + copy_size = pipe_info->cur_transfer_size; + } + + cur_size = frm->cur_size; + size = dev->req_image_size[dev->cc]; + + if ((copy_size + cur_size) > size) { + copy_size = size - cur_size; + btrunc = 1; + } + + memcpy(pdest, psrc, copy_size); + cur_size += copy_size; + frm->cur_size += copy_size; + dprintk(50, "cur_size size %lu size %lu \n", cur_size, size); + + if (cur_size >= (size - PREFIX_SIZE)) { + u32 cc = dev->cc; + frm->ulState = 2; + dprintk(2, "****************[%d]Buffer[%d]full*************\n", + cc, idx); + dev->last_frame[cc] = dev->cur_frame[cc]; + dev->cur_frame[cc]++; + /* end of system frame ring buffer, start at zero */ + if ((dev->cur_frame[cc] == SYS_FRAMES) || + (dev->cur_frame[cc] == dev->buffer[cc].dwFrames)) + dev->cur_frame[cc] = 0; + + /* signal the semaphore for this channel */ + if (dev->b_acquire[cc]) + s2255_got_frame(dev, cc); + dev->frame_count[cc]++; + } + /* frame was truncated */ + if (btrunc) { + /* return more data to process */ + return EAGAIN; + } + /* done successfully */ + return 0; +} + +static void s2255_read_video_callback(struct s2255_dev *dev, + struct s2255_pipeinfo *pipe_info) +{ + int res; + dprintk(50, "callback read video \n"); + + if (dev->cc >= MAX_CHANNELS) { + dev->cc = 0; + dev_err(&dev->udev->dev, "invalid channel\n"); + return; + } + /* otherwise copy to the system buffers */ + res = save_frame(dev, pipe_info); + if (res == EAGAIN) + save_frame(dev, pipe_info); + + dprintk(50, "callback read video done\n"); + return; +} + +static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request, + u16 Index, u16 Value, void *TransferBuffer, + s32 TransferBufferLength, int bOut) +{ + int r; + if (!bOut) { + r = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + Request, + USB_TYPE_VENDOR | USB_RECIP_DEVICE | + USB_DIR_IN, + Value, Index, TransferBuffer, + TransferBufferLength, HZ * 5); + } else { + r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE, + Value, Index, TransferBuffer, + TransferBufferLength, HZ * 5); + } + return r; +} + +/* + * retrieve FX2 firmware version. future use. + * @param dev pointer to device extension + * @return -1 for fail, else returns firmware version as an int(16 bits) + */ +static int s2255_get_fx2fw(struct s2255_dev *dev) +{ + int fw; + int ret; + unsigned char transBuffer[64]; + ret = s2255_vendor_req(dev, S2255_VR_FW, 0, 0, transBuffer, 2, + S2255_VR_IN); + if (ret < 0) + dprintk(2, "get fw error: %x\n", ret); + fw = transBuffer[0] + (transBuffer[1] << 8); + dprintk(2, "Get FW %x %x\n", transBuffer[0], transBuffer[1]); + return fw; +} + +/* + * Create the system ring buffer to copy frames into from the + * usb read pipe. + */ +static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn) +{ + unsigned long i; + unsigned long reqsize; + dprintk(1, "create sys buffers\n"); + if (chn >= MAX_CHANNELS) + return -1; + + dev->buffer[chn].dwFrames = SYS_FRAMES; + + /* always allocate maximum size(PAL) for system buffers */ + reqsize = SYS_FRAMES_MAXSIZE; + + if (reqsize > SYS_FRAMES_MAXSIZE) + reqsize = SYS_FRAMES_MAXSIZE; + + for (i = 0; i < SYS_FRAMES; i++) { + /* allocate the frames */ + dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize); + + dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n", + &dev->buffer[chn].frame[i], chn, i, + dev->buffer[chn].frame[i].lpvbits); + dev->buffer[chn].frame[i].size = reqsize; + if (dev->buffer[chn].frame[i].lpvbits == NULL) { + printk(KERN_INFO "out of memory. using less frames\n"); + dev->buffer[chn].dwFrames = i; + break; + } + } + + /* make sure internal states are set */ + for (i = 0; i < SYS_FRAMES; i++) { + dev->buffer[chn].frame[i].ulState = 0; + dev->buffer[chn].frame[i].cur_size = 0; + } + + dev->cur_frame[chn] = 0; + dev->last_frame[chn] = -1; + return 0; +} + +static int s2255_release_sys_buffers(struct s2255_dev *dev, + unsigned long channel) +{ + unsigned long i; + dprintk(1, "release sys buffers\n"); + for (i = 0; i < SYS_FRAMES; i++) { + if (dev->buffer[channel].frame[i].lpvbits) { + dprintk(1, "vfree %p\n", + dev->buffer[channel].frame[i].lpvbits); + vfree(dev->buffer[channel].frame[i].lpvbits); + } + dev->buffer[channel].frame[i].lpvbits = NULL; + } + return 0; +} + +static int s2255_board_init(struct s2255_dev *dev) +{ + int j; + struct s2255_mode mode_def = DEF_MODEI_NTSC_CONT; + int fw_ver; + dprintk(4, "board init: %p", dev); + + for (j = 0; j < MAX_PIPE_BUFFERS; j++) { + struct s2255_pipeinfo *pipe = &dev->pipes[j]; + + memset(pipe, 0, sizeof(*pipe)); + pipe->dev = dev; + pipe->cur_transfer_size = DEFAULT_PIPE_USBBLOCK; + pipe->max_transfer_size = MAX_PIPE_USBBLOCK; + + if (pipe->cur_transfer_size > pipe->max_transfer_size) + pipe->cur_transfer_size = pipe->max_transfer_size; + pipe->transfer_buffer = kzalloc(pipe->max_transfer_size, + GFP_KERNEL); + if (pipe->transfer_buffer == NULL) { + dprintk(1, "out of memory!\n"); + return -ENOMEM; + } + + } + + /* query the firmware */ + fw_ver = s2255_get_fx2fw(dev); + + printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver); + if (fw_ver < CUR_USB_FWVER) + err("usb firmware not up to date %d\n", fw_ver); + + for (j = 0; j < MAX_CHANNELS; j++) { + dev->b_acquire[j] = 0; + dev->mode[j] = mode_def; + dev->cur_fmt[j] = &formats[0]; + dev->mode[j].restart = 1; + dev->req_image_size[j] = get_transfer_size(&mode_def); + dev->frame_count[j] = 0; + /* create the system buffers */ + s2255_create_sys_buffers(dev, j); + } + /* start read pipe */ + s2255_start_readpipe(dev); + + dprintk(1, "S2255: board initialized\n"); + return 0; +} + +static int s2255_board_shutdown(struct s2255_dev *dev) +{ + u32 i; + + dprintk(1, "S2255: board shutdown: %p", dev); + + for (i = 0; i < MAX_CHANNELS; i++) { + if (dev->b_acquire[i]) + s2255_stop_acquire(dev, i); + } + + s2255_stop_readpipe(dev); + + for (i = 0; i < MAX_CHANNELS; i++) + s2255_release_sys_buffers(dev, i); + + /* release transfer buffers */ + for (i = 0; i < MAX_PIPE_BUFFERS; i++) { + struct s2255_pipeinfo *pipe = &dev->pipes[i]; + kfree(pipe->transfer_buffer); + } + return 0; +} + +static void read_pipe_completion(struct urb *purb) +{ + struct s2255_pipeinfo *pipe_info; + struct s2255_dev *dev; + int status; + int pipe; + + pipe_info = purb->context; + dprintk(100, "read pipe completion %p, status %d\n", purb, + purb->status); + if (pipe_info == NULL) { + err("no context !"); + return; + } + + dev = pipe_info->dev; + if (dev == NULL) { + err("no context !"); + return; + } + status = purb->status; + if (status != 0) { + dprintk(2, "read_pipe_completion: err\n"); + return; + } + + if (pipe_info->state == 0) { + dprintk(2, "exiting USB pipe"); + return; + } + + s2255_read_video_callback(dev, pipe_info); + + pipe_info->err_count = 0; + pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); + /* reuse urb */ + usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, + pipe, + pipe_info->transfer_buffer, + pipe_info->cur_transfer_size, + read_pipe_completion, pipe_info); + + if (pipe_info->state != 0) { + if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) { + dev_err(&dev->udev->dev, "error submitting urb\n"); + usb_free_urb(pipe_info->stream_urb); + } + } else { + dprintk(2, "read pipe complete state 0\n"); + } + return; +} + +static int s2255_start_readpipe(struct s2255_dev *dev) +{ + int pipe; + int retval; + int i; + struct s2255_pipeinfo *pipe_info = dev->pipes; + pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint); + dprintk(2, "start pipe IN %d\n", dev->read_endpoint); + + for (i = 0; i < MAX_PIPE_BUFFERS; i++) { + pipe_info->state = 1; + pipe_info->buf_index = (u32) i; + pipe_info->priority_set = 0; + pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!pipe_info->stream_urb) { + dev_err(&dev->udev->dev, + "ReadStream: Unable to alloc URB"); + return -ENOMEM; + } + /* transfer buffer allocated in board_init */ + usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev, + pipe, + pipe_info->transfer_buffer, + pipe_info->cur_transfer_size, + read_pipe_completion, pipe_info); + + pipe_info->urb_size = sizeof(pipe_info->stream_urb); + dprintk(4, "submitting URB %p\n", pipe_info->stream_urb); + retval = usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL); + if (retval) { + printk(KERN_ERR "s2255: start read pipe failed\n"); + return retval; + } + } + + return 0; +} + +/* starts acquisition process */ +static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn) +{ + unsigned char *buffer; + int res; + unsigned long chn_rev; + int j; + if (chn >= MAX_CHANNELS) { + dprintk(2, "start acquire failed, bad channel %lu\n", chn); + return -1; + } + + chn_rev = G_chnmap[chn]; + dprintk(1, "S2255: start acquire %lu \n", chn); + + buffer = kzalloc(512, GFP_KERNEL); + if (buffer == NULL) { + dev_err(&dev->udev->dev, "out of mem\n"); + return -ENOMEM; + } + + dev->last_frame[chn] = -1; + dev->bad_payload[chn] = 0; + dev->cur_frame[chn] = 0; + for (j = 0; j < SYS_FRAMES; j++) { + dev->buffer[chn].frame[j].ulState = 0; + dev->buffer[chn].frame[j].cur_size = 0; + } + + /* send the start command */ + *(u32 *) buffer = IN_DATA_TOKEN; + *((u32 *) buffer + 1) = (u32) chn_rev; + *((u32 *) buffer + 2) = (u32) CMD_START; + res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); + if (res != 0) + dev_err(&dev->udev->dev, "CMD_START error\n"); + + dprintk(2, "start acquire exit[%lu] %d \n", chn, res); + kfree(buffer); + return 0; +} + +static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn) +{ + unsigned char *buffer; + int res; + unsigned long chn_rev; + + if (chn >= MAX_CHANNELS) { + dprintk(2, "stop acquire failed, bad channel %lu\n", chn); + return -1; + } + chn_rev = G_chnmap[chn]; + + buffer = kzalloc(512, GFP_KERNEL); + if (buffer == NULL) { + dev_err(&dev->udev->dev, "out of mem\n"); + return -ENOMEM; + } + + /* send the stop command */ + dprintk(4, "stop acquire %lu\n", chn); + *(u32 *) buffer = IN_DATA_TOKEN; + *((u32 *) buffer + 1) = (u32) chn_rev; + *((u32 *) buffer + 2) = CMD_STOP; + res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512); + + if (res != 0) + dev_err(&dev->udev->dev, "CMD_STOP error\n"); + + dprintk(4, "stop acquire: releasing states \n"); + + kfree(buffer); + dev->b_acquire[chn] = 0; + + return 0; +} + +static void s2255_stop_readpipe(struct s2255_dev *dev) +{ + int j; + + if (dev == NULL) { + err("s2255: invalid device"); + return; + } + dprintk(4, "stop read pipe\n"); + for (j = 0; j < MAX_PIPE_BUFFERS; j++) { + struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; + if (pipe_info) { + if (pipe_info->state == 0) + continue; + pipe_info->state = 0; + pipe_info->prev_state = 1; + + } + } + + for (j = 0; j < MAX_PIPE_BUFFERS; j++) { + struct s2255_pipeinfo *pipe_info = &dev->pipes[j]; + if (pipe_info->stream_urb) { + /* cancel urb */ + usb_kill_urb(pipe_info->stream_urb); + usb_free_urb(pipe_info->stream_urb); + pipe_info->stream_urb = NULL; + } + } + dprintk(2, "s2255 stop read pipe: %d\n", j); + return; +} + +static void s2255_fwload_start(struct s2255_dev *dev) +{ + dev->fw_data->fw_size = dev->fw_data->fw->size; + atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED); + memcpy(dev->fw_data->pfw_data, + dev->fw_data->fw->data, CHUNK_SIZE); + dev->fw_data->fw_loaded = CHUNK_SIZE; + usb_fill_bulk_urb(dev->fw_data->fw_urb, dev->udev, + usb_sndbulkpipe(dev->udev, 2), + dev->fw_data->pfw_data, + CHUNK_SIZE, s2255_fwchunk_complete, + dev->fw_data); + mod_timer(&dev->timer, jiffies + HZ); +} + +/* standard usb probe function */ +static int s2255_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct s2255_dev *dev = NULL; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int i; + int retval = -ENOMEM; + + dprintk(2, "s2255: probe\n"); + + /* allocate memory for our device state and initialize it to zero */ + dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); + if (dev == NULL) { + err("s2255: out of memory"); + goto error; + } + + dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); + if (!dev->fw_data) + goto error; + + mutex_init(&dev->lock); + mutex_init(&dev->open_lock); + + /* grab usb_device and save it */ + dev->udev = usb_get_dev(interface_to_usbdev(interface)); + if (dev->udev == NULL) { + dev_err(&interface->dev, "null usb device\n"); + retval = -ENODEV; + goto error; + } + kref_init(&dev->kref); + dprintk(1, "dev: %p, kref: %p udev %p interface %p\n", dev, &dev->kref, + dev->udev, interface); + dev->interface = interface; + /* set up the endpoint information */ + iface_desc = interface->cur_altsetting; + dprintk(1, "num endpoints %d\n", iface_desc->desc.bNumEndpoints); + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + if (!dev->read_endpoint && usb_endpoint_is_bulk_in(endpoint)) { + /* we found the bulk in endpoint */ + dev->read_endpoint = endpoint->bEndpointAddress; + } + } + + if (!dev->read_endpoint) { + dev_err(&interface->dev, "Could not find bulk-in endpoint"); + goto error; + } + + /* set intfdata */ + usb_set_intfdata(interface, dev); + + dprintk(100, "after intfdata %p\n", dev); + + init_timer(&dev->timer); + dev->timer.function = s2255_timer; + dev->timer.data = (unsigned long)dev->fw_data; + + init_waitqueue_head(&dev->fw_data->wait_fw); + + + dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL); + + if (!dev->fw_data->fw_urb) { + dev_err(&interface->dev, "out of memory!\n"); + goto error; + } + dev->fw_data->pfw_data = kzalloc(CHUNK_SIZE, GFP_KERNEL); + if (!dev->fw_data->pfw_data) { + dev_err(&interface->dev, "out of memory!\n"); + goto error; + } + /* load the first chunk */ + if (request_firmware(&dev->fw_data->fw, + FIRMWARE_FILE_NAME, &dev->udev->dev)) { + printk(KERN_ERR "sensoray 2255 failed to get firmware\n"); + goto error; + } + + /* loads v4l specific */ + s2255_probe_v4l(dev); + /* load 2255 board specific */ + s2255_board_init(dev); + + dprintk(4, "before probe done %p\n", dev); + spin_lock_init(&dev->slock); + + s2255_fwload_start(dev); + dev_info(&interface->dev, "Sensoray 2255 detected\n"); + return 0; +error: + return retval; +} + +/* disconnect routine. when board is removed physically or with rmmod */ +static void s2255_disconnect(struct usb_interface *interface) +{ + struct s2255_dev *dev = NULL; + dprintk(1, "s2255: disconnect interface %p\n", interface); + dev = usb_get_intfdata(interface); + if (dev) { + kref_put(&dev->kref, s2255_destroy); + dprintk(1, "s2255drv: disconnect\n"); + dev_info(&interface->dev, "s2255usb now disconnected\n"); + } + usb_set_intfdata(interface, NULL); +} + +static struct usb_driver s2255_driver = { + .name = "s2255", + .probe = s2255_probe, + .disconnect = s2255_disconnect, + .id_table = s2255_table, +}; + +static int __init usb_s2255_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&s2255_driver); + + if (result) + err("usb_register failed. Error number %d", result); + + dprintk(2, "s2255_init: done\n"); + return result; +} + +static void __exit usb_s2255_exit(void) +{ + usb_deregister(&s2255_driver); +} + +module_init(usb_s2255_init); +module_exit(usb_s2255_exit); + +MODULE_DESCRIPTION("Sensoray 2255 Video for Linux driver"); +MODULE_AUTHOR("Dean Anderson (Sensoray Company Inc.)"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From f51b10ef6520f2bd725dc333e771eabd55d6c04f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:20:49 -0300 Subject: V4L/DVB (8126): net endianness fix According to RFC 4326 (4.1) D-bit is MSB in net-endian 16bit. dvb_net.c did /* Set D-bit for CRC32 verification, * if it was set originally. */ ulen |= 0x0080; which works of little-endian (htons(1<<15) is 0x0080 there), but breaks on big-endian. Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index c2334aef4143..ff7161094023 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -606,7 +606,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) if (priv->ule_dbit) { /* Set D-bit for CRC32 verification, * if it was set originally. */ - ulen |= 0x0080; + ulen |= htons(0x8000); } ule_crc = iov_crc32(ule_crc, iov, 3); -- cgit v1.2.3 From a36ef6b1e09d06d4f1ac769eee4bd7e6cf3e0fae Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:19:19 -0300 Subject: V4L/DVB (8128): saa7146: ->cpu_addr and friends are little-endian Annotations + stop saa7146_i2c from playing fast and loose with reuse of ->cpu_addr for host-endian. Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_core.c | 4 ++-- drivers/media/common/saa7146_hlp.c | 2 +- drivers/media/common/saa7146_i2c.c | 34 +++++++++++++++++----------------- drivers/media/common/saa7146_video.c | 4 ++-- include/media/saa7146.h | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 89c7660b85d6..d01965e96927 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c @@ -233,7 +233,7 @@ void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt) int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) { - u32 *cpu; + __le32 *cpu; dma_addr_t dma_addr; cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr); @@ -250,7 +250,7 @@ int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt) int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int sglen ) { - u32 *ptr, fill; + __le32 *ptr, fill; int nr_pages = 0; int i,p; diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index 9c905399a233..05bde9ccb770 100644 --- a/drivers/media/common/saa7146_hlp.c +++ b/drivers/media/common/saa7146_hlp.c @@ -338,7 +338,7 @@ static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct sa struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field) { struct saa7146_vv *vv = dev->vv_data; - u32 *clipping = vv->d_clipping.cpu_addr; + __le32 *clipping = vv->d_clipping.cpu_addr; int width = fh->ov.win.w.width; int height = fh->ov.win.w.height; diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index 35b01ec40a51..c11da4d09cd0 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c @@ -24,7 +24,7 @@ static inline u32 saa7146_i2c_status(struct saa7146_dev *dev) sent through the saa7146. have a look at the specifications p. 122 ff to understand this. it returns the number of u32s to send, or -1 in case of an error. */ -static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) +static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, __le32 *op) { int h1, h2; int i, j, addr; @@ -47,7 +47,7 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) } /* be careful: clear out the i2c-mem first */ - memset(op,0,sizeof(u32)*mem); + memset(op,0,sizeof(__le32)*mem); /* loop through all messages */ for(i = 0; i < num; i++) { @@ -57,16 +57,16 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) so we have to perform a translation */ addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0); h1 = op_count/3; h2 = op_count%3; - op[h1] |= ( (u8)addr << ((3-h2)*8)); - op[h1] |= (SAA7146_I2C_START << ((3-h2)*2)); + op[h1] |= cpu_to_le32( (u8)addr << ((3-h2)*8)); + op[h1] |= cpu_to_le32(SAA7146_I2C_START << ((3-h2)*2)); op_count++; /* loop through all bytes of message i */ for(j = 0; j < m[i].len; j++) { /* insert the data bytes */ h1 = op_count/3; h2 = op_count%3; - op[h1] |= ( (u32)((u8)m[i].buf[j]) << ((3-h2)*8)); - op[h1] |= ( SAA7146_I2C_CONT << ((3-h2)*2)); + op[h1] |= cpu_to_le32( (u32)((u8)m[i].buf[j]) << ((3-h2)*8)); + op[h1] |= cpu_to_le32( SAA7146_I2C_CONT << ((3-h2)*2)); op_count++; } @@ -75,9 +75,9 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) /* have a look at the last byte inserted: if it was: ...CONT change it to ...STOP */ h1 = (op_count-1)/3; h2 = (op_count-1)%3; - if ( SAA7146_I2C_CONT == (0x3 & (op[h1] >> ((3-h2)*2))) ) { - op[h1] &= ~(0x2 << ((3-h2)*2)); - op[h1] |= (SAA7146_I2C_STOP << ((3-h2)*2)); + if ( SAA7146_I2C_CONT == (0x3 & (le32_to_cpu(op[h1]) >> ((3-h2)*2))) ) { + op[h1] &= ~cpu_to_le32(0x2 << ((3-h2)*2)); + op[h1] |= cpu_to_le32(SAA7146_I2C_STOP << ((3-h2)*2)); } /* return the number of u32s to send */ @@ -88,7 +88,7 @@ static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, u32 *op) which bytes were read through the adapter and write them back to the corresponding i2c-message. but instead, we simply write back all bytes. fixme: this could be improved. */ -static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op) +static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op) { int i, j; int op_count = 0; @@ -101,7 +101,7 @@ static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, u32 *op) /* loop throgh all bytes of message i */ for(j = 0; j < m[i].len; j++) { /* write back all bytes that could have been read */ - m[i].buf[j] = (op[op_count/3] >> ((3-(op_count%3))*8)); + m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8)); op_count++; } } @@ -174,7 +174,7 @@ static int saa7146_i2c_reset(struct saa7146_dev *dev) /* this functions writes out the data-byte 'dword' to the i2c-device. it returns 0 if ok, -1 if the transfer failed, -2 if the transfer failed badly (e.g. address error) */ -static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_delay) +static int saa7146_i2c_writeout(struct saa7146_dev *dev, __le32 *dword, int short_delay) { u32 status = 0, mc2 = 0; int trial = 0; @@ -186,7 +186,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, *dword); + saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword)); dev->i2c_op = 1; SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17); @@ -209,7 +209,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d status = saa7146_read(dev, I2C_STATUS); } else { saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate); - saa7146_write(dev, I2C_TRANSFER, *dword); + saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword)); saa7146_write(dev, MC2, (MASK_00 | MASK_16)); /* do not poll for i2c-status before upload is complete */ @@ -282,7 +282,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d } /* read back data, just in case we were reading ... */ - *dword = saa7146_read(dev, I2C_TRANSFER); + *dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER)); DEB_I2C(("after: 0x%08x\n",*dword)); return 0; @@ -291,7 +291,7 @@ static int saa7146_i2c_writeout(struct saa7146_dev *dev, u32* dword, int short_d static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries) { int i = 0, count = 0; - u32* buffer = dev->d_i2c.cpu_addr; + __le32 *buffer = dev->d_i2c.cpu_addr; int err = 0; int address_err = 0; int short_delay = 0; @@ -376,7 +376,7 @@ out: /* another bug in revision 0: the i2c-registers get uploaded randomly by other uploads, so we better clear them out before continueing */ if( 0 == dev->revision ) { - u32 zero = 0; + __le32 zero = 0; saa7146_i2c_reset(dev); if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) { INFO(("revision 0 error. this should never happen.\n")); diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 3cbc6ebbe649..a5e62750eea3 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -605,8 +605,8 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu struct saa7146_pgtable *pt1 = &buf->pt[0]; struct saa7146_pgtable *pt2 = &buf->pt[1]; struct saa7146_pgtable *pt3 = &buf->pt[2]; - u32 *ptr1, *ptr2, *ptr3; - u32 fill; + __le32 *ptr1, *ptr2, *ptr3; + __le32 fill; int size = buf->fmt->width*buf->fmt->height; int i,p,m1,m2,m3,o1,o2; diff --git a/include/media/saa7146.h b/include/media/saa7146.h index 88b2b5a619aa..2f68f4cd0037 100644 --- a/include/media/saa7146.h +++ b/include/media/saa7146.h @@ -53,7 +53,7 @@ struct saa7146_vv; /* saa7146 page table */ struct saa7146_pgtable { unsigned int size; - u32 *cpu; + __le32 *cpu; dma_addr_t dma; /* used for offsets for u,v planes for planar capture modes */ unsigned long offset; @@ -101,7 +101,7 @@ struct saa7146_extension struct saa7146_dma { dma_addr_t dma_handle; - u32 *cpu_addr; + __le32 *cpu_addr; }; struct saa7146_dev -- cgit v1.2.3 From 67778b322780200ac14e95c8089a0bd679a467d9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:20:39 -0300 Subject: V4L/DVB (8129): pluto_set_dma_addr() fix bogus cpu_to_le32() when passing dma address to hardware via writel() - writel() converts itself. Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/pluto2/pluto2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 960ed5763ae1..1360403b88b6 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -234,7 +234,7 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable) static void pluto_set_dma_addr(struct pluto *pluto) { - pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr)); + pluto_writereg(pluto, REG_PCAR, pluto->dma_addr); } static int __devinit pluto_dma_map(struct pluto *pluto) -- cgit v1.2.3 From b0ba0e3ab6f452321771325b7b5578f9a804f69e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:20:29 -0300 Subject: V4L/DVB (8130): split dvb_ringbuffer dual-use functions split the suckers into kernel-memory and user-memory versions, annotate both properly. Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dmxdev.c | 2 +- drivers/media/dvb/dvb-core/dvb_ca_en50221.c | 8 +-- drivers/media/dvb/dvb-core/dvb_ringbuffer.c | 78 ++++++++++++++++++++--------- drivers/media/dvb/dvb-core/dvb_ringbuffer.h | 12 +++-- drivers/media/dvb/ttpci/av7110.c | 2 +- drivers/media/dvb/ttpci/av7110_av.c | 2 +- drivers/media/dvb/ttpci/av7110_ca.c | 2 +- 7 files changed, 69 insertions(+), 37 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index df5bef6a2517..1cf9fcb6f514 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, if (avail > todo) avail = todo; - ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1); + ret = dvb_ringbuffer_read_user(src, buf, avail); if (ret < 0) break; diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 588fbe105c27..8e5dd7b1f034 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1357,7 +1357,7 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); while (idx != -1) { - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); + dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { @@ -1438,7 +1438,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, goto exit; } - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); + dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); if (connection_id == -1) connection_id = hdr[0]; if (hdr[0] == connection_id) { @@ -1449,8 +1449,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, fraglen -= 2; } - if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, - (u8 *)buf + pktlen, fraglen, 1)) < 0) { + if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2, + buf + pktlen, fraglen)) < 0) { goto exit; } pktlen += fraglen; diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 872985b7912d..584bbd194dc8 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) wake_up(&rbuf->queue); } - - -ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem) +ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len) { size_t todo = len; size_t split; split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; if (split > 0) { - if (!usermem) - memcpy(buf, rbuf->data+rbuf->pread, split); - else - if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) + return -EFAULT; buf += split; todo -= split; rbuf->pread = 0; } - if (!usermem) - memcpy(buf, rbuf->data+rbuf->pread, todo); - else - if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) + return -EFAULT; rbuf->pread = (rbuf->pread + todo) % rbuf->size; return len; } +void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len) +{ + size_t todo = len; + size_t split; + + split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; + if (split > 0) { + memcpy(buf, rbuf->data+rbuf->pread, split); + buf += split; + todo -= split; + rbuf->pread = 0; + } + memcpy(buf, rbuf->data+rbuf->pread, todo); + + rbuf->pread = (rbuf->pread + todo) % rbuf->size; +} ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) @@ -171,8 +179,8 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le return status; } -ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len, int usermem) +ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, + int offset, u8 __user *buf, size_t len) { size_t todo; size_t split; @@ -187,21 +195,40 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, todo = len; split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; if (split > 0) { - if (!usermem) - memcpy(buf, rbuf->data+idx, split); - else - if (copy_to_user(buf, rbuf->data+idx, split)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+idx, split)) + return -EFAULT; buf += split; todo -= split; idx = 0; } - if (!usermem) - memcpy(buf, rbuf->data+idx, todo); - else - if (copy_to_user(buf, rbuf->data+idx, todo)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+idx, todo)) + return -EFAULT; + + return len; +} +ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, + int offset, u8* buf, size_t len) +{ + size_t todo; + size_t split; + size_t pktlen; + + pktlen = rbuf->data[idx] << 8; + pktlen |= rbuf->data[(idx + 1) % rbuf->size]; + if (offset > pktlen) return -EINVAL; + if ((offset + len) > pktlen) len = pktlen - offset; + + idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; + todo = len; + split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; + if (split > 0) { + memcpy(buf, rbuf->data+idx, split); + buf += split; + todo -= split; + idx = 0; + } + memcpy(buf, rbuf->data+idx, todo); return len; } @@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty); EXPORT_SYMBOL(dvb_ringbuffer_free); EXPORT_SYMBOL(dvb_ringbuffer_avail); EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); +EXPORT_SYMBOL(dvb_ringbuffer_read_user); EXPORT_SYMBOL(dvb_ringbuffer_read); EXPORT_SYMBOL(dvb_ringbuffer_write); diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 890826262966..41f04dae69b6 100644 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -61,7 +61,7 @@ struct dvb_ringbuffer { ** *** read min. 1000, max. bytes *** ** avail = dvb_ringbuffer_avail(rbuf); ** if (avail >= 1000) -** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0); +** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); ** else ** ... ** @@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); ** specifies whether resides in user space ** returns number of bytes transferred or -EFAULT */ -extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, - size_t len, int usermem); +extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, + u8 __user *buf, size_t len); +extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, + u8 *buf, size_t len); /* write routines & macros */ @@ -157,8 +159,10 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, * Set to 1 if is in userspace. * returns Number of bytes read, or -EFAULT. */ +extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, + int offset, u8 __user *buf, size_t len); extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len, int usermem); + int offset, u8 *buf, size_t len); /** * Dispose of a packet in the ring buffer. diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 6d7b9f6a6c75..dfe03cb42671 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -587,7 +587,7 @@ static void gpioirq(unsigned long data) } DVB_RINGBUFFER_SKIP(cibuf, 2); - dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0); + dvb_ringbuffer_read(cibuf, av7110->debi_virt, len); iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index ec55a968f204..184647ad1c7c 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c @@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) return -1; } - dvb_ringbuffer_read(buf, dest, (size_t) blen, 0); + dvb_ringbuffer_read(buf, dest, (size_t) blen); dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", (unsigned long) buf->pread, (unsigned long) buf->pwrite); diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index c58e3fc509ed..261135ded481 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c @@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, return -EINVAL; DVB_RINGBUFFER_SKIP(cibuf, 2); - return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1); + return dvb_ringbuffer_read_user(cibuf, buf, len); } static int dvb_ca_open(struct inode *inode, struct file *file) -- cgit v1.2.3 From 947a080037c6ae47cfe5072eadbd189e3da27ecd Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:20:19 -0300 Subject: V4L/DVB (8131): dmx_write: memcpy from user-supplied pointer ... copy to kernel memory first Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/demux.h | 2 +- drivers/media/dvb/dvb-core/dvb_demux.c | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h index b0d347daae47..eb91fd808c16 100644 --- a/drivers/media/dvb/dvb-core/demux.h +++ b/drivers/media/dvb/dvb-core/demux.h @@ -247,7 +247,7 @@ struct dmx_demux { void* priv; /* Pointer to private data of the API client */ int (*open) (struct dmx_demux* demux); int (*close) (struct dmx_demux* demux); - int (*write) (struct dmx_demux* demux, const char* buf, size_t count); + int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count); int (*allocate_ts_feed) (struct dmx_demux* demux, struct dmx_ts_feed** feed, dmx_ts_cb callback); diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 934e15fffc56..e2eca0b1fe7c 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/drivers/media/dvb/dvb-core/dvb_demux.c @@ -1056,16 +1056,27 @@ static int dvbdmx_close(struct dmx_demux *demux) return 0; } -static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) +static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; + void *p; if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + p = kmalloc(count, GFP_USER); + if (!p) + return -ENOMEM; + if (copy_from_user(p, buf, count)) { + kfree(p); + return -EFAULT; + } + if (mutex_lock_interruptible(&dvbdemux->mutex)) { + kfree(p); return -ERESTARTSYS; - dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count); + } + dvb_dmx_swfilter(dvbdemux, p, count); + kfree(p); mutex_unlock(&dvbdemux->mutex); if (signal_pending(current)) -- cgit v1.2.3 From 3aa7110e1c415c38c42ef77be0ef2c7a888b9e16 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:20:09 -0300 Subject: V4L/DVB (8132): bt8xx endianness annotations and fixes Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/bt8xx/bt878.h | 2 +- drivers/media/video/bt8xx/bttv-driver.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index 375fd2892a11..d19b59299d78 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h @@ -128,7 +128,7 @@ struct bt878 { dma_addr_t buf_dma; u32 risc_size; - u32 *risc_cpu; + __le32 *risc_cpu; dma_addr_t risc_dma; u32 risc_pos; diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 06c40c91a6f7..0ea559a7fe59 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3705,7 +3705,7 @@ static void bttv_risc_disasm(struct bttv *btv, for (i = 0; i < (risc->size >> 2); i += n) { printk("%s: 0x%lx: ", btv->c.name, (unsigned long)(risc->dma + (i<<2))); - n = bttv_risc_decode(risc->cpu[i]); + n = bttv_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n", btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)), @@ -3774,8 +3774,8 @@ static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc) printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n", btv->c.nr, (unsigned long)btv->main.dma, - (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1], - (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1], + (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]), + (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]), (unsigned long)rc); if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) { -- cgit v1.2.3 From 86ecc02755ea2d00925b344272b49b26d610bbe2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:19:59 -0300 Subject: V4L/DVB (8133): cx23885 endianness fixes Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index c4cc2f3b8876..d17343ea0d33 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -291,9 +291,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev, lines = 6; BUG_ON(lines < 2); - cx_write(8 + 0, cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC) ); - cx_write(8 + 4, cpu_to_le32(8) ); - cx_write(8 + 8, cpu_to_le32(0) ); + cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); + cx_write(8 + 4, 8); + cx_write(8 + 8, 0); /* write CDT */ for (i = 0; i < lines; i++) { @@ -408,11 +408,11 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port, dev->name, risc->cpu, (unsigned long)risc->dma); for (i = 0; i < (risc->size >> 2); i += n) { printk("%s: %04d: ", dev->name, i); - n = cx23885_risc_decode(risc->cpu[i]); + n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) printk("%s: %04d: 0x%08x [ arg #%d ]\n", dev->name, i + j, risc->cpu[i + j], j); - if (risc->cpu[i] == RISC_JUMP) + if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) break; } } -- cgit v1.2.3 From 9c169df8d6877c618587bf40498f2ef378c97eb8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:19:49 -0300 Subject: V4L/DVB (8134): zoran annotations and fixes Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_card.c | 2 +- drivers/media/video/zoran_driver.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 24afe81a59de..5ce1ec7338bf 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -1138,7 +1138,7 @@ zr36057_init (struct zoran *zr) goto exit_free; } for (j = 0; j < BUZ_NUM_STAT_COM; j++) { - zr->stat_com[j] = 1; /* mark as unavailable to zr36057 */ + zr->stat_com[j] = cpu_to_le32(1); /* mark as unavailable to zr36057 */ } /* diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 8764c352061d..c0675921fe20 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -2794,7 +2794,7 @@ zoran_do_ioctl (struct inode *inode, { struct v4l2_format *fmt = arg; int i, res = 0; - __u32 printformat; + __le32 printformat; dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ", ZR_DEVNAME(zr), fmt->type); @@ -3039,7 +3039,7 @@ zoran_do_ioctl (struct inode *inode, { int i, res = 0; struct v4l2_framebuffer *fb = arg; - __u32 printformat = __cpu_to_le32(fb->fmt.pixelformat); + __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat); dprintk(3, KERN_DEBUG -- cgit v1.2.3 From 153755a774578dcf921f8145e786ce25f72368d2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:19:39 -0300 Subject: V4L/DVB (8135): WRITE_RPS1() converts to le32 itself ... but two ancient drivers had not noticed. Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/av7110.c | 40 +++++++++++++++---------------- drivers/media/dvb/ttpci/budget-patch.c | 44 +++++++++++++++++----------------- 2 files changed, 42 insertions(+), 42 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index dfe03cb42671..865c4596b7b7 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2402,18 +2402,18 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, saa7146_write(dev, MC1, MASK_29); /* RPS1 timeout disable */ saa7146_write(dev, RPS_TOV1, 0); - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B)); - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); + WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); #if RPS_IRQ /* issue RPS1 interrupt to increment counter */ - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif - WRITE_RPS1(cpu_to_le32(CMD_STOP)); + WRITE_RPS1(CMD_STOP); /* Jump to begin of RPS program as safety measure (p37) */ - WRITE_RPS1(cpu_to_le32(CMD_JUMP)); - WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); + WRITE_RPS1(CMD_JUMP); + WRITE_RPS1(dev->d_rps1.dma_handle); #if RPS_IRQ /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) @@ -2526,28 +2526,28 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, count = 0; /* Wait Source Line Counter Threshold (p36) */ - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); + WRITE_RPS1(CMD_PAUSE | EVT_HS); /* Set GPIO3=1 (p42) */ - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); #if RPS_IRQ /* issue RPS1 interrupt */ - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif /* Wait reset Source Line Counter Threshold (p36) */ - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); + WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); /* Set GPIO3=0 (p42) */ - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); #if RPS_IRQ /* issue RPS1 interrupt */ - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif /* Jump to begin of RPS program (p37) */ - WRITE_RPS1(cpu_to_le32(CMD_JUMP)); - WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); + WRITE_RPS1(CMD_JUMP); + WRITE_RPS1(dev->d_rps1.dma_handle); /* Fix VSYNC level */ saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 9a155396d6ac..39bd0a20f53a 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c @@ -431,22 +431,22 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte // in budget patch GPIO3 is connected to VSYNC_B count = 0; #if 0 - WRITE_RPS1(cpu_to_le32(CMD_UPLOAD | - MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 )); + WRITE_RPS1(CMD_UPLOAD | + MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ); #endif - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B)); - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); + WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); #if RPS_IRQ // issue RPS1 interrupt to increment counter - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); // at least a NOP is neede between two interrupts - WRITE_RPS1(cpu_to_le32(CMD_NOP)); + WRITE_RPS1(CMD_NOP); // interrupt again - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif - WRITE_RPS1(cpu_to_le32(CMD_STOP)); + WRITE_RPS1(CMD_STOP); #if RPS_IRQ // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) @@ -558,28 +558,28 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte // Wait Source Line Counter Threshold (p36) - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); + WRITE_RPS1(CMD_PAUSE | EVT_HS); // Set GPIO3=1 (p42) - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); #if RPS_IRQ // issue RPS1 interrupt - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif // Wait reset Source Line Counter Threshold (p36) - WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); + WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); // Set GPIO3=0 (p42) - WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); - WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); - WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); + WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); + WRITE_RPS1(GPIO3_MSK); + WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); #if RPS_IRQ // issue RPS1 interrupt - WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); + WRITE_RPS1(CMD_INTERRUPT); #endif // Jump to begin of RPS program (p37) - WRITE_RPS1(cpu_to_le32(CMD_JUMP)); - WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); + WRITE_RPS1(CMD_JUMP); + WRITE_RPS1(dev->d_rps1.dma_handle); // Fix VSYNC level saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); -- cgit v1.2.3 From 84a9f33614e3cfcc7326629a503d4389c9d84e0f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Jun 2008 14:19:29 -0300 Subject: V4L/DVB (8136): xc2028 unaligned access fixes Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tuner-xc2028.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c index 30eb07b7f9ef..4dd1d2421cc5 100644 --- a/drivers/media/common/tuners/tuner-xc2028.c +++ b/drivers/media/common/tuners/tuner-xc2028.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "tuner-i2c.h" #include "tuner-xc2028.h" #include "tuner-xc2028-types.h" @@ -292,10 +293,10 @@ static int load_all_firmwares(struct dvb_frontend *fe) name[sizeof(name) - 1] = 0; p += sizeof(name) - 1; - priv->firm_version = le16_to_cpu(*(__u16 *) p); + priv->firm_version = get_unaligned_le16(p); p += 2; - n_array = le16_to_cpu(*(__u16 *) p); + n_array = get_unaligned_le16(p); p += 2; tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n", @@ -324,26 +325,26 @@ static int load_all_firmwares(struct dvb_frontend *fe) } /* Checks if there's enough bytes to read */ - if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) { - tuner_err("Firmware header is incomplete!\n"); - goto corrupt; - } + if (endp - p < sizeof(type) + sizeof(id) + sizeof(size)) + goto header; - type = le32_to_cpu(*(__u32 *) p); + type = get_unaligned_le32(p); p += sizeof(type); - id = le64_to_cpu(*(v4l2_std_id *) p); + id = get_unaligned_le64(p); p += sizeof(id); if (type & HAS_IF) { - int_freq = le16_to_cpu(*(__u16 *) p); + int_freq = get_unaligned_le16(p); p += sizeof(int_freq); + if (endp - p < sizeof(size)) + goto header; } - size = le32_to_cpu(*(__u32 *) p); + size = get_unaligned_le32(p); p += sizeof(size); - if ((!size) || (size + p > endp)) { + if (!size || size > endp - p) { tuner_err("Firmware type "); dump_firm_type(type); printk("(%x), id %llx is corrupted " @@ -382,6 +383,8 @@ static int load_all_firmwares(struct dvb_frontend *fe) goto done; +header: + tuner_err("Firmware header is incomplete!\n"); corrupt: rc = -EINVAL; tuner_err("Error: firmware file is corrupted!\n"); -- cgit v1.2.3 From 2d5b5a4733b7e32188baa250fbbc4ae11f5e6f69 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 29 Jun 2008 08:29:00 -0300 Subject: V4L/DVB (8142): ttpci: tda827x.h is at drivers/media/common As reported by Stephen Rothwell : drivers/media/dvb/ttpci/budget-ci.c:50:21: error: tda827x.h: No such file or directory Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index d7483f1a9b3f..3819390b16a5 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +EXTRA_CFLAGS += -Idrivers/media/common/tuners hostprogs-y := fdump -- cgit v1.2.3 From ecfceef742b816a5c8541a7d58fe215c38d4d859 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 29 Jun 2008 08:41:19 -0300 Subject: V4L/DVB (8143): Fix compilation for mt9v022 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/mt9v022.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 1658fe590392..b31ba4e09327 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c @@ -815,7 +815,6 @@ static int mt9v022_remove(struct i2c_client *client) return 0; } - static const struct i2c_device_id mt9v022_id[] = { { "mt9v022", 0 }, { } -- cgit v1.2.3 From c0f4c0adfdb10747045fcc757a3e60ae1e1558f3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 02:06:50 -0300 Subject: V4L/DVB (8146): lgdt330x: add additional FEC control configuration option Allow the following configuration, by passing clock_polarity_flip = 2: Enable FEC automatic reset. Disable spectrum inversion. Enable viterbi resynchronization. Set polarity indicator high. Enable error flag insertion. Thanks to Daniel Gimpelevich, for discovering that this configuration is used on the AVerMedia AVerTVHD Volar. Signed-off-by: Michael Krufky CC: Daniel Gimpelevich Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/lgdt330x.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index f0195c8272f4..056387b41a8f 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c @@ -226,11 +226,16 @@ static int lgdt330x_init(struct dvb_frontend* fe) 0x4c, 0x14 }; - static u8 flip_lgdt3303_init_data[] = { + static u8 flip_1_lgdt3303_init_data[] = { 0x4c, 0x14, 0x87, 0xf3 }; + static u8 flip_2_lgdt3303_init_data[] = { + 0x4c, 0x14, + 0x87, 0xda + }; + struct lgdt330x_state* state = fe->demodulator_priv; char *chip_name; int err; @@ -243,10 +248,19 @@ static int lgdt330x_init(struct dvb_frontend* fe) break; case LGDT3303: chip_name = "LGDT3303"; - if (state->config->clock_polarity_flip) { - err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data, - sizeof(flip_lgdt3303_init_data)); - } else { + switch (state->config->clock_polarity_flip) { + case 2: + err = i2c_write_demod_bytes(state, + flip_2_lgdt3303_init_data, + sizeof(flip_2_lgdt3303_init_data)); + break; + case 1: + err = i2c_write_demod_bytes(state, + flip_1_lgdt3303_init_data, + sizeof(flip_1_lgdt3303_init_data)); + break; + case 0: + default: err = i2c_write_demod_bytes(state, lgdt3303_init_data, sizeof(lgdt3303_init_data)); } -- cgit v1.2.3 From f5376adacc693155c24e4e7be3777bdd0eeb99f7 Mon Sep 17 00:00:00 2001 From: Daniel Gimpelevich Date: Sat, 28 Jun 2008 05:01:30 -0300 Subject: V4L/DVB (8147): cxusb: add initial support for AVerTVHD Volar Add initial support for this device. The AGC and tracking filter settings for the mxl5003 are known to be wrong, but it generally works. Signed-off-by: Daniel Gimpelevich Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cxusb.c | 146 +++++++++++++++++++++++++++++++- drivers/media/dvb/dvb-usb/cxusb.h | 3 + drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 5 ++ 3 files changed, 150 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 0286156704f2..578afce6884c 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -35,6 +35,7 @@ #include "zl10353.h" #include "tuner-xc2028.h" #include "tuner-simple.h" +#include "mxl5005s.h" /* debug */ static int dvb_usb_cxusb_debug; @@ -43,9 +44,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_ST DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) -#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ - dprintk(dvb_usb_cxusb_debug,0x01,args) +#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args) +#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args) static int cxusb_ctrl_msg(struct dvb_usb_device *d, u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) @@ -202,6 +202,46 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); } +static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + int ret; + if (!onoff) + return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0); + if (d->state == DVB_USB_STATE_INIT && + usb_set_interface(d->udev, 0, 0) < 0) + err("set interface failed"); + do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && + !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && + !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); + if (!ret) { + /* FIXME: We don't know why, but we need to configure the + * lgdt3303 with the register settings below on resume */ + int i; + u8 buf, bufs[] = { + 0x0e, 0x2, 0x00, 0x7f, + 0x0e, 0x2, 0x02, 0xfe, + 0x0e, 0x2, 0x02, 0x01, + 0x0e, 0x2, 0x00, 0x03, + 0x0e, 0x2, 0x0d, 0x40, + 0x0e, 0x2, 0x0e, 0x87, + 0x0e, 0x2, 0x0f, 0x8e, + 0x0e, 0x2, 0x10, 0x01, + 0x0e, 0x2, 0x14, 0xd7, + 0x0e, 0x2, 0x47, 0x88, + }; + msleep(20); + for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) { + ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE, + bufs+i, 4, &buf, 1); + if (ret) + break; + if (buf != 0x8) + return -EREMOTEIO; + } + } + return ret; +} + static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 b = 0; @@ -233,6 +273,16 @@ static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return 0; } +static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + if (onoff) + cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0); + else + cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF, + NULL, 0, NULL, 0); + return 0; +} + static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { struct dvb_usb_rc_key *keymap = d->props.rc_key_map; @@ -423,6 +473,12 @@ static struct lgdt330x_config cxusb_lgdt3303_config = { .demod_chip = LGDT3303, }; +static struct lgdt330x_config cxusb_aver_lgdt3303_config = { + .demod_address = 0x0e, + .demod_chip = LGDT3303, + .clock_polarity_flip = 2, +}; + static struct mt352_config cxusb_dee1601_config = { .demod_address = 0x0f, .demod_init = cxusb_dee1601_demod_init, @@ -453,6 +509,24 @@ static struct mt352_config cxusb_mt352_xc3028_config = { .demod_init = cxusb_mt352_demod_init, }; +/* FIXME: needs tweaking */ +static struct mxl5005s_config aver_a868r_tuner = { + .i2c_address = 0x63, + .if_freq = 6000000UL, + .xtal_freq = CRYSTAL_FREQ_16000000HZ, + .agc_mode = MXL_SINGLE_AGC, + .tracking_filter = MXL_TF_C, + .rssi_enable = MXL_RSSI_ENABLE, + .cap_select = MXL_CAP_SEL_ENABLE, + .div_out = MXL_DIV_OUT_4, + .clock_out = MXL_CLOCK_OUT_DISABLE, + .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, + .top = MXL5005S_TOP_25P2, + .mod_mode = MXL_DIGITAL_MODE, + .if_mode = MXL_ZERO_IF, + .AgcMasterByte = 0x00, +}; + /* Callbacks for DVB USB */ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { @@ -533,6 +607,13 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) return 0; } +static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) +{ + dvb_attach(mxl5005s_attach, adap->fe, + &adap->dev->i2c_adap, &aver_a868r_tuner); + return 0; +} + static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) { u8 b; @@ -562,6 +643,16 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) return -EIO; } +static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) +{ + adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, + &adap->dev->i2c_adap); + if (adap->fe != NULL) + return 0; + + return -EIO; +} + static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) { /* used in both lgz201 and th7579 */ @@ -736,6 +827,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; +static struct dvb_usb_device_properties cxusb_aver_a868r_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -756,7 +848,10 @@ static int cxusb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr) || 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_needsfirmware_properties, - THIS_MODULE, NULL, adapter_nr)) + THIS_MODULE, NULL, adapter_nr) || + 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, + THIS_MODULE, NULL, adapter_nr) || + 0) return 0; return -EINVAL; @@ -779,6 +874,7 @@ static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, + { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); @@ -1182,6 +1278,48 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope } }; +static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + + .usb_ctrl = CYPRESS_FX2, + + .size_of_priv = sizeof(struct cxusb_state), + + .num_adapters = 1, + .adapter = { + { + .streaming_ctrl = cxusb_aver_streaming_ctrl, + .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, + .tuner_attach = cxusb_mxl5003s_tuner_attach, + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 5, + .endpoint = 0x04, + .u = { + .bulk = { + .buffersize = 8192, + } + } + }, + + }, + }, + .power_ctrl = cxusb_aver_power_ctrl, + + .i2c_algo = &cxusb_i2c_algo, + + .generic_bulk_ctrl_endpoint = 0x01, + + .num_device_descs = 1, + .devices = { + { "AVerMedia AVerTVHD Volar (A868R)", + { NULL }, + { &cxusb_table[16], NULL }, + }, + } +}; + static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h index 4768a2c35517..1a51eafd31b9 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ b/drivers/media/dvb/dvb-usb/cxusb.h @@ -20,6 +20,9 @@ #define CMD_STREAMING_ON 0x36 #define CMD_STREAMING_OFF 0x37 +#define CMD_AVER_STREAM_ON 0x18 +#define CMD_AVER_STREAM_OFF 0x19 + #define CMD_GET_IR_CODE 0x47 #define CMD_ANALOG 0x50 diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index e6b43fb3a148..75ec9caa1421 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -137,6 +137,11 @@ #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 +#define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868 +#define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228 +#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 +#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 +#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 #define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a #define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 -- cgit v1.2.3 From e5e4cd8df61e602202f588dd545364dba37b4cc7 Mon Sep 17 00:00:00 2001 From: Tim Farrington Date: Sun, 29 Jun 2008 11:54:08 -0300 Subject: V4L/DVB (8149): Avermedia E506 composite Composite was originally mis-labelled as name_comp1, so it should be simply redone as name_comp, with its now corrected attributes. Signed-off-by: Tim Farrington Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 348c8635f19f..932a93cab3ef 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4200,17 +4200,13 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .tv = 1, }, { - .name = name_comp1, - .vmux = 3, - .amux = LINE2, + .name = name_comp, + .vmux = 0, + .amux = LINE1, }, { .name = name_svideo, .vmux = 8, .amux = LINE1, - }, { - .name = name_comp, - .vmux = 0, - .amux = LINE1, } }, .radio = { .name = name_radio, -- cgit v1.2.3 From 8b53b39d6228cda41b7ddfc9d094a072afca6655 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Jun 2008 21:18:15 -0300 Subject: V4L/DVB (8151): saa7134-empress: fix MPEG control support The MPEG controls could not be enumerated and so could not be read or set through the v4l2-ctl utility or shown in control panels. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa6752hs.c | 102 ++++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-empress.c | 74 +++++++++++++++++-- drivers/media/video/saa7134/saa7134-i2c.c | 2 + drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 174 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index 002e70a33a4f..fc32c3f68af1 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -448,6 +448,104 @@ static int handle_ctrl(struct saa6752hs_mpeg_params *params, return 0; } +static int saa6752hs_qctrl(struct saa6752hs_mpeg_params *params, + struct v4l2_queryctrl *qctrl) +{ + int err; + + switch (qctrl->id) { + case V4L2_CID_MPEG_AUDIO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, + V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + + case V4L2_CID_MPEG_AUDIO_L2_BITRATE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_L2_BITRATE_256K, + V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, + V4L2_MPEG_AUDIO_L2_BITRATE_256K); + + case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, 1, + V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000); + + case V4L2_CID_MPEG_VIDEO_ENCODING: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2, 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2); + + case V4L2_CID_MPEG_VIDEO_ASPECT: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_VIDEO_ASPECT_4x3, + V4L2_MPEG_VIDEO_ASPECT_16x9, 1, + V4L2_MPEG_VIDEO_ASPECT_4x3); + + case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: + err = v4l2_ctrl_query_fill_std(qctrl); + if (err == 0 && + params->vi_bitrate_mode == + V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) + qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; + return err; + + case V4L2_CID_MPEG_STREAM_TYPE: + return v4l2_ctrl_query_fill(qctrl, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS, 1, + V4L2_MPEG_STREAM_TYPE_MPEG2_TS); + + case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: + case V4L2_CID_MPEG_VIDEO_BITRATE: + case V4L2_CID_MPEG_STREAM_PID_PMT: + case V4L2_CID_MPEG_STREAM_PID_AUDIO: + case V4L2_CID_MPEG_STREAM_PID_VIDEO: + case V4L2_CID_MPEG_STREAM_PID_PCR: + return v4l2_ctrl_query_fill_std(qctrl); + + default: + break; + } + return -EINVAL; +} + +static int saa6752hs_qmenu(struct saa6752hs_mpeg_params *params, + struct v4l2_querymenu *qmenu) +{ + static const char *mpeg_audio_l2_bitrate[] = { + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "256 kbps", + "", + "384 kbps", + NULL + }; + struct v4l2_queryctrl qctrl; + int err; + + qctrl.id = qmenu->id; + err = saa6752hs_qctrl(params, &qctrl); + if (err) + return err; + if (qmenu->id == V4L2_CID_MPEG_AUDIO_L2_BITRATE) + return v4l2_ctrl_query_menu(qmenu, &qctrl, + mpeg_audio_l2_bitrate); + return v4l2_ctrl_query_menu(qmenu, &qctrl, + v4l2_ctrl_get_menu(qmenu->id)); +} + static int saa6752hs_init(struct i2c_client* client) { unsigned char buf[9], buf2[4]; @@ -662,6 +760,10 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) } h->params = params; break; + case VIDIOC_QUERYCTRL: + return saa6752hs_qctrl(&h->params, arg); + case VIDIOC_QUERYMENU: + return saa6752hs_qmenu(&h->params, arg); case VIDIOC_G_FMT: { struct v4l2_format *f = arg; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index e11700eb3e5a..2a5ab957542d 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -294,10 +294,20 @@ static int empress_streamoff(struct file *file, void *priv, return videobuf_streamoff(&dev->empress_tsq); } +static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, + cmd, arg); +} + static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { struct saa7134_dev *dev = file->private_data; + int err; /* count == 0 is abused in saa6752hs.c, so that special case is handled here explicitly. */ @@ -307,10 +317,10 @@ static int empress_s_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_S_EXT_CTRLS, ctrls); + err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls); ts_init_encoder(dev); - return 0; + return err; } static int empress_g_ext_ctrls(struct file *file, void *priv, @@ -320,9 +330,62 @@ static int empress_g_ext_ctrls(struct file *file, void *priv, if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG) return -EINVAL; - saa7134_i2c_call_clients(dev, VIDIOC_G_EXT_CTRLS, ctrls); + return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls); +} - return 0; +static int empress_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *c) +{ + static const u32 user_ctrls[] = { + V4L2_CID_USER_CLASS, + V4L2_CID_BRIGHTNESS, + V4L2_CID_CONTRAST, + V4L2_CID_SATURATION, + V4L2_CID_HUE, + V4L2_CID_AUDIO_VOLUME, + V4L2_CID_AUDIO_MUTE, + V4L2_CID_HFLIP, + 0 + }; + + static const u32 mpeg_ctrls[] = { + V4L2_CID_MPEG_CLASS, + V4L2_CID_MPEG_STREAM_TYPE, + V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, + V4L2_CID_MPEG_AUDIO_ENCODING, + V4L2_CID_MPEG_AUDIO_L2_BITRATE, + V4L2_CID_MPEG_VIDEO_ENCODING, + V4L2_CID_MPEG_VIDEO_ASPECT, + V4L2_CID_MPEG_VIDEO_BITRATE_MODE, + V4L2_CID_MPEG_VIDEO_BITRATE, + V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, + 0 + }; + static const u32 *ctrl_classes[] = { + user_ctrls, + mpeg_ctrls, + NULL + }; + struct saa7134_dev *dev = file->private_data; + + c->id = v4l2_ctrl_next(ctrl_classes, c->id); + if (c->id == 0) + return -EINVAL; + if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS) + return v4l2_ctrl_query_fill_std(c); + if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) + return saa7134_queryctrl(file, priv, c); + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c); +} + +static int empress_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *c) +{ + struct saa7134_dev *dev = file->private_data; + + if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG) + return -EINVAL; + return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c); } static const struct file_operations ts_fops = @@ -363,7 +426,8 @@ static struct video_device saa7134_empress_template = .vidioc_g_input = empress_g_input, .vidioc_s_input = empress_s_input, - .vidioc_queryctrl = saa7134_queryctrl, + .vidioc_queryctrl = empress_queryctrl, + .vidioc_querymenu = empress_querymenu, .vidioc_g_ctrl = saa7134_g_ctrl, .vidioc_s_ctrl = saa7134_s_ctrl, diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index d8af3863f2d3..5f713e637683 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -327,6 +327,8 @@ static int attach_inform(struct i2c_client *client) d1printk( "%s i2c attach [addr=0x%x,client=%s]\n", client->driver->driver.name, client->addr, client->name); + if (client->addr == 0x20 && client->driver && client->driver->command) + dev->mpeg_i2c_client = client; /* Am I an i2c remote control? */ diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 0a94be7afc1e..4e491ad389ac 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -553,6 +553,7 @@ struct saa7134_dev { struct saa7134_ts ts; struct saa7134_dmaqueue ts_q; struct saa7134_mpeg_ops *mops; + struct i2c_client *mpeg_i2c_client; /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; -- cgit v1.2.3 From 63eb9546dcb5e9dc39ab88a603dede8fdd18e717 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 12 Apr 2008 09:58:09 -0300 Subject: V4L/DVB (8152): Initial release of gspca with only one driver. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 238 +++++ drivers/media/video/Kconfig | 2 + drivers/media/video/gspca/Kconfig | 13 + drivers/media/video/gspca/Makefile | 4 + drivers/media/video/gspca/gspca.c | 1750 +++++++++++++++++++++++++++++++++++ drivers/media/video/gspca/gspca.h | 178 ++++ drivers/media/video/gspca/jpeg.h | 301 ++++++ drivers/media/video/gspca/stk014.c | 562 +++++++++++ 8 files changed, 3048 insertions(+) create mode 100644 Documentation/video4linux/gspca.txt create mode 100644 drivers/media/video/gspca/Kconfig create mode 100644 drivers/media/video/gspca/Makefile create mode 100644 drivers/media/video/gspca/gspca.c create mode 100644 drivers/media/video/gspca/gspca.h create mode 100644 drivers/media/video/gspca/jpeg.h create mode 100644 drivers/media/video/gspca/stk014.c (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt new file mode 100644 index 000000000000..9c404b56dbb3 --- /dev/null +++ b/Documentation/video4linux/gspca.txt @@ -0,0 +1,238 @@ +Here the list of the known working cameras with gspca. + +The modules are: + gspca_main main driver + gspca_xxxx subdriver module with xxxx as follows + +xxxx vend:prod +---- +conex 0572:0041 Creative Notebook cx11646 +etoms 102c:6151 Qcam Sangha CIF +etoms 102c:6251 Qcam xxxxxx VGA +mars 093a:050f Mars-Semi Pc-Camera +ov519 041e:4052 Creative Live! VISTA IM +ov519 041e:405f Creative Live! VISTA VF0330 +ov519 041e:4060 Creative Live! VISTA VF0350 +ov519 041e:4061 Creative Live! VISTA VF0400 +ov519 041e:4064 Creative Live! VISTA VF0420 +ov519 041e:4068 Creative Live! VISTA VF0470 +ov519 045e:028c Micro$oft xbox cam +ov519 054c:0154 Sonny toy4 +ov519 054c:0155 Sonny toy5 +ov519 05a9:0519 OmniVision +ov519 05a9:4519 OmniVision +ov519 05a9:8519 OmniVision +ov519 05a9:0530 OmniVision +pac207 041e:4028 Creative Webcam Vista Plus +pac207 093a:2460 PAC207 Qtec Webcam 100 +pac207 093a:2463 Philips spc200nc pac207 +pac207 093a:2464 Labtec Webcam 1200 +pac207 093a:2468 PAC207 +pac207 093a:2470 Genius GF112 +pac207 093a:2471 PAC207 Genius VideoCam ge111 +pac207 093a:2472 PAC207 Genius VideoCam ge110 +pac7311 093a:2600 PAC7311 Typhoon +pac7311 093a:2601 PAC7311 Phillips SPC610NC +pac7311 093a:2603 PAC7312 +pac7311 093a:2608 PAC7311 Trust WB-3300p +pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 +pac7311 093a:260f PAC7311 SnakeCam +sonixb 0c45:6001 Genius VideoCAM NB +sonixb 0c45:6005 Sweex Tas5110 +sonixb 0c45:6007 Sonix sn9c101 + Tas5110D +sonixb 0c45:6009 spcaCam@120 +sonixb 0c45:600d spcaCam@120 +sonixb 0c45:6011 MAX Webcam (Microdia - OV6650 - SN9C101G) +sonixb 0c45:6019 Generic Sonix OV7630 +sonixb 0c45:6024 Generic Sonix Tas5130c +sonixb 0c45:6025 Xcam Shanga +sonixb 0c45:6028 Sonix Btc Pc380 +sonixb 0c45:6029 spcaCam@150 +sonixb 0c45:602c Generic Sonix OV7630 +sonixb 0c45:602d LIC-200 LG +sonixb 0c45:602e Genius VideoCam Messenger +sonixj 0458:7025 Genius Eye 311Q +sonixj 045e:00f5 MicroSoft VX3000 +sonixj 045e:00f7 MicroSoft VX1000 +sonixj 0471:0327 Philips SPC 600 NC +sonixj 0471:0328 Philips SPC 700 NC +sonixj 0471:0330 Philips SPC 710NC +sonixj 0c45:6040 Speed NVC 350K +sonixj 0c45:607c Sonix sn9c102p Hv7131R +sonixj 0c45:60c0 Sangha Sn535 +sonixj 0c45:60ec SN9C105+MO4000 +sonixj 0c45:60fb Surfer NoName +sonixj 0c45:60fc LG-LIC300 +sonixj 0c45:612a Avant Camera +sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix +sonixj 0c45:6130 Sonix Pccam +sonixj 0c45:6138 Sn9c120 Mo4000 +sonixj 0c45:613b Surfer SN-206 +sonixj 0c45:613c Sonix Pccam168 +spca500 040a:0300 Kodak EZ200 +spca500 041e:400a Creative PC-CAM 300 +spca500 046d:0890 Logitech QuickCam traveler +spca500 046d:0900 Logitech Inc. ClickSmart 310 +spca500 046d:0901 Logitech Inc. ClickSmart 510 +spca500 04a5:300c Benq DC1016 +spca500 04fc:7333 PalmPixDC85 +spca500 055f:c200 Mustek Gsmart 300 +spca500 055f:c220 Gsmart Mini +spca500 06bd:0404 Agfa CL20 +spca500 06be:0800 Optimedia +spca500 084d:0003 D-Link DSC-350 +spca500 08ca:0103 Aiptek PocketDV +spca500 2899:012c Toptro Industrial +spca500 8086:0630 Intel Pocket PC Camera +spca501 040a:0002 Kodak DVC-325 +spca501 0497:c001 Smile International +spca501 0506:00df 3Com HomeConnect Lite +spca501 0733:0401 Intel Create and Share +spca501 0733:0402 ViewQuest M318B +spca501 1776:501c Arowana 300K CMOS Camera +spca501 0000:0000 MystFromOri Unknow Camera +spca505 041e:401d Creative Webcam NX ULTRA +spca505 0733:0430 Intel PC Camera Pro +spca506 06e1:a190 ADS Instant VCD +spca506 0734:043b 3DeMon USB Capture aka +spca506 99fa:8988 Grandtec V.cap +spca506 99fa:8988 Grandtec V.cap +spca508 041e:4018 Creative Webcam Vista (PD1100) +spca508 0461:0815 Micro Innovation IC200 +spca508 0733:0110 ViewQuest VQ110 +spca508 0af9:0010 Hama USB Sightcam 100 +spca508 0af9:0011 Hama USB Sightcam 100 +spca508 8086:0110 Intel Easy PC Camera +spca561 041e:401a Creative Webcam Vista (PD1100) +spca561 041e:403b Creative Webcam Vista (VF0010) +spca561 0458:7004 Genius VideoCAM Express V2 +spca561 046d:0928 Logitech QC Express Etch2 +spca561 046d:0929 Labtec Webcam Elch2 +spca561 046d:092a Logitech QC for Notebook +spca561 046d:092b Labtec Webcam Plus +spca561 046d:092c Logitech QC chat Elch2 +spca561 046d:092d Logitech QC Elch2 +spca561 046d:092e Logitech QC Elch2 +spca561 046d:092f Logitech QC Elch2 +spca561 04fc:0561 Flexcam 100 +spca561 060b:a001 Maxell Compact Pc PM3 +spca561 10fd:7e50 FlyCam Usb 100 +spca561 abcd:cdee Petcam +stk014 05e1:0893 Syntek DV4000 +sunplus 041e:400b Creative PC-CAM 600 +sunplus 041e:4012 PC-Cam350 +sunplus 041e:4013 Creative Pccam750 +sunplus 0458:7006 Genius Dsc 1.3 Smart +sunplus 046d:0905 Logitech ClickSmart 820 +sunplus 046d:0960 Logitech ClickSmart 420 +sunplus 0471:0322 Philips DMVC1300K +sunplus 04a5:3003 Benq DC 1300 +sunplus 04a5:3008 Benq DC 1500 +sunplus 04a5:300a Benq DC3410 +sunplus 04f1:1001 JVC GC A50 +sunplus 04fc:500c Sunplus CA500C +sunplus 04fc:504a Aiptek Mini PenCam 1.3 +sunplus 04fc:504b Maxell MaxPocket LE 1.3 +sunplus 04fc:5330 Digitrex 2110 +sunplus 04fc:5360 Sunplus Generic +sunplus 04fc:ffff Pure DigitalDakota +sunplus 052b:1513 Megapix V4 +sunplus 0546:3155 Polaroid PDC3070 +sunplus 0546:3191 Polaroid Ion 80 +sunplus 0546:3273 Polaroid PDC2030 +sunplus 055f:c211 Kowa Bs888e Microcamera +sunplus 055f:c230 Mustek Digicam 330K +sunplus 055f:c232 Mustek MDC3500 +sunplus 055f:c360 Mustek DV4000 Mpeg4 +sunplus 055f:c420 Mustek gSmart Mini 2 +sunplus 055f:c430 Mustek Gsmart LCD 2 +sunplus 055f:c440 Mustek DV 3000 +sunplus 055f:c520 Mustek gSmart Mini 3 +sunplus 055f:c530 Mustek Gsmart LCD 3 +sunplus 055f:c540 Gsmart D30 +sunplus 055f:c630 Mustek MDC4000 +sunplus 055f:c650 Mustek MDC5500Z +sunplus 05da:1018 Digital Dream Enigma 1.3 +sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom +sunplus 0733:1311 Digital Dream Epsilon 1.3 +sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam +sunplus 0733:2211 Jenoptik jdc 21 LCD +sunplus 0733:2221 Mercury Digital Pro 3.1p +sunplus 0733:3261 Concord 3045 spca536a +sunplus 0733:3281 Cyberpix S550V +sunplus 08ca:0104 Aiptek PocketDVII 1.3 +sunplus 08ca:0106 Aiptek Pocket DV3100+ +sunplus 08ca:2008 Aiptek Mini PenCam 2 M +sunplus 08ca:2010 Aiptek PocketCam 3M +sunplus 08ca:2016 Aiptek PocketCam 2 Mega +sunplus 08ca:2018 Aiptek Pencam SD 2M +sunplus 08ca:2020 Aiptek Slim 3000F +sunplus 08ca:2022 Aiptek Slim 3200 +sunplus 08ca:2024 Aiptek DV3500 Mpeg4 +sunplus 08ca:2028 Aiptek PocketCam4M +sunplus 08ca:2040 Aiptek PocketDV4100M +sunplus 08ca:2042 Aiptek PocketDV5100 +sunplus 08ca:2060 Aiptek PocketDV5300 +sunplus 0d64:0303 Sunplus FashionCam DXG +tv8532 046d:0920 QC Express +tv8532 046d:0921 Labtec Webcam +tv8532 0545:808b Veo Stingray +tv8532 0545:8333 Veo Stingray +tv8532 0923:010f ICM532 cams +vc032x 046d:0892 Logitech Orbicam +vc032x 046d:0896 Logitech Orbicam +vc032x 0ac8:0321 Vimicro generic vc0321 +vc032x 0ac8:0323 Vimicro Vc0323 +vc032x 0ac8:0328 A4Tech PK-130MG +vc032x 0ac8:c001 Sony embedded vimicro +vc032x 0ac8:c002 Sony embedded vimicro +vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC +zc3xx 041e:041e Creative WebCam Live! +zc3xx 041e:4017 Creative Webcam Mobile PD1090 +zc3xx 041e:401c Creative NX +zc3xx 041e:401e Creative Nx Pro +zc3xx 041e:401f Creative Webcam Notebook PD1171 +zc3xx 041e:4029 Creative WebCam Vista Pro +zc3xx 041e:4034 Creative Instant P0620 +zc3xx 041e:4035 Creative Instant P0620D +zc3xx 041e:4036 Creative Live ! +zc3xx 041e:403a Creative Nx Pro 2 +zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) +zc3xx 041e:4053 Creative Live!Cam Video IM +zc3xx 0458:7007 Genius VideoCam V2 +zc3xx 0458:700c Genius VideoCam V3 +zc3xx 0458:700f Genius VideoCam Web V2 +zc3xx 0461:0a00 MicroInnovation WebCam320 +zc3xx 046d:08a0 Logitech QC IM +zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound +zc3xx 046d:08a2 Labtec Webcam Pro +zc3xx 046d:08a3 Logitech QC Chat +zc3xx 046d:08a6 Logitech QCim +zc3xx 046d:08a7 Logitech QuickCam Image +zc3xx 046d:08a9 Logitech Notebook Deluxe +zc3xx 046d:08aa Labtec Webcam Notebook +zc3xx 046d:08ac Logitech QuickCam Cool +zc3xx 046d:08ad Logitech QCCommunicate STX +zc3xx 046d:08ae Logitech QuickCam for Notebooks +zc3xx 046d:08af Logitech QuickCam Cool +zc3xx 046d:08b9 Logitech QC IM ??? +zc3xx 046d:08d7 Logitech QCam STX +zc3xx 046d:08d9 Logitech QuickCam IM/Connect +zc3xx 046d:08d8 Logitech Notebook Deluxe +zc3xx 046d:08da Logitech QuickCam Messenger +zc3xx 046d:08dd Logitech QuickCam for Notebooks +zc3xx 0471:0325 Philips SPC 200 NC +zc3xx 0471:0326 Philips SPC 300 NC +zc3xx 0471:032d Philips spc210nc +zc3xx 0471:032e Philips spc315nc +zc3xx 055f:c005 Mustek Wcam300A +zc3xx 055f:d003 Mustek WCam300A +zc3xx 055f:d004 Mustek WCam300 AN +zc3xx 0698:2003 CTX M730V built in +zc3xx 0ac8:0302 Z-star Vimicro zc0302 +zc3xx 0ac8:301b Z-Star zc301b +zc3xx 0ac8:303b Vimicro 0x303b +zc3xx 0ac8:305b Z-star Vimicro zc0305b +zc3xx 0ac8:307b Ldlc VC302+Ov7620 +zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 +zc3xx 10fd:8050 Typhoon Webshot II USB 300k diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 8fca90b75e79..a6fbee4d41b7 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -801,6 +801,8 @@ config USB_VIDEO_CLASS For more information see: +source "drivers/media/video/gspca/Kconfig" + source "drivers/media/video/pvrusb2/Kconfig" source "drivers/media/video/em28xx/Kconfig" diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig new file mode 100644 index 000000000000..a04e413e1258 --- /dev/null +++ b/drivers/media/video/gspca/Kconfig @@ -0,0 +1,13 @@ +config USB_GSPCA + tristate "USB GSPCA driver" + depends on VIDEO_V4L2 + ---help--- + Say Y here if you want support for various USB cameras. + + See for more info. + + This driver uses the Video For Linux API. You must say Y or M to + "Video For Linux" to use this driver. + + To compile this driver as modules, choose M here: the + modules will be called gspca_xxxx. diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile new file mode 100644 index 000000000000..885d4454d8e5 --- /dev/null +++ b/drivers/media/video/gspca/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_GSPCA) += gspca_main.o gspca_stk014.o + +gspca_main-objs := gspca.o +gspca_stk014-objs := stk014.o diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c new file mode 100644 index 000000000000..4fe082ff7074 --- /dev/null +++ b/drivers/media/video/gspca/gspca.c @@ -0,0 +1,1750 @@ +/* + * Main USB camera driver + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define MODULE_NAME "gspca" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gspca.h" + +MODULE_AUTHOR("Jean-Francois Moine "); +MODULE_DESCRIPTION("GSPCA USB Camera Driver"); +MODULE_LICENSE("GPL"); + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 26) +static const char version[] = "0.0.26"; + +static int video_nr = -1; + +static int comp_fac = 30; /* Buffer size ratio when compressed in % */ + +#ifdef GSPCA_DEBUG +int gspca_debug = D_ERR | D_PROBE; +EXPORT_SYMBOL(gspca_debug); + +static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) +{ + if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') { + PDEBUG(D_CONF|D_STREAM, "%s %c%c%c%c %dx%d", + txt, + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24, + w, h); + } else { + PDEBUG(D_CONF|D_STREAM, "%s 0x%08x %dx%d", + txt, + pixfmt, + w, h); + } +} +#else +#define PDEBUG_MODE(txt, pixfmt, w, h) +#endif + +/* + * VMA operations. + */ +static void gspca_vm_open(struct vm_area_struct *vma) +{ + struct gspca_frame *frame = vma->vm_private_data; + + frame->vma_use_count++; + frame->v4l2_buf.flags |= V4L2_BUF_FLAG_MAPPED; +} + +static void gspca_vm_close(struct vm_area_struct *vma) +{ + struct gspca_frame *frame = vma->vm_private_data; + + if (--frame->vma_use_count <= 0) + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_MAPPED; +} + +static struct vm_operations_struct gspca_vm_ops = { + .open = gspca_vm_open, + .close = gspca_vm_close, +}; + +/* + * ISOC message interrupt from the USB device + * + * Analyse each packet and call the subdriver for doing the copy + * to the frame buffer. + */ +static void isoc_irq(struct urb *urb) +{ + struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; + struct gspca_frame *frame; + unsigned char *data; /* address of data in the iso message */ + int i, j, len, st; + cam_pkt_op pkt_scan; + + PDEBUG(D_PACK, "isoc irq"); + if (!gspca_dev->streaming) + return; + pkt_scan = gspca_dev->sd_desc->pkt_scan; + for (i = 0; i < urb->number_of_packets; i++) { + + /* check the availability of the frame buffer */ + j = gspca_dev->fr_i; + j = gspca_dev->fr_queue[j]; + frame = &gspca_dev->frame[j]; + if ((frame->v4l2_buf.flags + & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) + != V4L2_BUF_FLAG_QUEUED) { + gspca_dev->last_packet_type = DISCARD_PACKET; + break; + } + + /* check the packet status and length */ + len = urb->iso_frame_desc[i].actual_length; + st = urb->iso_frame_desc[i].status; + if (st) { + PDEBUG(D_ERR, "ISOC data error: [%d] len=%d, status=%d", + i, len, st); + gspca_dev->last_packet_type = DISCARD_PACKET; + continue; + } + if (len == 0) + continue; + + /* let the packet be analyzed by the subdriver */ + PDEBUG(D_PACK, "packet [%d] o:%d l:%d", + i, urb->iso_frame_desc[i].offset, len); + data = (unsigned char *) urb->transfer_buffer + + urb->iso_frame_desc[i].offset; + pkt_scan(gspca_dev, frame, data, len); + } + + /* resubmit the URB */ + urb->status = 0; + st = usb_submit_urb(urb, GFP_ATOMIC); + if (st < 0) + PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); +} + +/* + * add data to the current frame + * + * This function is called by the subdrivers at interrupt level. + * To build a frame, these ones must add + * - one FIRST_PACKET + * - 0 or many INTER_PACKETs + * - one LAST_PACKET + * DISCARD_PACKET invalidates the whole frame. + * On LAST_PACKET, a new frame is returned. + */ +struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, + int packet_type, + struct gspca_frame *frame, + unsigned char *data, + int len) +{ + int i, j; + + PDEBUG(D_PACK, "add t:%d l:%d %02x %02x %02x %02x...", + packet_type, len, data[0], data[1], data[2], data[3]); + + /* when start of a new frame, if the current frame buffer + * is not queued, discard the whole frame */ + if (packet_type == FIRST_PACKET) { + if ((frame->v4l2_buf.flags + & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) + != V4L2_BUF_FLAG_QUEUED) { + gspca_dev->last_packet_type = DISCARD_PACKET; + return frame; + } + frame->data_end = frame->data; + jiffies_to_timeval(get_jiffies_64(), + &frame->v4l2_buf.timestamp); + frame->v4l2_buf.sequence = ++gspca_dev->sequence; + } else if (gspca_dev->last_packet_type == DISCARD_PACKET) + return frame; + + /* append the packet in the frame buffer */ + if (len > 0) { + if (frame->data_end - frame->data + len + > frame->v4l2_buf.length) { + PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", + frame->data_end - frame->data + len, + frame->v4l2_buf.length); + packet_type = DISCARD_PACKET; + } else { + if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) + memcpy(frame->data_end, data, len); + else + copy_to_user(frame->data_end, data, len); + frame->data_end += len; + } + } + gspca_dev->last_packet_type = packet_type; + + /* if last packet, wake the application and advance in the queue */ + if (packet_type == LAST_PACKET) { + frame->v4l2_buf.bytesused = frame->data_end - frame->data; + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; + frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ + i = gspca_dev->fr_i; + i = (i + 1) % gspca_dev->nframes; + PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", + frame->v4l2_buf.bytesused, + gspca_dev->fr_q, + i, + gspca_dev->fr_o); + j = gspca_dev->fr_queue[i]; + frame = &gspca_dev->frame[j]; + gspca_dev->fr_i = i; + } + return frame; +} +EXPORT_SYMBOL(gspca_frame_add); + +static int gspca_is_compressed(__u32 format) +{ + switch (format) { + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_JPEG: + return 1; + } + return 0; +} + +static void *rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr; + + size = PAGE_ALIGN(size); + mem = vmalloc_32(size); + if (mem != 0) { + memset(mem, 0, size); + adr = (unsigned long) mem; + while ((long) size > 0) { + SetPageReserved(vmalloc_to_page((void *) adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + } + return mem; +} + +static void rvfree(void *mem, unsigned long size) +{ + unsigned long adr; + + if (!mem) + return; + adr = (unsigned long) mem; + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *) adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(mem); +} + +static int frame_alloc(struct gspca_dev *gspca_dev, + unsigned int count, + unsigned int frsz, + enum v4l2_memory memory) +{ + int i, ret = 0; + + PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); + if (gspca_dev->nframes != 0) { + PDEBUG(D_ERR|D_STREAM, "alloc frame already done"); + return -EBUSY; + } + if (count > GSPCA_MAX_FRAMES) + count = GSPCA_MAX_FRAMES; + /* if compressed, reduce the buffer size */ + if (gspca_is_compressed(gspca_dev->pixfmt)) + frsz = (frsz * comp_fac) / 100; + frsz = PAGE_ALIGN(frsz); + PDEBUG(D_STREAM, "new fr_sz: %d", frsz); + gspca_dev->frsz = frsz; + if (memory == V4L2_MEMORY_MMAP) { + gspca_dev->frbuf = rvmalloc(frsz * count); + if (!gspca_dev->frbuf) { + err("frame alloc failed"); + return -ENOMEM; + } + } + gspca_dev->nframes = count; + for (i = 0; i < count; i++) { + gspca_dev->frame[i].v4l2_buf.index = i; + gspca_dev->frame[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + gspca_dev->frame[i].v4l2_buf.flags = 0; + gspca_dev->frame[i].v4l2_buf.field = V4L2_FIELD_NONE; + gspca_dev->frame[i].v4l2_buf.length = frsz; + gspca_dev->frame[i].v4l2_buf.memory = memory; + if (memory == V4L2_MEMORY_MMAP) { + gspca_dev->frame[i].data + = gspca_dev->frame[i].data_end + = gspca_dev->frbuf + i * frsz; + gspca_dev->frame[i].v4l2_buf.m.offset = i * frsz; + } + gspca_dev->frame[i].v4l2_buf.flags = 0; /* buf in app space */ + } + gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; + gspca_dev->last_packet_type = DISCARD_PACKET; + gspca_dev->sequence = 0; + atomic_set(&gspca_dev->nevent, 0); + return ret; +} + +static void frame_free(struct gspca_dev *gspca_dev) +{ + int i; + + PDEBUG(D_STREAM, "frame free"); + if (gspca_dev->frbuf != 0) { + rvfree(gspca_dev->frbuf, + gspca_dev->nframes * gspca_dev->frsz); + gspca_dev->frbuf = NULL; + for (i = 0; i < gspca_dev->nframes; i++) + gspca_dev->frame[i].data = NULL; + } + gspca_dev->nframes = 0; +} + +static int gspca_kill_transfer(struct gspca_dev *gspca_dev) +{ + struct urb *urb; + unsigned int i; + + PDEBUG(D_STREAM, "kill transfer"); + gspca_dev->streaming = 0; + for (i = 0; i < NURBS; ++i) { + urb = gspca_dev->pktbuf[i].urb; + if (urb == NULL) + continue; + + gspca_dev->pktbuf[i].urb = NULL; + usb_kill_urb(urb); + + /* urb->transfer_buffer_length is not touched by USB core, + * so we can use it here as the buffer length */ + if (gspca_dev->pktbuf[i].data) { + usb_buffer_free(gspca_dev->dev, + urb->transfer_buffer_length, + gspca_dev->pktbuf[i].data, + urb->transfer_dma); + gspca_dev->pktbuf[i].data = NULL; + } + usb_free_urb(urb); + } + return 0; +} + +/* + * search an input isochronous endpoint in an alternate setting + */ +static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, + __u8 epaddr) +{ + struct usb_host_endpoint *ep; + int i, attr; + + epaddr |= USB_DIR_IN; + for (i = 0; i < alt->desc.bNumEndpoints; i++) { + ep = &alt->endpoint[i]; + if (ep->desc.bEndpointAddress == epaddr) { + attr = ep->desc.bmAttributes + & USB_ENDPOINT_XFERTYPE_MASK; + if (attr == USB_ENDPOINT_XFER_ISOC) + return ep; + break; + } + } + return NULL; +} + +/* + * search an input isochronous endpoint + * + * The endpoint is defined by the subdriver. + * Use only the first isoc (some Zoran - 0x0572:0x0001 - have two such ep). + * This routine may be called many times when the bandwidth is too small + * (the bandwidth is checked on urb submit). + */ +struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) +{ + struct usb_interface *intf; + struct usb_host_endpoint *ep; + int i, ret; + + intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); + i = gspca_dev->alt; /* previous alt setting */ + while (--i > 0) { /* alt 0 is unusable */ + ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); + if (ep) + break; + } + if (i <= 0) { + err("no ISOC endpoint found"); + return NULL; + } + PDEBUG(D_STREAM, "use ISOC alt %d ep 0x%02x", + i, ep->desc.bEndpointAddress); + ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i); + if (ret < 0) { + err("set interface err %d", ret); + return NULL; + } + gspca_dev->alt = i; + return ep; +} + +/* + * create the isochronous URBs + */ +static int create_urbs(struct gspca_dev *gspca_dev, + struct usb_host_endpoint *ep) +{ + struct urb *urb; + int n, i, psize, npkt, bsize; + + /* calculate the packet size and the number of packets */ + /* the URB buffer size must be a power of 2 */ + psize = le16_to_cpu(ep->desc.wMaxPacketSize); + /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ + psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); + npkt = ISO_MAX_SIZE / psize; + if (npkt > ISO_MAX_PKT) + npkt = ISO_MAX_PKT; + bsize = psize * npkt; + for (n = ISO_MAX_SIZE; n > 0; n >>= 1) { + if (n & bsize) /* !! assume ISO_MAX_SIZE is a power of 2 */ + break; + } + if (n != 0) { + npkt = n / psize; + bsize = psize * npkt; + } + PDEBUG(D_STREAM, + "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); + for (n = 0; n < NURBS; n++) { + urb = usb_alloc_urb(npkt, GFP_KERNEL); + if (!urb) { + err("usb_alloc_urb failed"); + return -ENOMEM; + } + gspca_dev->pktbuf[n].data = usb_buffer_alloc(gspca_dev->dev, + bsize, + GFP_KERNEL, + &urb->transfer_dma); + + if (gspca_dev->pktbuf[n].data == NULL) { + usb_free_urb(urb); + gspca_kill_transfer(gspca_dev); + err("usb_buffer_urb failed"); + return -ENOMEM; + } + gspca_dev->pktbuf[n].urb = urb; + urb->dev = gspca_dev->dev; + urb->context = gspca_dev; + urb->pipe = usb_rcvisocpipe(gspca_dev->dev, + ep->desc.bEndpointAddress); + urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->interval = ep->desc.bInterval; + urb->transfer_buffer = gspca_dev->pktbuf[n].data; + urb->complete = isoc_irq; + urb->number_of_packets = npkt; + urb->transfer_buffer_length = bsize; + for (i = 0; i < npkt; i++) { + urb->iso_frame_desc[i].length = psize; + urb->iso_frame_desc[i].offset = psize * i; + } + } + return 0; +} + +/* + * start the USB transfer + */ +static int gspca_init_transfer(struct gspca_dev *gspca_dev) +{ + struct usb_interface *intf; + struct usb_host_endpoint *ep; + int n, ret; + + ret = mutex_lock_interruptible(&gspca_dev->usb_lock); + if (ret < 0) + return ret; + + /* set the max alternate setting and loop until urb submit succeeds */ + intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); + gspca_dev->alt = intf->num_altsetting; + for (;;) { + PDEBUG(D_STREAM, "init transfer nbalt %d", gspca_dev->alt); + ep = get_isoc_ep(gspca_dev); + if (ep == NULL) { + ret = -EIO; + goto out; + } + ret = create_urbs(gspca_dev, ep); + if (ret < 0) + goto out; + + /* start the cam */ + gspca_dev->sd_desc->start(gspca_dev); + gspca_dev->streaming = 1; + atomic_set(&gspca_dev->nevent, 0); + + /* submit the URBs */ + for (n = 0; n < NURBS; n++) { + ret = usb_submit_urb(gspca_dev->pktbuf[n].urb, + GFP_KERNEL); + if (ret < 0) { + PDEBUG(D_ERR|D_STREAM, + "usb_submit_urb [%d] err %d", n, ret); + gspca_kill_transfer(gspca_dev); + if (ret == -ENOSPC) + break; /* try the previous alt */ + goto out; + } + } + if (ret >= 0) + break; + } +out: + mutex_unlock(&gspca_dev->usb_lock); + return ret; +} + +static int gspca_set_alt0(struct gspca_dev *gspca_dev) +{ + int ret; + + ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0); + if (ret < 0) + PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret); + return ret; +} + +static void gspca_stream_off(struct gspca_dev *gspca_dev) +{ + mutex_lock_interruptible(&gspca_dev->usb_lock); + gspca_dev->streaming = 0; + if (gspca_dev->present) { + gspca_dev->sd_desc->stopN(gspca_dev); + gspca_kill_transfer(gspca_dev); + gspca_set_alt0(gspca_dev); + gspca_dev->sd_desc->stop0(gspca_dev); + PDEBUG(D_STREAM, "stream off OK"); + } else { + gspca_kill_transfer(gspca_dev); + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); + PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); + } + mutex_unlock(&gspca_dev->usb_lock); +} + +static int gspca_set_default_mode(struct gspca_dev *gspca_dev) +{ + int i; + + i = gspca_dev->cam.nmodes - 1; /* take the highest mode */ + gspca_dev->curr_mode = i; + gspca_dev->width = gspca_dev->cam.cam_mode[i].width; + gspca_dev->height = gspca_dev->cam.cam_mode[i].height; + gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; + return 0; +} + +static int wxh_to_mode(struct gspca_dev *gspca_dev, + int width, int height) +{ + int i; + + for (i = gspca_dev->cam.nmodes - 1; --i >= 0; ) { + if (width > gspca_dev->cam.cam_mode[i].width) + break; + } + i++; + while (i < gspca_dev->cam.nmodes - 1 + && width == gspca_dev->cam.cam_mode[i + 1].width + && height < gspca_dev->cam.cam_mode[i + 1].height) + i++; + return i; +} + +static __u32 get_v4l2_depth(__u32 pixfmt) +{ + switch (pixfmt) { + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + return 32; + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + return 24; + case V4L2_PIX_FMT_RGB565: + case V4L2_PIX_FMT_YUYV: /* packed 4.2.2 */ + case V4L2_PIX_FMT_YYUV: + return 16; + case V4L2_PIX_FMT_YUV420: /* planar 4.2.0 */ + return 12; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_SBGGR8: /* Bayer */ + return 8; + } + PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24); + return -EINVAL; +} + +/* + * search a mode with the right pixel format + */ +static int gspca_get_mode(struct gspca_dev *gspca_dev, + int mode, + int pixfmt) +{ + int modeU, modeD; + + modeU = modeD = mode; + while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) { + if (--modeD >= 0) { + if (gspca_dev->cam.cam_mode[modeD].pixfmt == pixfmt) + return modeD; + } + if (++modeU < gspca_dev->cam.nmodes) { + if (gspca_dev->cam.cam_mode[modeU].pixfmt == pixfmt) + return modeU; + } + } + return -EINVAL; +} + +static int vidioc_enum_fmt_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *fmtdesc) +{ + struct gspca_dev *gspca_dev = priv; + int i, j, index; + __u32 fmt_tb[8]; + + PDEBUG(D_CONF, "enum fmt cap"); + + /* give an index to each format */ + index = 0; + j = 0; + for (i = gspca_dev->cam.nmodes; --i >= 0; ) { + fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixfmt; + j = 0; + for (;;) { + if (fmt_tb[j] == fmt_tb[index]) + break; + j++; + } + if (j == index) { + if (fmtdesc->index == index) + break; /* new format */ + index++; + if (index >= sizeof fmt_tb / sizeof fmt_tb[0]) + return -EINVAL; + } + } + if (i < 0) + return -EINVAL; /* no more format */ + + fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmtdesc->pixelformat = fmt_tb[index]; + if (gspca_is_compressed(fmt_tb[index])) + fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; + fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; + fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; + fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; + fmtdesc->description[3] = fmtdesc->pixelformat >> 24; + fmtdesc->description[4] = '\0'; + return 0; +} + +static int gspca_get_buff_size(struct gspca_dev *gspca_dev) +{ + unsigned int size; + + size = gspca_dev->width * gspca_dev->height + * get_v4l2_depth(gspca_dev->pixfmt) / 8; + if (!size) + return -ENOMEM; + return size; +} + +static int vidioc_g_fmt_cap(struct file *file, void *priv, + struct v4l2_format *fmt) +{ + struct gspca_dev *gspca_dev = priv; + + fmt->fmt.pix.width = gspca_dev->width; + fmt->fmt.pix.height = gspca_dev->height; + fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) { + PDEBUG_MODE("get fmt cap", + fmt->fmt.pix.pixelformat, + fmt->fmt.pix.width, + fmt->fmt.pix.height); + } +#endif + fmt->fmt.pix.field = V4L2_FIELD_NONE; + fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) + * fmt->fmt.pix.width / 8; + fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline + * fmt->fmt.pix.height; +/* (should be in the subdriver) */ + fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; + fmt->fmt.pix.priv = 0; + return 0; +} + +static int try_fmt_cap(struct file *file, + void *priv, + struct v4l2_format *fmt) +{ + struct gspca_dev *gspca_dev = priv; + int w, h, mode, mode2, frsz; + + w = (int) fmt->fmt.pix.width; + h = (int) fmt->fmt.pix.height; +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) + PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); +#endif + /* search the closest mode for width and height */ + mode = wxh_to_mode(gspca_dev, w, h); + + /* OK if right palette */ + if (gspca_dev->cam.cam_mode[mode].pixfmt != fmt->fmt.pix.pixelformat) { + + /* else, search the closest mode with the same pixel format */ + mode2 = gspca_get_mode(gspca_dev, mode, + fmt->fmt.pix.pixelformat); + if (mode2 >= 0) + mode = mode2; + else { + + /* no chance, return this mode */ + fmt->fmt.pix.pixelformat + = gspca_dev->cam.cam_mode[mode].pixfmt; +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) { + PDEBUG_MODE("new format", + fmt->fmt.pix.pixelformat, + gspca_dev->cam.cam_mode[mode].width, + gspca_dev->cam.cam_mode[mode].height); + } +#endif + } + } + fmt->fmt.pix.width = gspca_dev->cam.cam_mode[mode].width; + fmt->fmt.pix.height = gspca_dev->cam.cam_mode[mode].height; + fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) + * fmt->fmt.pix.width / 8; + frsz = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height; + if (gspca_is_compressed(fmt->fmt.pix.pixelformat)) + frsz = (frsz * comp_fac) / 100; + fmt->fmt.pix.sizeimage = frsz; + return mode; /* used when s_fmt */ +} + +static int vidioc_try_fmt_cap(struct file *file, + void *priv, + struct v4l2_format *fmt) +{ + int ret; + +/* mutex_lock_interruptible(&gspca_dev->queue_lock); */ + ret = try_fmt_cap(file, priv, fmt); +/* mutex_unlock(&gspca_dev->queue_lock); */ + if (ret < 0) + return ret; + return 0; +} + +static int vidioc_s_fmt_cap(struct file *file, void *priv, + struct v4l2_format *fmt) +{ + struct gspca_dev *gspca_dev = priv; + int ret, was_streaming; + +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) { + PDEBUG_MODE("set fmt cap", + fmt->fmt.pix.pixelformat, + fmt->fmt.pix.width, fmt->fmt.pix.height); + } +#endif + mutex_lock_interruptible(&gspca_dev->queue_lock); + ret = try_fmt_cap(file, priv, fmt); + if (ret < 0) + goto out; + + if (ret == gspca_dev->curr_mode) + goto out; /* same mode */ + was_streaming = gspca_dev->streaming; + if (was_streaming != 0) + gspca_stream_off(gspca_dev); + gspca_dev->width = (int) fmt->fmt.pix.width; + gspca_dev->height = (int) fmt->fmt.pix.height; + gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; + gspca_dev->curr_mode = ret; + if (was_streaming) + ret = gspca_init_transfer(gspca_dev); +out: + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +static int dev_open(struct inode *inode, struct file *file) +{ + struct gspca_dev *gspca_dev; + int ret; + + PDEBUG(D_STREAM, "opening"); + gspca_dev = (struct gspca_dev *) video_devdata(file); + ret = mutex_lock_interruptible(&gspca_dev->queue_lock); + if (ret < 0) + return ret; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } + + /* if not done yet, initialize the sensor */ + if (gspca_dev->users == 0) { + ret = mutex_lock_interruptible(&gspca_dev->usb_lock); + if (ret < 0) + goto out; + ret = gspca_dev->sd_desc->open(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + if (ret != 0) { + PDEBUG(D_ERR|D_CONF, "init device failed %d", ret); + goto out; + } + } else if (gspca_dev->users > 8) { /* (arbitrary value) */ + ret = -EBUSY; + goto out; + } + gspca_dev->users++; + file->private_data = gspca_dev; +#ifdef GSPCA_DEBUG + /* activate the v4l2 debug */ + if (gspca_debug & D_CONF) + gspca_dev->vdev.debug |= 3; + else + gspca_dev->vdev.debug &= ~3; +#endif +out: + mutex_unlock(&gspca_dev->queue_lock); + if (ret != 0) + PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret); + else + PDEBUG(D_STREAM, "open OK"); + return ret; +} + +static int dev_close(struct inode *inode, struct file *file) +{ + struct gspca_dev *gspca_dev = file->private_data; + + PDEBUG(D_STREAM, "closing"); + if (gspca_dev->streaming) { + mutex_lock_interruptible(&gspca_dev->queue_lock); + gspca_stream_off(gspca_dev); + mutex_unlock(&gspca_dev->queue_lock); + } + mutex_lock_interruptible(&gspca_dev->usb_lock); + gspca_dev->sd_desc->close(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* wake blocked processes */ + schedule(); + mutex_lock_interruptible(&gspca_dev->queue_lock); + frame_free(gspca_dev); + file->private_data = NULL; + gspca_dev->users--; + mutex_unlock(&gspca_dev->queue_lock); + PDEBUG(D_STREAM, "closed"); + return 0; +} + +static int vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct gspca_dev *gspca_dev = priv; + + PDEBUG(D_CONF, "querycap"); + memset(cap, 0, sizeof *cap); + strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); + strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); + strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, + sizeof cap->bus_info); + cap->version = DRIVER_VERSION_NUMBER; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_STREAMING + | V4L2_CAP_READWRITE; + return 0; +} + +static int vidioc_queryctrl(struct file *file, void *priv, + struct v4l2_queryctrl *q_ctrl) +{ + struct gspca_dev *gspca_dev = priv; + int i; + + PDEBUG(D_CONF, "queryctrl"); + for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { + if (q_ctrl->id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { + memcpy(q_ctrl, + &gspca_dev->sd_desc->ctrls[i].qctrl, + sizeof *q_ctrl); + return 0; + } + } + if (q_ctrl->id >= V4L2_CID_BASE + && q_ctrl->id <= V4L2_CID_LASTP1) { + q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; + return 0; + } + return -EINVAL; +} + +static int vidioc_s_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct gspca_dev *gspca_dev = priv; + struct ctrl *ctrls; + int i, ret; + + PDEBUG(D_CONF, "set ctrl"); + for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; + i < gspca_dev->sd_desc->nctrls; + i++, ctrls++) { + if (ctrl->id != ctrls->qctrl.id) + continue; + if (ctrl->value < ctrls->qctrl.minimum + && ctrl->value > ctrls->qctrl.maximum) + return -ERANGE; + PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); + mutex_lock_interruptible(&gspca_dev->usb_lock); + ret = ctrls->set(gspca_dev, ctrl->value); + mutex_unlock(&gspca_dev->usb_lock); + return ret; + } + return -EINVAL; +} + +static int vidioc_g_ctrl(struct file *file, void *priv, + struct v4l2_control *ctrl) +{ + struct gspca_dev *gspca_dev = priv; + + struct ctrl *ctrls; + int i, ret; + + for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; + i < gspca_dev->sd_desc->nctrls; + i++, ctrls++) { + if (ctrl->id != ctrls->qctrl.id) + continue; + mutex_lock_interruptible(&gspca_dev->usb_lock); + ret = ctrls->get(gspca_dev, &ctrl->value); + mutex_unlock(&gspca_dev->usb_lock); + return ret; + } + return -EINVAL; +} + +static int vidioc_querymenu(struct file *file, void *priv, + struct v4l2_querymenu *qmenu) +{ + struct gspca_dev *gspca_dev = priv; + + if (!gspca_dev->sd_desc->querymenu) + return -EINVAL; + return gspca_dev->sd_desc->querymenu(gspca_dev, qmenu); +} + +static int vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *input) +{ + struct gspca_dev *gspca_dev = priv; + + if (input->index != 0) + return -EINVAL; + memset(input, 0, sizeof *input); + input->type = V4L2_INPUT_TYPE_CAMERA; + strncpy(input->name, gspca_dev->sd_desc->name, + sizeof input->name); + return 0; +} + +static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i > 0) + return -EINVAL; + return (0); +} + +static int vidioc_reqbufs(struct file *file, void *priv, + struct v4l2_requestbuffers *rb) +{ + struct gspca_dev *gspca_dev = priv; + int frsz, ret; + + PDEBUG(D_STREAM, "reqbufs %d", rb->count); + if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (rb->memory != V4L2_MEMORY_MMAP + && rb->memory != V4L2_MEMORY_USERPTR) + return -EINVAL; + if (rb->count == 0) + return -EINVAL; + frsz = gspca_get_buff_size(gspca_dev); + if (frsz < 0) + return frsz; + ret = mutex_lock_interruptible(&gspca_dev->queue_lock); + if (ret < 0) + return ret; + ret = frame_alloc(gspca_dev, + rb->count, + (unsigned int) frsz, + rb->memory); + if (ret == 0) + rb->count = gspca_dev->nframes; + mutex_unlock(&gspca_dev->queue_lock); + PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count); + return ret; +} + +static int vidioc_querybuf(struct file *file, void *priv, + struct v4l2_buffer *v4l2_buf) +{ + struct gspca_dev *gspca_dev = priv; + struct gspca_frame *frame; + + PDEBUG(D_STREAM, "querybuf"); + if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || v4l2_buf->index < 0 + || v4l2_buf->index >= gspca_dev->nframes) + return -EINVAL; + + frame = &gspca_dev->frame[v4l2_buf->index]; + memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); + return 0; +} + +static int vidioc_streamon(struct file *file, void *priv, + enum v4l2_buf_type buf_type) +{ + struct gspca_dev *gspca_dev = priv; + int ret; + + PDEBUG(D_STREAM, "stream on"); + if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + ret = mutex_lock_interruptible(&gspca_dev->queue_lock); + if (ret < 0) + return ret; + if (!gspca_dev->present) { + ret = -ENODEV; + goto out; + } + if (gspca_dev->nframes == 0) { + ret = -EINVAL; + goto out; + } + if (!gspca_dev->streaming) { + ret = gspca_init_transfer(gspca_dev); + if (ret < 0) + goto out; + } +#ifdef GSPCA_DEBUG + if (gspca_debug & D_STREAM) { + PDEBUG_MODE("stream on OK", + gspca_dev->pixfmt, + gspca_dev->width, + gspca_dev->height); + } +#endif +out: + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +static int vidioc_streamoff(struct file *file, void *priv, + enum v4l2_buf_type buf_type) +{ + struct gspca_dev *gspca_dev = priv; + + PDEBUG(D_STREAM, "stream off"); + if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (gspca_dev->streaming) { + mutex_lock_interruptible(&gspca_dev->queue_lock); + gspca_stream_off(gspca_dev); + mutex_unlock(&gspca_dev->queue_lock); + } + return 0; +} + +static int vidioc_g_jpegcomp(struct file *file, void *priv, + struct v4l2_jpegcompression *jpegcomp) +{ + struct gspca_dev *gspca_dev = priv; + int ret; + + if (!gspca_dev->sd_desc->get_jcomp) + return -EINVAL; + mutex_lock_interruptible(&gspca_dev->usb_lock); + ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); + mutex_unlock(&gspca_dev->usb_lock); + return ret; +} + +static int vidioc_s_jpegcomp(struct file *file, void *priv, + struct v4l2_jpegcompression *jpegcomp) +{ + struct gspca_dev *gspca_dev = priv; + int ret; + + mutex_lock_interruptible(&gspca_dev->usb_lock); + if (!gspca_dev->sd_desc->set_jcomp) + return -EINVAL; + ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); + mutex_unlock(&gspca_dev->usb_lock); + return ret; +} + +static int vidioc_g_parm(struct file *filp, void *priv, + struct v4l2_streamparm *parm) +{ + struct gspca_dev *gspca_dev = priv; + + memset(parm, 0, sizeof parm); + parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + parm->parm.capture.readbuffers = gspca_dev->nbufread; + return 0; +} + +static int vidioc_s_parm(struct file *filp, void *priv, + struct v4l2_streamparm *parm) +{ + struct gspca_dev *gspca_dev = priv; + int n; + + mutex_lock_interruptible(&gspca_dev->usb_lock); + n = parm->parm.capture.readbuffers; + if (n == 0 || n > GSPCA_MAX_FRAMES) + parm->parm.capture.readbuffers = gspca_dev->nbufread; + else + gspca_dev->nbufread = n; + mutex_unlock(&gspca_dev->usb_lock); + return 0; +} + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static int vidiocgmbuf(struct file *file, void *priv, + struct video_mbuf *mbuf) +{ + struct gspca_dev *gspca_dev = file->private_data; + int i; + + PDEBUG(D_STREAM, "cgmbuf"); + if (gspca_dev->nframes == 0) { + struct v4l2_requestbuffers rb; + int ret; + + memset(&rb, 0, sizeof rb); + rb.count = 4; + rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + rb.memory = V4L2_MEMORY_MMAP; + ret = vidioc_reqbufs(file, priv, &rb); + if (ret != 0) + return ret; + } + mbuf->frames = gspca_dev->nframes; + mbuf->size = gspca_dev->frsz * gspca_dev->nframes; + for (i = 0; i < mbuf->frames; i++) + mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset; + return 0; +} +#endif + +static int dev_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct gspca_dev *gspca_dev = file->private_data; + struct gspca_frame *frame = 0; + struct page *page; + unsigned long addr, start, size; + int i, ret; +#ifdef CONFIG_VIDEO_V4L1_COMPAT + int compat = 0; +#endif + + start = vma->vm_start; + size = vma->vm_end - vma->vm_start; + PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size); + + ret = mutex_lock_interruptible(&gspca_dev->queue_lock); + if (ret < 0) + return ret; +/* sanity check disconnect, in use, no memory available */ + if (!gspca_dev->present) { + ret = -ENODEV; + goto done; + } + + for (i = 0; i < gspca_dev->nframes; ++i) { + if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) { + PDEBUG(D_STREAM, "mmap bad memory type"); + break; + } + if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT) + == vma->vm_pgoff) { + frame = &gspca_dev->frame[i]; + break; + } + } + if (frame == 0) { + PDEBUG(D_STREAM, "mmap no frame buffer found"); + ret = -EINVAL; + goto done; + } +#ifdef CONFIG_VIDEO_V4L1_COMPAT + if (i == 0 && size == frame->v4l2_buf.length * gspca_dev->nframes) + compat = 1; + else +#endif + if (size != frame->v4l2_buf.length) { + PDEBUG(D_STREAM, "mmap bad size"); + ret = -EINVAL; + goto done; + } + + /* + * - VM_IO marks the area as being a mmaped region for I/O to a + * device. It also prevents the region from being core dumped. + */ + vma->vm_flags |= VM_IO; + + addr = (unsigned long) frame->data; + while (size > 0) { + page = vmalloc_to_page((void *) addr); + ret = vm_insert_page(vma, start, page); + if (ret < 0) + goto done; + start += PAGE_SIZE; + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + vma->vm_ops = &gspca_vm_ops; + vma->vm_private_data = frame; + gspca_vm_open(vma); +#ifdef CONFIG_VIDEO_V4L1_COMPAT + if (compat) { +/*fixme: ugly*/ + for (i = 1; i < gspca_dev->nframes; ++i) + gspca_dev->frame[i].v4l2_buf.flags |= + V4L2_BUF_FLAG_MAPPED; + } +#endif +done: + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +static unsigned int dev_poll(struct file *file, poll_table * wait) +{ + struct gspca_dev *gspca_dev = file->private_data; + int i, ret; + + PDEBUG(D_FRAM, "poll"); + + poll_wait(file, &gspca_dev->wq, wait); + + if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) + return POLLERR; + if (gspca_dev->dev == 0 + || !gspca_dev->streaming) /* if not streaming */ + ret = POLLERR; + else { + i = gspca_dev->fr_o; + i = gspca_dev->fr_queue[i]; + if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) + ret = POLLIN | POLLRDNORM; /* something to read */ + else + ret = 0; + } + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +/* + * wait for a video frame + * + * If a frame is ready, its index is returned. + */ +static int gspca_frame_wait(struct gspca_dev *gspca_dev, + int nonblock_ing) +{ + struct gspca_frame *frame; + int i, j, ret; + + i = gspca_dev->fr_o; + j = gspca_dev->fr_queue[i]; + frame = &gspca_dev->frame[j]; + if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) + goto ok; + if (nonblock_ing) /* no frame yet */ + return -EAGAIN; + + /* wait till a frame is ready */ + for (;;) { + ret = wait_event_interruptible(gspca_dev->wq, + atomic_read(&gspca_dev->nevent) > 0); + if (ret != 0) + return ret; + i = gspca_dev->fr_o; + j = gspca_dev->fr_queue[i]; + frame = &gspca_dev->frame[j]; + if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) + break; + } + +ok: + atomic_dec(&gspca_dev->nevent); + gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; + PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", + gspca_dev->fr_q, + gspca_dev->fr_i, + gspca_dev->fr_o); + return j; +} + +/* + * dequeue a video buffer + * + * If nonblock_ing is false, block until a buffer is available. + */ +static int vidioc_dqbuf(struct file *file, void *priv, + struct v4l2_buffer *v4l2_buf) +{ + struct gspca_dev *gspca_dev = priv; + struct gspca_frame *frame; + int i, ret; + + PDEBUG(D_FRAM, "dqbuf"); + if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE + || (v4l2_buf->memory != V4L2_MEMORY_MMAP + && v4l2_buf->memory != V4L2_MEMORY_USERPTR)) + return -EINVAL; + if (!gspca_dev->streaming) + return -EINVAL; + + /* only one read */ + if (mutex_lock_interruptible(&gspca_dev->read_lock)) + return -ERESTARTSYS; + + ret = gspca_frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); + if (ret < 0) + goto done; + i = ret; /* frame index */ + frame = &gspca_dev->frame[i]; + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; + memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); + PDEBUG(D_FRAM, "dqbuf %d", i); + ret = 0; +done: + mutex_unlock(&gspca_dev->read_lock); + return ret; +} + +/* + * queue a video buffer + * + * Attempting to queue a buffer that has already been + * queued will return -EINVAL. + */ +static int vidioc_qbuf(struct file *file, void *priv, + struct v4l2_buffer *v4l2_buf) +{ + struct gspca_dev *gspca_dev = priv; + struct gspca_frame *frame; + int i, index, ret; + + PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index); + if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + index = v4l2_buf->index; + if ((unsigned) index >= gspca_dev->nframes) { + PDEBUG(D_STREAM, + "qbuf idx %d >= %d", index, gspca_dev->nframes); + return -EINVAL; + } + frame = &gspca_dev->frame[index]; + + if (v4l2_buf->memory != frame->v4l2_buf.memory) { + PDEBUG(D_STREAM, "qbuf bad memory type"); + return -EINVAL; + } + + ret = mutex_lock_interruptible(&gspca_dev->queue_lock); + if (ret < 0) + return ret; + if (frame->v4l2_buf.flags + & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) { + PDEBUG(D_STREAM, "qbuf bad state"); + ret = -EINVAL; + goto out; + } + + frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; + + if (v4l2_buf->memory == V4L2_MEMORY_USERPTR) { + frame->data = frame->data_end = + (unsigned char *) v4l2_buf->m.userptr; + frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; + frame->v4l2_buf.length = v4l2_buf->length; + } + + /* put the buffer in the 'queued' queue */ + i = gspca_dev->fr_q; + gspca_dev->fr_queue[i] = index; + gspca_dev->fr_q = (i + 1) % gspca_dev->nframes; + PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d", + gspca_dev->fr_q, + gspca_dev->fr_i, + gspca_dev->fr_o); + + v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED; + v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE; + ret = 0; +out: + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +static ssize_t dev_read(struct file *file, char __user *data, + size_t count, loff_t *ppos) +{ + struct gspca_dev *gspca_dev = file->private_data; + struct gspca_frame *frame; + struct v4l2_buffer v4l2_buf; + struct timeval timestamp; + int i, ret, ret2; + + PDEBUG(D_FRAM, "read (%p, %d)", data, count); + if (gspca_dev->nframes == 0) { + struct v4l2_requestbuffers rb; + + memset(&rb, 0, sizeof rb); + rb.count = gspca_dev->nbufread; + rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + rb.memory = V4L2_MEMORY_MMAP; + ret = vidioc_reqbufs(file, gspca_dev, &rb); + if (ret != 0) { + PDEBUG(D_STREAM, "read reqbuf err: %d", ret); + return ret; + } + memset(&v4l2_buf, 0, sizeof v4l2_buf); + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buf.memory = V4L2_MEMORY_MMAP; + for (i = 0; i < gspca_dev->nbufread; i++) { + v4l2_buf.index = i; +/*fixme: ugly!*/ + gspca_dev->frame[i].v4l2_buf.flags |= + V4L2_BUF_FLAG_MAPPED; + ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); + if (ret != 0) { + PDEBUG(D_STREAM, "read qbuf err: %d", ret); + return ret; + } + } + } + if (!gspca_dev->streaming) { + ret = vidioc_streamon(file, gspca_dev, + V4L2_BUF_TYPE_VIDEO_CAPTURE); + if (ret != 0) { + PDEBUG(D_STREAM, "read streamon err %d", ret); + return ret; + } + } + + /* get a frame */ + jiffies_to_timeval(get_jiffies_64(), ×tamp); + timestamp.tv_sec--; + for (i = 0; i < 2; i++) { + memset(&v4l2_buf, 0, sizeof v4l2_buf); + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buf.memory = V4L2_MEMORY_MMAP; + ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf); + if (ret != 0) { + PDEBUG(D_STREAM, "read dqbuf err %d", ret); + return ret; + } + + /* if the process slept for more than 1 second, + * get a brand new frame */ + frame = &gspca_dev->frame[v4l2_buf.index]; + if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec) + break; + ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); + if (ret != 0) { + PDEBUG(D_STREAM, "read qbuf err %d", ret); + return ret; + } + } + + /* copy the frame */ + if (count < frame->v4l2_buf.bytesused) { + PDEBUG(D_STREAM, "read bad count: %d < %d", + count, frame->v4l2_buf.bytesused); +/*fixme: special errno?*/ + ret = -EINVAL; + goto out; + } + count = frame->v4l2_buf.bytesused; + ret = copy_to_user(data, frame->data, count); + if (ret != 0) { + PDEBUG(D_ERR|D_STREAM, + "read cp to user lack %d / %d", ret, count); + ret = -EFAULT; + goto out; + } + ret = count; +out: + /* in each case, requeue the buffer */ + ret2 = vidioc_qbuf(file, gspca_dev, &v4l2_buf); + if (ret2 != 0) + return ret2; + return ret; +} + +static void gspca_dev_release(struct video_device *vfd) +{ + /* nothing */ +} + +static struct file_operations dev_fops = { + .owner = THIS_MODULE, + .open = dev_open, + .release = dev_close, + .read = dev_read, + .mmap = dev_mmap, + .ioctl = video_ioctl2, + .llseek = no_llseek, + .poll = dev_poll, +}; + +static struct video_device gspca_template = { + .name = "gspca main driver", + .type = VID_TYPE_CAPTURE, + .fops = &dev_fops, + .release = gspca_dev_release, /* mandatory */ + .minor = -1, + .vidioc_querycap = vidioc_querycap, + .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_qbuf = vidioc_qbuf, + .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, + .vidioc_try_fmt_cap = vidioc_try_fmt_cap, + .vidioc_g_fmt_cap = vidioc_g_fmt_cap, + .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_streamon = vidioc_streamon, + .vidioc_queryctrl = vidioc_queryctrl, + .vidioc_g_ctrl = vidioc_g_ctrl, + .vidioc_s_ctrl = vidioc_s_ctrl, + .vidioc_querymenu = vidioc_querymenu, + .vidioc_enum_input = vidioc_enum_input, + .vidioc_g_input = vidioc_g_input, + .vidioc_s_input = vidioc_s_input, + .vidioc_reqbufs = vidioc_reqbufs, + .vidioc_querybuf = vidioc_querybuf, + .vidioc_streamoff = vidioc_streamoff, + .vidioc_g_jpegcomp = vidioc_g_jpegcomp, + .vidioc_s_jpegcomp = vidioc_s_jpegcomp, + .vidioc_g_parm = vidioc_g_parm, + .vidioc_s_parm = vidioc_s_parm, +#ifdef CONFIG_VIDEO_V4L1_COMPAT + .vidiocgmbuf = vidiocgmbuf, +#endif +}; + +/* + * probe and create a new gspca device + * + * This function must be called by the sub-driver when it is + * called for probing a new device. + */ +int gspca_dev_probe(struct usb_interface *intf, + const struct usb_device_id *id, + const struct sd_desc *sd_desc, + int dev_size) +{ + struct usb_interface_descriptor *interface; + struct gspca_dev *gspca_dev; + struct usb_device *dev = interface_to_usbdev(intf); + int ret; + __u16 vendor; + __u16 product; + + vendor = le16_to_cpu(dev->descriptor.idVendor); + product = le16_to_cpu(dev->descriptor.idProduct); + PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product); + + /* we don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return -ENODEV; + interface = &intf->cur_altsetting->desc; + if (interface->bInterfaceNumber > 0) + return -ENODEV; + + /* create the device */ + if (dev_size < sizeof *gspca_dev) + dev_size = sizeof *gspca_dev; + gspca_dev = kzalloc(dev_size, GFP_KERNEL); + if (gspca_dev == NULL) { + err("couldn't kzalloc gspca struct"); + return -EIO; + } + gspca_dev->dev = dev; + gspca_dev->iface = interface->bInterfaceNumber; + gspca_dev->sd_desc = sd_desc; +/* gspca_dev->users = 0; (done by kzalloc) */ + gspca_dev->nbufread = 2; + + /* configure the subdriver */ + ret = gspca_dev->sd_desc->config(gspca_dev, id); + if (ret < 0) + goto out; + ret = gspca_set_alt0(gspca_dev); + if (ret < 0) + goto out; + gspca_set_default_mode(gspca_dev); + + mutex_init(&gspca_dev->usb_lock); + mutex_init(&gspca_dev->read_lock); + mutex_init(&gspca_dev->queue_lock); + init_waitqueue_head(&gspca_dev->wq); + + /* init video stuff */ + memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); + gspca_dev->vdev.dev = &dev->dev; + ret = video_register_device(&gspca_dev->vdev, + VFL_TYPE_GRABBER, + video_nr); + if (ret < 0) { + err("video_register_device err %d", ret); + goto out; + } + + gspca_dev->present = 1; + usb_set_intfdata(intf, gspca_dev); + PDEBUG(D_PROBE, "probe ok"); + return 0; +out: + kfree(gspca_dev); + return ret; +} +EXPORT_SYMBOL(gspca_dev_probe); + +/* + * USB disconnection + * + * This function must be called by the sub-driver + * when the device disconnects, after the specific resources are freed. + */ +void gspca_disconnect(struct usb_interface *intf) +{ + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + + if (!gspca_dev) + return; + gspca_dev->present = 0; + mutex_lock_interruptible(&gspca_dev->queue_lock); + mutex_lock_interruptible(&gspca_dev->usb_lock); + gspca_kill_transfer(gspca_dev); + mutex_unlock(&gspca_dev->queue_lock); + mutex_unlock(&gspca_dev->usb_lock); + while (gspca_dev->users != 0) { /* wait until fully closed */ + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* wake processes */ + schedule(); + } +/* We don't want people trying to open up the device */ + video_unregister_device(&gspca_dev->vdev); +/* Free the memory */ + kfree(gspca_dev); + PDEBUG(D_PROBE, "disconnect complete"); +} +EXPORT_SYMBOL(gspca_disconnect); + +/* -- module insert / remove -- */ +static int __init gspca_init(void) +{ + info("main v%s registered", version); + return 0; +} +static void __exit gspca_exit(void) +{ + info("main deregistered"); +} + +module_init(gspca_init); +module_exit(gspca_exit); + +module_param_named(debug, gspca_debug, int, 0644); +MODULE_PARM_DESC(debug, + "Debug (bit) 0x01:error 0x02:probe 0x04:config" + " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout"); + +module_param(comp_fac, int, 0644); +MODULE_PARM_DESC(comp_fac, + "Buffer size ratio when compressed in percent"); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h new file mode 100644 index 000000000000..1394ab13f1f4 --- /dev/null +++ b/drivers/media/video/gspca/gspca.h @@ -0,0 +1,178 @@ +#ifndef GSPCAV2_H +#define GSPCAV2_H + +#include +#include +#include +#include +#include +#include +#include + +#ifdef GSPCA_DEBUG +/* GSPCA our debug messages */ +extern int gspca_debug; +#define PDEBUG(level, fmt, args...) \ + do {\ + if (gspca_debug & (level)) \ + printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) +#define D_ERR 0x01 +#define D_PROBE 0x02 +#define D_CONF 0x04 +#define D_STREAM 0x08 +#define D_FRAM 0x10 +#define D_PACK 0x20 +#define D_USBI 0x40 +#define D_USBO 0x80 +#else +#define PDEBUG(level, fmt, args...) +#endif +#undef err +#define err(fmt, args...) \ + do {\ + printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) +#undef info +#define info(fmt, args...) \ + do {\ + printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) +#undef warn +#define warn(fmt, args...) \ + do {\ + printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \ + } while (0) + +#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ +/* ISOC transfers */ +#define NURBS 4 /* number of URBs */ +#define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ +#define ISO_MAX_SIZE 0x10000 /* max size of one URB buffer (64 Kb) */ + +/* device information - set at probe time */ +struct cam_mode { + __u32 pixfmt; + short width; + short height; + short mode; /* subdriver value */ + short reserved; /* subdriver value */ +}; +struct cam { + char *dev_name; + struct cam_mode *cam_mode; /* size nmodes */ + char nmodes; + __u8 epaddr; +}; + +struct gspca_dev; +struct gspca_frame; + +/* subdriver operations */ +typedef int (*cam_op) (struct gspca_dev *); +typedef void (*cam_v_op) (struct gspca_dev *); +typedef int (*cam_cf_op) (struct gspca_dev *, const struct usb_device_id *); +typedef int (*cam_jpg_op) (struct gspca_dev *, + struct v4l2_jpegcompression *); +typedef int (*cam_qmnu_op) (struct gspca_dev *, + struct v4l2_querymenu *); +typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + unsigned char *data, + int len); + +struct ctrl { + struct v4l2_queryctrl qctrl; + int (*set)(struct gspca_dev *, __s32); + int (*get)(struct gspca_dev *, __s32 *); +}; + +/* subdriver description */ +struct sd_desc { +/* information */ + char *name; /* sub-driver name */ +/* controls */ + struct ctrl *ctrls; + int nctrls; +/* operations */ + cam_cf_op config; /* called on probe */ + cam_op open; /* called on open */ + cam_v_op start; /* called on stream on */ + cam_v_op stopN; /* called on stream off - main alt */ + cam_v_op stop0; /* called on stream off - alt 0 */ + cam_v_op close; /* called on close */ + cam_pkt_op pkt_scan; + cam_jpg_op get_jcomp; + cam_jpg_op set_jcomp; + cam_qmnu_op querymenu; +}; + +struct gspca_pktbuf { + char *data; + struct urb *urb; +}; + +/* packet types when moving from iso buf to frame buf */ +#define DISCARD_PACKET 0 +#define FIRST_PACKET 1 +#define INTER_PACKET 2 +#define LAST_PACKET 3 + +struct gspca_frame { + unsigned char *data; /* frame buffer */ + unsigned char *data_end; /* current end of frame while filling */ + int vma_use_count; + struct v4l2_buffer v4l2_buf; +}; + +struct gspca_dev { + struct video_device vdev; /* !! must be the first item */ + struct usb_device *dev; + + struct cam cam; /* device information */ + const struct sd_desc *sd_desc; /* subdriver description */ + + struct gspca_pktbuf pktbuf[NURBS]; + + __u8 *frbuf; /* buffer for nframes */ + struct gspca_frame frame[GSPCA_MAX_FRAMES]; + unsigned int frsz; /* frame size */ + char nframes; /* number of frames */ + char fr_i; /* frame being filled */ + char fr_q; /* next frame to queue */ + char fr_o; /* next frame to dequeue */ + signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */ + char last_packet_type; + + __u8 iface; /* USB interface number */ + __u8 alt; /* USB alternate setting */ + char curr_mode; /* current camera mode */ + __u32 pixfmt; /* current mode parameters */ + short width; + short height; + + atomic_t nevent; /* number of frames done */ + wait_queue_head_t wq; /* wait queue */ + struct mutex usb_lock; /* usb exchange protection */ + struct mutex read_lock; /* read protection */ + struct mutex queue_lock; /* ISOC queue protection */ + __u32 sequence; /* frame sequence number */ + signed char streaming; + char users; /* # open */ + char present; /* device connected */ + char nbufread; /* number of buffers for read() */ +}; + +int gspca_dev_probe(struct usb_interface *intf, + const struct usb_device_id *id, + const struct sd_desc *sd_desc, + int dev_size); +int gspca_dev_init(struct gspca_dev *gspca_dev, + struct usb_interface *intf); +void gspca_disconnect(struct usb_interface *intf); +struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, + int packet_type, + struct gspca_frame *frame, + unsigned char *data, + int len); +#endif /* GSPCAV2_H */ diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h new file mode 100644 index 000000000000..c4087c0ebc46 --- /dev/null +++ b/drivers/media/video/gspca/jpeg.h @@ -0,0 +1,301 @@ +#ifndef JPEG_H +#define JPEG_H 1 +/* + * Insert a JPEG header at start of frame + * + * This module is used by the gspca subdrivers. + * A special case is done for Conexant webcams. + * + * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* start of jpeg frame + quantization table */ +static const unsigned char quant[][0x88] = { +/* index 0 - Q40*/ + { + 0xff, 0xd8, /* jpeg */ + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, /* quantization table part 1 */ + 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50, + 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64, + 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101, + 109, + 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115, + 126, 129, 124, +1, /* quantization table part 2 */ + 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124}, +/* index 1 - Q50 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, + 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51, + 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87, + 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, + 103, 99, +1, + 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99}, +/* index 2 Q60 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32, + 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41, + 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70, + 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79, +1, + 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79}, +/* index 3 - Q70 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24, + 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31, + 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52, + 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59, +1, + 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59}, +/* index 4 - Q80 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16, + 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20, + 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35, + 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40, +1, + 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}, +/* index 5 - Q85 */ + { + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12, + 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15, + 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26, + 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30, +1, + 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, +/* index 6 - 86 */ +{ + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B, + 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A, + 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E, + 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13, + 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18, + 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20, + 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C, +1, + 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07, + 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, + }, +/* index 7 - 88 */ +{ + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A, + 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09, + 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C, + 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10, + 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15, + 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B, + 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18, +1, + 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06, + 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, +}, +/* index 8 - ?? */ +{ + 0xff, 0xd8, + 0xff, 0xdb, 0x00, 0x84, /* DQT */ +0, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05, + 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06, + 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09, + 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B, + 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E, + 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C, +1, + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03, + 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C +} +}; + +/* huffman table + start of SOF0 */ +static unsigned char huffman[] = { + 0xff, 0xc4, 0x01, 0xa2, + 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x01, 0x00, 0x03, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, + 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, + 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, + 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, + 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, + 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, + 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, + 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, + 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, + 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, + 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, + 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, + 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, + 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0x11, 0x00, 0x02, + 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, + 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, + 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, + 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, + 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, + 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, + 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, + 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, + 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, +#ifdef CONEX_CAM +/* the Conexant frames start with SOF0 */ +#else + 0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */ + 0x08, /* data precision */ +#endif +}; + +#ifndef CONEX_CAM +/* variable part: + * 0x01, 0xe0, height + * 0x02, 0x80, width + * 0x03, component number + * 0x01, + * 0x21, samples Y + */ + +/* end of header */ +static unsigned char eoh[] = { + 0x00, /* quant Y */ + 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ + 0x03, 0x11, 0x01, + + 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan */ + 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 +}; +#endif + +/* -- output the JPEG header -- */ +static void jpeg_put_header(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + int qindex, + int samplesY) +{ +#ifndef CONEX_CAM + unsigned char tmpbuf[8]; +#endif + + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + (unsigned char *) quant[qindex], sizeof quant[0]); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + (unsigned char *) huffman, sizeof huffman); +#ifndef CONEX_CAM + tmpbuf[0] = gspca_dev->height >> 8; + tmpbuf[1] = gspca_dev->height & 0xff; + tmpbuf[2] = gspca_dev->width >> 8; + tmpbuf[3] = gspca_dev->width & 0xff; + tmpbuf[4] = 0x03; /* component number */ + tmpbuf[5] = 0x01; /* first component */ + tmpbuf[6] = samplesY; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, 7); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + eoh, sizeof eoh); +#endif +} +#endif diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c new file mode 100644 index 000000000000..8fd4ff01362e --- /dev/null +++ b/drivers/media/video/gspca/stk014.c @@ -0,0 +1,562 @@ +/* + * Syntek DV4000 (STK014) subdriver + * + * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "stk014" + +#include "gspca.h" +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 22) +static const char version[] = "0.0.22"; + +MODULE_AUTHOR("Jean-Francois Moine "); +MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; +}; + +/* global parameters */ +static int lightfreq = 50; +static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240}, + {V4L2_PIX_FMT_JPEG, 640, 480}, +}; + +/* -- read a register -- */ +static int reg_read(struct gspca_dev *gspca_dev, + __u16 index, __u8 *buf) +{ + int ret; + struct usb_device *dev = gspca_dev->dev; + + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + 0x00, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x00, + index, + buf, 1, + 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_read err %d", ret); + return ret; +} + +/* -- write a register -- */ +static int reg_write(struct gspca_dev *gspca_dev, + __u16 index, __u16 value) +{ + struct usb_device *dev = gspca_dev->dev; + int ret; + + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0x01, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + index, + NULL, + 0, + 500); + if (ret < 0) + PDEBUG(D_ERR, "reg_write err %d", ret); + return ret; +} + +/* -- get a value -- */ +static int rcv_val(struct gspca_dev *gspca_dev, + int ads, + int len) +{ + struct usb_device *dev = gspca_dev->dev; + int alen, ret; + unsigned char bulk_buf[4]; + + reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff); + reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff); + reg_write(gspca_dev, 0x636, ads & 0xff); + reg_write(gspca_dev, 0x637, 0); + reg_write(gspca_dev, 0x638, len & 0xff); + reg_write(gspca_dev, 0x639, len >> 8); + reg_write(gspca_dev, 0x63a, 0); + reg_write(gspca_dev, 0x63b, 0); + reg_write(gspca_dev, 0x630, 5); + if (len > sizeof bulk_buf) + return -1; + ret = usb_bulk_msg(dev, + usb_rcvbulkpipe(dev, 5), + bulk_buf, + len, + &alen, + 500); /* timeout in milliseconds */ + return ret; +} + +/* -- send a value -- */ +static int snd_val(struct gspca_dev *gspca_dev, + int ads, + unsigned int val) +{ + struct usb_device *dev = gspca_dev->dev; + int alen, ret; + __u8 value, seq; + unsigned char bulk_buf[4]; + + if (ads == 0x003f08) { + ret = reg_read(gspca_dev, 0x0704, &value); + if (ret < 0) + goto ko; + ret = reg_read(gspca_dev, 0x0705, &seq); + if (ret < 0) + goto ko; + ret = reg_read(gspca_dev, 0x0650, &value); + if (ret < 0) + goto ko; + reg_write(gspca_dev, 0x654, seq); + } else + reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff); + reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff); + reg_write(gspca_dev, 0x656, ads & 0xff); + reg_write(gspca_dev, 0x657, 0); + reg_write(gspca_dev, 0x658, 0x04); /* size */ + reg_write(gspca_dev, 0x659, 0); + reg_write(gspca_dev, 0x65a, 0); + reg_write(gspca_dev, 0x65b, 0); + reg_write(gspca_dev, 0x650, 5); + bulk_buf[0] = (val >> 24) & 0xff; + bulk_buf[1] = (val >> 16) & 0xff; + bulk_buf[2] = (val >> 8) & 0xff; + bulk_buf[3] = val & 0xff; + ret = usb_bulk_msg(dev, + usb_sndbulkpipe(dev, 6), + bulk_buf, + 4, + &alen, + 500); /* timeout in milliseconds */ + if (ret < 0) + goto ko; + if (ads == 0x003f08) { + seq += 4; + seq &= 0x3f; + reg_write(gspca_dev, 0x705, seq); + } + return ret; +ko: + PDEBUG(D_ERR, "snd_val err %d", ret); + return ret; +} + +/* set a camera parameter */ +static int set_par(struct gspca_dev *gspca_dev, + int parval) +{ + return snd_val(gspca_dev, 0x003f08, parval); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int parval; + + PDEBUG(D_CONF, "brightness: %d", sd->brightness); + parval = 0x06000000 /* whiteness */ + + (sd->brightness << 16); + set_par(gspca_dev, parval); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int parval; + + PDEBUG(D_CONF, "contrast: %d", sd->contrast); + parval = 0x07000000 /* contrast */ + + (sd->contrast << 16); + set_par(gspca_dev, parval); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int parval; + + PDEBUG(D_CONF, "saturation: %d", + sd->colors); + parval = 0x08000000 /* saturation */ + + (sd->colors << 16); + set_par(gspca_dev, parval); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam = &gspca_dev->cam; + + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x02; + gspca_dev->cam.cam_mode = vga_mode; + gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + __u8 value; + int ret; + + /* check if the device responds */ + usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); + ret = reg_read(gspca_dev, 0x0740, &value); + if (ret < 0) + return ret; + if (value != 0xff) { + PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value); + return -1; + } + return 0; +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + __u8 dum; + int ret, value; + + /* work on alternate 1 */ + usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); + + set_par(gspca_dev, 0x10000000); + set_par(gspca_dev, 0x00000000); + set_par(gspca_dev, 0x8002e001); + set_par(gspca_dev, 0x14000000); + if (gspca_dev->width > 320) + value = 0x8002e001; /* 640x480 */ + else + value = 0x4001f000; /* 320x240 */ + set_par(gspca_dev, value); + ret = usb_set_interface(gspca_dev->dev, + gspca_dev->iface, + gspca_dev->alt); + if (ret < 0) + goto out; + ret = reg_read(gspca_dev, 0x0630, &dum); + if (ret < 0) + goto out; + rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ + ret = reg_read(gspca_dev, 0x0650, &dum); + if (ret < 0) + goto out; + snd_val(gspca_dev, 0x000020, 0xffffffff); + reg_write(gspca_dev, 0x0620, 0); + reg_write(gspca_dev, 0x0630, 0); + reg_write(gspca_dev, 0x0640, 0); + reg_write(gspca_dev, 0x0650, 0); + reg_write(gspca_dev, 0x0660, 0); + setbrightness(gspca_dev); /* whiteness */ + setcontrast(gspca_dev); /* contrast */ + setcolors(gspca_dev); /* saturation */ + set_par(gspca_dev, 0x09800000); /* Red ? */ + set_par(gspca_dev, 0x0a800000); /* Green ? */ + set_par(gspca_dev, 0x0b800000); /* Blue ? */ + set_par(gspca_dev, 0x0d030000); /* Gamma ? */ + set_par(gspca_dev, lightfreq == 60 + ? 0x33780000 /* 60 Hz */ + : 0x33640000); /* 50 Hz */ + + /* start the video flow */ + set_par(gspca_dev, 0x01000000); + set_par(gspca_dev, 0x01000000); + PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); + return; +out: + PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 value; + + set_par(gspca_dev, 0x02000000); + set_par(gspca_dev, 0x02000000); + usb_set_interface(dev, gspca_dev->iface, 1); + reg_read(gspca_dev, 0x0630, &value); + rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ + reg_read(gspca_dev, 0x0650, &value); + snd_val(gspca_dev, 0x000020, 0xffffffff); + reg_write(gspca_dev, 0x0620, 0); + reg_write(gspca_dev, 0x0630, 0); + reg_write(gspca_dev, 0x0640, 0); + reg_write(gspca_dev, 0x0650, 0); + reg_write(gspca_dev, 0x0660, 0); + PDEBUG(D_STREAM, "camera stopped"); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + int l; + + /* a frame starts with: + * - 0xff 0xfe + * - 0x08 0x00 // length (little endian ?!) + * - 4 bytes = size of whole frame (big endian - including header) + * - 0x00 0x0c + * - 0xff 0xd8 + * - .. JPEG image with escape sequences (ff 00) + */ + if (data[0] == 0xff && data[1] == 0xfe) { + if (gspca_dev->last_packet_type == INTER_PACKET) { + PDEBUG(D_ERR|D_FRAM, "sof actual l: %d init l: %d", + frame->data_end - frame->data, + frame->v4l2_buf.bytesused); + } + + /* put the JPEG headaer */ + jpeg_put_header(gspca_dev, frame, sd_quant, 0x22); + + /* beginning of the frame */ +#define STKHDRSZ 12 + l = (data[4] << 24) /* frame size */ + + (data[5] << 16) + + (data[6] << 8) + + data[7] + - STKHDRSZ + + (frame->data_end - frame->data) + + 2; /* EOF (ff d9) */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data + STKHDRSZ, len - STKHDRSZ); +#undef STKHDRSZ + frame->v4l2_buf.bytesused = l; + return; + } + if (gspca_dev->last_packet_type != INTER_PACKET) { + if (gspca_dev->last_packet_type == LAST_PACKET) { + PDEBUG(D_ERR|D_PACK, "mof actual l: %d init l: %d", + frame->data_end - frame->data, + frame->v4l2_buf.bytesused); + } + return; + } + + /* intermediate packet */ + l = frame->data_end - frame->data; + if (len < frame->v4l2_buf.bytesused - 2 - l) { + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data, len); + return; + } + + /* last packet */ + if (len > frame->v4l2_buf.bytesused - 2 - l) + len = frame->v4l2_buf.bytesused - 2 - l; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + gspca_frame_add(gspca_dev, LAST_PACKET, frame, "\xff\xd9", 2); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + PDEBUG(D_PROBE, "camera probe"); + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd)); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + info("v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + info("deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); + +module_param(lightfreq, int, 0644); +MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz"); +module_param_named(quant, sd_quant, int, 0644); +MODULE_PARM_DESC(quant, "Quantization index (0..8)"); -- cgit v1.2.3 From e2997a72ddfafc25bd0c8f1f52bcf41979d5a559 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Apr 2008 08:09:12 -0300 Subject: V4L/DVB (8153): Subdriver pac207 added and minor changes. pac207 added. Check status on mutex lock. Call back on frame dequeue. Free the resources on last close only. Avoid URB and ISOC errors on close. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/Makefile | 3 +- drivers/media/video/gspca/gspca.c | 121 +++-- drivers/media/video/gspca/gspca.h | 17 +- drivers/media/video/gspca/pac207.c | 939 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1018 insertions(+), 62 deletions(-) create mode 100644 drivers/media/video/gspca/pac207.c (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index 885d4454d8e5..81170c19ba47 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -1,4 +1,5 @@ -obj-$(CONFIG_GSPCA) += gspca_main.o gspca_stk014.o +obj-$(CONFIG_GSPCA) += gspca_main.o gspca_pac207.o gspca_stk014.o gspca_main-objs := gspca.o +gspca_pac207-objs := pac207.o gspca_stk014-objs := stk014.o diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 4fe082ff7074..c4735e133611 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -39,8 +39,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 26) -static const char version[] = "0.0.26"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30) +static const char version[] = "0.0.30"; static int video_nr = -1; @@ -172,8 +172,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, { int i, j; - PDEBUG(D_PACK, "add t:%d l:%d %02x %02x %02x %02x...", - packet_type, len, data[0], data[1], data[2], data[3]); + PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len); /* when start of a new frame, if the current frame buffer * is not queued, discard the whole frame */ @@ -346,7 +345,6 @@ static int gspca_kill_transfer(struct gspca_dev *gspca_dev) unsigned int i; PDEBUG(D_STREAM, "kill transfer"); - gspca_dev->streaming = 0; for (i = 0; i < NURBS; ++i) { urb = gspca_dev->pktbuf[i].urb; if (urb == NULL) @@ -501,9 +499,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) struct usb_host_endpoint *ep; int n, ret; - ret = mutex_lock_interruptible(&gspca_dev->usb_lock); - if (ret < 0) - return ret; + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; /* set the max alternate setting and loop until urb submit succeeds */ intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); @@ -531,6 +528,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) if (ret < 0) { PDEBUG(D_ERR|D_STREAM, "usb_submit_urb [%d] err %d", n, ret); + gspca_dev->streaming = 0; gspca_kill_transfer(gspca_dev); if (ret == -ENOSPC) break; /* try the previous alt */ @@ -555,9 +553,9 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) return ret; } +/* Note both the queue and the usb lock should be hold when calling this */ static void gspca_stream_off(struct gspca_dev *gspca_dev) { - mutex_lock_interruptible(&gspca_dev->usb_lock); gspca_dev->streaming = 0; if (gspca_dev->present) { gspca_dev->sd_desc->stopN(gspca_dev); @@ -571,7 +569,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) wake_up_interruptible(&gspca_dev->wq); PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); } - mutex_unlock(&gspca_dev->usb_lock); } static int gspca_set_default_mode(struct gspca_dev *gspca_dev) @@ -791,9 +788,7 @@ static int vidioc_try_fmt_cap(struct file *file, { int ret; -/* mutex_lock_interruptible(&gspca_dev->queue_lock); */ ret = try_fmt_cap(file, priv, fmt); -/* mutex_unlock(&gspca_dev->queue_lock); */ if (ret < 0) return ret; return 0; @@ -812,7 +807,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, fmt->fmt.pix.width, fmt->fmt.pix.height); } #endif - mutex_lock_interruptible(&gspca_dev->queue_lock); + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; ret = try_fmt_cap(file, priv, fmt); if (ret < 0) goto out; @@ -820,8 +816,14 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, if (ret == gspca_dev->curr_mode) goto out; /* same mode */ was_streaming = gspca_dev->streaming; - if (was_streaming != 0) + if (was_streaming != 0) { + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { + ret = -ERESTARTSYS; + goto out; + } gspca_stream_off(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + } gspca_dev->width = (int) fmt->fmt.pix.width; gspca_dev->height = (int) fmt->fmt.pix.height; gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; @@ -840,9 +842,8 @@ static int dev_open(struct inode *inode, struct file *file) PDEBUG(D_STREAM, "opening"); gspca_dev = (struct gspca_dev *) video_devdata(file); - ret = mutex_lock_interruptible(&gspca_dev->queue_lock); - if (ret < 0) - return ret; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; if (!gspca_dev->present) { ret = -ENODEV; goto out; @@ -850,16 +851,17 @@ static int dev_open(struct inode *inode, struct file *file) /* if not done yet, initialize the sensor */ if (gspca_dev->users == 0) { - ret = mutex_lock_interruptible(&gspca_dev->usb_lock); - if (ret < 0) + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { + ret = -ERESTARTSYS; goto out; + } ret = gspca_dev->sd_desc->open(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); if (ret != 0) { PDEBUG(D_ERR|D_CONF, "init device failed %d", ret); goto out; } - } else if (gspca_dev->users > 8) { /* (arbitrary value) */ + } else if (gspca_dev->users > 4) { /* (arbitrary value) */ ret = -EBUSY; goto out; } @@ -886,21 +888,20 @@ static int dev_close(struct inode *inode, struct file *file) struct gspca_dev *gspca_dev = file->private_data; PDEBUG(D_STREAM, "closing"); - if (gspca_dev->streaming) { - mutex_lock_interruptible(&gspca_dev->queue_lock); - gspca_stream_off(gspca_dev); + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + gspca_dev->users--; + if (gspca_dev->users > 0) { mutex_unlock(&gspca_dev->queue_lock); + return 0; } - mutex_lock_interruptible(&gspca_dev->usb_lock); + + if (gspca_dev->streaming) + gspca_stream_off(gspca_dev); gspca_dev->sd_desc->close(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - atomic_inc(&gspca_dev->nevent); - wake_up_interruptible(&gspca_dev->wq); /* wake blocked processes */ - schedule(); - mutex_lock_interruptible(&gspca_dev->queue_lock); + frame_free(gspca_dev); file->private_data = NULL; - gspca_dev->users--; mutex_unlock(&gspca_dev->queue_lock); PDEBUG(D_STREAM, "closed"); return 0; @@ -964,7 +965,8 @@ static int vidioc_s_ctrl(struct file *file, void *priv, && ctrl->value > ctrls->qctrl.maximum) return -ERANGE; PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value); - mutex_lock_interruptible(&gspca_dev->usb_lock); + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; ret = ctrls->set(gspca_dev, ctrl->value); mutex_unlock(&gspca_dev->usb_lock); return ret; @@ -985,7 +987,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, i++, ctrls++) { if (ctrl->id != ctrls->qctrl.id) continue; - mutex_lock_interruptible(&gspca_dev->usb_lock); + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; ret = ctrls->get(gspca_dev, &ctrl->value); mutex_unlock(&gspca_dev->usb_lock); return ret; @@ -1047,9 +1050,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, frsz = gspca_get_buff_size(gspca_dev); if (frsz < 0) return frsz; - ret = mutex_lock_interruptible(&gspca_dev->queue_lock); - if (ret < 0) - return ret; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; ret = frame_alloc(gspca_dev, rb->count, (unsigned int) frsz, @@ -1087,9 +1089,8 @@ static int vidioc_streamon(struct file *file, void *priv, PDEBUG(D_STREAM, "stream on"); if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - ret = mutex_lock_interruptible(&gspca_dev->queue_lock); - if (ret < 0) - return ret; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; if (!gspca_dev->present) { ret = -ENODEV; goto out; @@ -1111,6 +1112,7 @@ static int vidioc_streamon(struct file *file, void *priv, gspca_dev->height); } #endif + ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); return ret; @@ -1125,8 +1127,14 @@ static int vidioc_streamoff(struct file *file, void *priv, if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (gspca_dev->streaming) { - mutex_lock_interruptible(&gspca_dev->queue_lock); + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { + mutex_unlock(&gspca_dev->queue_lock); + return -ERESTARTSYS; + } gspca_stream_off(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); mutex_unlock(&gspca_dev->queue_lock); } return 0; @@ -1140,7 +1148,8 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv, if (!gspca_dev->sd_desc->get_jcomp) return -EINVAL; - mutex_lock_interruptible(&gspca_dev->usb_lock); + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp); mutex_unlock(&gspca_dev->usb_lock); return ret; @@ -1152,7 +1161,8 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int ret; - mutex_lock_interruptible(&gspca_dev->usb_lock); + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; if (!gspca_dev->sd_desc->set_jcomp) return -EINVAL; ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp); @@ -1177,7 +1187,8 @@ static int vidioc_s_parm(struct file *filp, void *priv, struct gspca_dev *gspca_dev = priv; int n; - mutex_lock_interruptible(&gspca_dev->usb_lock); + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) + return -ERESTARTSYS; n = parm->parm.capture.readbuffers; if (n == 0 || n > GSPCA_MAX_FRAMES) parm->parm.capture.readbuffers = gspca_dev->nbufread; @@ -1230,10 +1241,8 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) size = vma->vm_end - vma->vm_start; PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size); - ret = mutex_lock_interruptible(&gspca_dev->queue_lock); - if (ret < 0) - return ret; -/* sanity check disconnect, in use, no memory available */ + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; if (!gspca_dev->present) { ret = -ENODEV; goto done; @@ -1294,6 +1303,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) V4L2_BUF_FLAG_MAPPED; } #endif + ret = 0; done: mutex_unlock(&gspca_dev->queue_lock); return ret; @@ -1350,6 +1360,8 @@ static int gspca_frame_wait(struct gspca_dev *gspca_dev, atomic_read(&gspca_dev->nevent) > 0); if (ret != 0) return ret; + if (!gspca_dev->streaming || !gspca_dev->present) + return -EIO; i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; @@ -1364,6 +1376,10 @@ ok: gspca_dev->fr_q, gspca_dev->fr_i, gspca_dev->fr_o); + + if (gspca_dev->sd_desc->dq_callback) + gspca_dev->sd_desc->dq_callback(gspca_dev); + return j; } @@ -1435,9 +1451,9 @@ static int vidioc_qbuf(struct file *file, void *priv, return -EINVAL; } - ret = mutex_lock_interruptible(&gspca_dev->queue_lock); - if (ret < 0) - return ret; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + if (frame->v4l2_buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) { PDEBUG(D_STREAM, "qbuf bad state"); @@ -1708,11 +1724,12 @@ void gspca_disconnect(struct usb_interface *intf) if (!gspca_dev) return; gspca_dev->present = 0; - mutex_lock_interruptible(&gspca_dev->queue_lock); - mutex_lock_interruptible(&gspca_dev->usb_lock); + mutex_lock(&gspca_dev->queue_lock); + mutex_lock(&gspca_dev->usb_lock); + gspca_dev->streaming = 0; gspca_kill_transfer(gspca_dev); - mutex_unlock(&gspca_dev->queue_lock); mutex_unlock(&gspca_dev->usb_lock); + mutex_unlock(&gspca_dev->queue_lock); while (gspca_dev->users != 0) { /* wait until fully closed */ atomic_inc(&gspca_dev->nevent); wake_up_interruptible(&gspca_dev->wq); /* wake processes */ diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 1394ab13f1f4..3bfb3641cf36 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -90,17 +90,18 @@ struct ctrl { /* subdriver description */ struct sd_desc { /* information */ - char *name; /* sub-driver name */ + char *name; /* sub-driver name */ /* controls */ struct ctrl *ctrls; int nctrls; /* operations */ - cam_cf_op config; /* called on probe */ - cam_op open; /* called on open */ - cam_v_op start; /* called on stream on */ - cam_v_op stopN; /* called on stream off - main alt */ - cam_v_op stop0; /* called on stream off - alt 0 */ - cam_v_op close; /* called on close */ + cam_cf_op config; /* called on probe */ + cam_op open; /* called on open */ + cam_v_op start; /* called on stream on */ + cam_v_op stopN; /* called on stream off - main alt */ + cam_v_op stop0; /* called on stream off - alt 0 */ + cam_v_op close; /* called on close */ + cam_v_op dq_callback; /* called when a frame has been dequeued */ cam_pkt_op pkt_scan; cam_jpg_op get_jcomp; cam_jpg_op set_jcomp; @@ -167,8 +168,6 @@ int gspca_dev_probe(struct usb_interface *intf, const struct usb_device_id *id, const struct sd_desc *sd_desc, int dev_size); -int gspca_dev_init(struct gspca_dev *gspca_dev, - struct usb_interface *intf); void gspca_disconnect(struct usb_interface *intf); struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c new file mode 100644 index 000000000000..ac16c7352892 --- /dev/null +++ b/drivers/media/video/gspca/pac207.c @@ -0,0 +1,939 @@ +/* + * Pixart PAC207BCA library + * + * Copyright (C) 2008 Hans de Goede + * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li + * Copyleft (C) 2005 Michel Xhaard mxhaard@magic.fr + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "pac207" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30) +static const char version[] = "0.0.30"; + +MODULE_AUTHOR("Hans de Goede "); +MODULE_DESCRIPTION("Pixart PAC207"); +MODULE_LICENSE("GPL"); + +#define PAC207_CTRL_TIMEOUT 100 /* ms */ + +#define PAC207_BRIGHTNESS_MIN 0 +#define PAC207_BRIGHTNESS_MAX 255 +#define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */ + +#define PAC207_EXPOSURE_MIN 4 +#define PAC207_EXPOSURE_MAX 26 +#define PAC207_EXPOSURE_DEFAULT 4 /* power on default: 3 ?? */ +#define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */ + +#define PAC207_GAIN_MIN 0 +#define PAC207_GAIN_MAX 31 +#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */ +#define PAC207_GAIN_KNEE 20 + +#define PAC207_AUTOGAIN_DEADZONE 30 +/* We calculating the autogain at the end of the transfer of a frame, at this + moment a frame with the old settings is being transmitted, and a frame is + being captured with the old settings. So if we adjust the autogain we must + ignore atleast the 2 next frames for the new settings to come into effect + before doing any other adjustments */ +#define PAC207_AUTOGAIN_IGNORE_FRAMES 3 + +enum pac207_line_state { + LINE_HEADER1, + LINE_HEADER2, + LINE_UNCOMPRESSED, + LINE_COMPRESSED, +}; + +struct pac207_decoder_state { + /* generic state */ + u16 line_read; + u16 line_marker; + u8 line_state; + u8 header_read; + /* compression state */ + u16 processed_bytes; + u8 remaining_bits; + s8 no_remaining_bits; + u8 get_abs; + u8 discard_byte; + u8 line_decode_buf[352]; +}; + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + struct pac207_decoder_state decoder_state; + + u8 mode; + + u8 brightness; + u8 exposure; + u8 autogain; + u8 gain; + + u8 sof_read; + u8 autogain_ignore_frames; + + atomic_t avg_lum; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = PAC207_BRIGHTNESS_MIN, + .maximum = PAC207_BRIGHTNESS_MAX, + .step = 1, + .default_value = PAC207_BRIGHTNESS_DEFAULT, + .flags = 0, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_EXPOSURE 1 + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "exposure", + .minimum = PAC207_EXPOSURE_MIN, + .maximum = PAC207_EXPOSURE_MAX, + .step = 1, + .default_value = PAC207_EXPOSURE_DEFAULT, + .flags = 0, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, +#define SD_AUTOGAIN 2 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +#define SD_GAIN 3 + { + { + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "gain", + .minimum = PAC207_GAIN_MIN, + .maximum = PAC207_GAIN_MAX, + .step = 1, + .default_value = PAC207_GAIN_DEFAULT, + .flags = 0, + }, + .set = sd_setgain, + .get = sd_getgain, + }, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, + {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, +}; + +static const __u8 pac207_sensor_init[][8] = { + {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0}, + {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30}, + {0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00}, + {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02}, + {0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00}, +}; + + /* 48 reg_72 Rate Control end BalSize_4a =0x36 */ +static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; + +static const char pac207_sof_marker[5] = { 0xff, 0xff, 0x00, 0xff, 0x96 }; + +int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, + const u8 *buffer, u16 length) +{ + struct usb_device *udev = gspca_dev->dev; + int err; + u8 kbuf[8]; + + memcpy(kbuf, buffer, length); + + err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0x00, index, kbuf, length, PAC207_CTRL_TIMEOUT); + if (err < 0) + PDEBUG(D_ERR, + "Failed to write registers to index 0x%04X, error %d)", + index, err); + + return err; +} + + +int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) +{ + struct usb_device *udev = gspca_dev->dev; + int err; + + err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, index, NULL, 0, PAC207_CTRL_TIMEOUT); + if (err) + PDEBUG(D_ERR, "Failed to write a register (index 0x%04X," + " value 0x%02X, error %d)", index, value, err); + + return err; +} + + +int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) +{ + struct usb_device *udev = gspca_dev->dev; + u8 buff; + int res; + + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0x00, index, &buff, 1, PAC207_CTRL_TIMEOUT); + if (res < 0) { + PDEBUG(D_ERR, + "Failed to read a register (index 0x%04X, error %d)", + index, res); + return res; + } + + return buff; +} + + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam; + u8 idreg[2]; + + idreg[0] = pac207_read_reg(gspca_dev, 0x0000); + idreg[1] = pac207_read_reg(gspca_dev, 0x0001); + idreg[0] = ((idreg[0] & 0x0F) << 4) | ((idreg[1] & 0xf0) >> 4); + idreg[1] = idreg[1] & 0x0f; + PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X", + idreg[0], idreg[1]); + + if (idreg[0] != 0x27) { + PDEBUG(D_PROBE, "Error invalid sensor ID!"); + return -ENODEV; + } + + pac207_write_reg(gspca_dev, 0x41, 0x00); + /* Bit_0=Image Format, + * Bit_1=LED, + * Bit_2=Compression test mode enable */ + pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ + pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */ + + PDEBUG(D_PROBE, + "Pixart PAC207BCA Image Processor and Control Chip detected" + " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct); + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x05; + cam->cam_mode = sif_mode; + cam->nmodes = ARRAY_SIZE(sif_mode); + + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = PAC207_BRIGHTNESS_DEFAULT; + sd->exposure = PAC207_EXPOSURE_DEFAULT; + sd->gain = PAC207_GAIN_DEFAULT; + sd->autogain = 1; + + return 0; +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 mode; + + pac207_write_reg(gspca_dev, 0x0f, 0x10); /* Power control (Bit 6-0) */ + pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8); + pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8); + pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8); + pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8); + pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8); + pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4); + + /* Compression Balance */ + if (gspca_dev->width == 176) + pac207_write_reg(gspca_dev, 0x4a, 0xff); + else + pac207_write_reg(gspca_dev, 0x4a, 0x88); + pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */ + pac207_write_reg(gspca_dev, 0x08, sd->brightness); + + /* PGA global gain (Bit 4-0) */ + pac207_write_reg(gspca_dev, 0x0e, sd->gain); + pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */ + + mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */ + if (gspca_dev->width == 176) { /* 176x144 */ + mode |= 0x01; + PDEBUG(D_STREAM, "pac207_start mode 176x144"); + } else/* 352x288 */ + PDEBUG(D_STREAM, "pac207_start mode 352x288"); + pac207_write_reg(gspca_dev, 0x41, mode); + + pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ + pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ + udelay(1000); /* taken from gspca */ + pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ + + sd->sof_read = 0; + sd->autogain_ignore_frames = 0; + atomic_set(&sd->avg_lum, -1); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + pac207_write_reg(gspca_dev, 0x40, 0x00); /* Stop ISO pipe */ + pac207_write_reg(gspca_dev, 0x41, 0x00); /* Turn of LED */ + pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */ +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +/* -- convert pixart frames to Bayer -- */ +/* Sonix decompressor struct B.S.(2004) */ +static struct { + u8 is_abs; + u8 len; + s8 val; +} table[256]; + +void init_pixart_decoder(void) +{ + int i, is_abs, val, len; + + for (i = 0; i < 256; i++) { + is_abs = 0; + val = 0; + len = 0; + if ((i & 0xC0) == 0) { + /* code 00 */ + val = 0; + len = 2; + } else if ((i & 0xC0) == 0x40) { + /* code 01 */ + val = -5; + len = 2; + } else if ((i & 0xC0) == 0x80) { + /* code 10 */ + val = 5; + len = 2; + } else if ((i & 0xF0) == 0xC0) { + /* code 1100 */ + val = -10; + len = 4; + } else if ((i & 0xF0) == 0xD0) { + /* code 1101 */ + val = 10; + len = 4; + } else if ((i & 0xF8) == 0xE0) { + /* code 11100 */ + val = -15; + len = 5; + } else if ((i & 0xF8) == 0xE8) { + /* code 11101 */ + val = 15; + len = 5; + } else if ((i & 0xFC) == 0xF0) { + /* code 111100 */ + val = -20; + len = 6; + } else if ((i & 0xFC) == 0xF4) { + /* code 111101 */ + val = 20; + len = 6; + } else if ((i & 0xF8) == 0xF8) { + /* code 11111xxxxxx */ + is_abs = 1; + val = 0; + len = 5; + } + table[i].is_abs = is_abs; + table[i].val = val; + table[i].len = len; + } +} + +/* auto gain and exposure algorithm based on the knee algorithm described here: + http://ytse.tricolour.net/docs/LowLightOptimization.html */ +static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, steps, desired_avg_lum; + int orig_gain = sd->gain; + int orig_exposure = sd->exposure; + int avg_lum = atomic_read(&sd->avg_lum); + + if (!sd->autogain || avg_lum == -1) + return; + + if (sd->autogain_ignore_frames > 0) { + sd->autogain_ignore_frames--; + return; + } + + /* correct desired lumination for the configured brightness */ + desired_avg_lum = 100 + sd->brightness / 2; + + /* If we are of a multiple of deadzone, do multiple step to reach the + desired lumination fast (with the risc of a slight overshoot) */ + steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE; + + for (i = 0; i < steps; i++) { + if (avg_lum > desired_avg_lum) { + if (sd->gain > PAC207_GAIN_KNEE) { + sd->gain--; + } else if (sd->exposure > PAC207_EXPOSURE_KNEE) { + sd->exposure--; + } else if (sd->gain > PAC207_GAIN_DEFAULT) { + sd->gain--; + } else if (sd->exposure > PAC207_EXPOSURE_MIN) { + sd->exposure--; + } else if (sd->gain > PAC207_GAIN_MIN) { + sd->gain--; + } else + break; + } else { + if (sd->gain < PAC207_GAIN_DEFAULT) { + sd->gain++; + } else if (sd->exposure < PAC207_EXPOSURE_KNEE) { + sd->exposure++; + } else if (sd->gain < PAC207_GAIN_KNEE) { + sd->gain++; + } else if (sd->exposure < PAC207_EXPOSURE_MAX) { + sd->exposure++; + } else if (sd->gain < PAC207_GAIN_MAX) { + sd->gain++; + } else + break; + } + } + + if (sd->exposure != orig_exposure || sd->gain != orig_gain) { + if (sd->exposure != orig_exposure) + pac207_write_reg(gspca_dev, 0x0002, sd->exposure); + if (sd->gain != orig_gain) + pac207_write_reg(gspca_dev, 0x000e, sd->gain); + pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */ + pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ + sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; + } +} + +static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, + unsigned char *m, int len) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + + /* Search for the SOF marker (fixed part) in the header */ + for (i = 0; i < len; i++) { + if (m[i] == pac207_sof_marker[sd->sof_read]) { + sd->sof_read++; + if (sd->sof_read == sizeof(pac207_sof_marker)) { + PDEBUG(D_STREAM, + "SOF found, bytes to analyze: %u." + " Frame starts at byte #%u", + len, i + 1); + sd->sof_read = 0; + return m + i + 1; + } + } else + sd->sof_read = 0; + } + + return NULL; +} + +static int pac207_decompress_row(struct gspca_dev *gspca_dev, + struct gspca_frame *f, unsigned char *cdata, int len) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct pac207_decoder_state *decoder_state = &sd->decoder_state; + unsigned char *outp = decoder_state->line_decode_buf + + decoder_state->line_read; + int val, bitlen, bitpos = -decoder_state->no_remaining_bits; + u8 code; + + /* first two pixels are stored as raw 8-bit */ + while (decoder_state->line_read < 2) { + *outp++ = *cdata++; + decoder_state->line_read++; + len--; + if (len == 0) + return 0; + } + + while (decoder_state->line_read < gspca_dev->width) { + if (bitpos < 0) { + code = decoder_state->remaining_bits << (8 + bitpos) | + cdata[0] >> -bitpos; + } else { + u8 *addr = cdata + bitpos / 8; + code = addr[0] << (bitpos & 7) | + addr[1] >> (8 - (bitpos & 7)); + } + + bitlen = decoder_state->get_abs ? + 6 : table[code].len; + + /* Stop decompressing if we're out of input data */ + if ((bitpos + bitlen) > (len * 8)) + break; + + if (decoder_state->get_abs) { + *outp++ = code & 0xFC; + decoder_state->line_read++; + decoder_state->get_abs = 0; + } else { + if (table[code].is_abs) + decoder_state->get_abs = 1; + else { + /* relative to left pixel */ + val = outp[-2] + + table[code].val; + if (val > 0xff) + val = 0xff; + else if (val < 0) + val = 0; + *outp++ = val; + decoder_state->line_read++; + } + } + bitpos += bitlen; + } + + if (decoder_state->line_read == gspca_dev->width) { + int compressed_line_len; + + gspca_frame_add(gspca_dev, INTER_PACKET, f, + decoder_state->line_decode_buf, + gspca_dev->width); + + /* completely decompressed line, round pos to nearest word */ + compressed_line_len = ((decoder_state->processed_bytes * 8 + + bitpos + 15) / 16) * 2; + + len -= compressed_line_len - decoder_state->processed_bytes; + if (len < 0) { + decoder_state->discard_byte = 1; + len = 0; + } + } else { + decoder_state->processed_bytes += len; + decoder_state->remaining_bits = cdata[bitpos/8]; + decoder_state->no_remaining_bits = (8 - bitpos) & 7; + len = 0; + } + + return len; +} + +static void pac207_decode_line_init(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct pac207_decoder_state *decoder_state = &sd->decoder_state; + + decoder_state->line_read = 0; + decoder_state->line_state = LINE_HEADER1; + decoder_state->processed_bytes = 0; + decoder_state->no_remaining_bits = 0; + decoder_state->get_abs = 0; +} + +static void pac207_decode_frame_init(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct pac207_decoder_state *decoder_state = &sd->decoder_state; + + decoder_state->header_read = 0; + decoder_state->discard_byte = 0; + + pac207_decode_line_init(gspca_dev); +} + +static int pac207_decode_frame_data(struct gspca_dev *gspca_dev, + struct gspca_frame *f, unsigned char *data, int len) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct pac207_decoder_state *decoder_state = &sd->decoder_state; + int needed = 0; + + /* first 11 bytes after sof marker: frame header */ + if (decoder_state->header_read < 11) { + /* get average lumination from frame header (byte 5) */ + if (decoder_state->header_read < 5) { + needed = 5 - decoder_state->header_read; + if (len >= needed) + atomic_set(&sd->avg_lum, data[needed-1]); + } + /* skip the rest of the header */ + needed = 11 - decoder_state->header_read; + if (len <= needed) { + decoder_state->header_read += len; + return 0; + } + data += needed; + len -= needed; + decoder_state->header_read = 11; + } + + while (len) { + if (decoder_state->discard_byte) { + data++; + len--; + decoder_state->discard_byte = 0; + continue; + } + + switch (decoder_state->line_state) { + case LINE_HEADER1: + decoder_state->line_marker = data[0] << 8; + decoder_state->line_state = LINE_HEADER2; + needed = 1; + break; + case LINE_HEADER2: + decoder_state->line_marker |= data[0]; + switch (decoder_state->line_marker) { + case 0x0FF0: + decoder_state->line_state = LINE_UNCOMPRESSED; + break; + case 0x1EE1: + decoder_state->line_state = LINE_COMPRESSED; + break; + default: + PDEBUG(D_STREAM, + "Error unknown line-header %04X", + (int) decoder_state->line_marker); + gspca_dev->last_packet_type = DISCARD_PACKET; + return 0; + } + needed = 1; + break; + case LINE_UNCOMPRESSED: + needed = gspca_dev->width - decoder_state->line_read; + if (needed > len) + needed = len; + gspca_frame_add(gspca_dev, INTER_PACKET, f, data, + needed); + decoder_state->line_read += needed; + break; + case LINE_COMPRESSED: + needed = len - + pac207_decompress_row(gspca_dev, f, data, len); + break; + } + + data += needed; + len -= needed; + + if (decoder_state->line_read == gspca_dev->width) { + if ((f->data_end - f->data) == + (gspca_dev->width * gspca_dev->height)) { + /* eureka we've got a frame */ + return 1; + } + pac207_decode_line_init(gspca_dev); + } + } + + return 0; +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + unsigned char *data, + int len) +{ + unsigned char *sof; + int n; + + sof = pac207_find_sof(gspca_dev, data, len); + + if (sof) { + /* finish decoding current frame */ + if (gspca_dev->last_packet_type == INTER_PACKET) { + n = sof - data; + if (n > sizeof(pac207_sof_marker)) + n -= sizeof(pac207_sof_marker); + else + n = 0; + n = pac207_decode_frame_data(gspca_dev, frame, + data, n); + if (n) + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + NULL, + 0); + else + PDEBUG(D_STREAM, "Incomplete frame"); + } + pac207_decode_frame_init(gspca_dev); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, + 0); + len -= sof - data; + data = sof; + } + + if (gspca_dev->last_packet_type == DISCARD_PACKET) + return; + + n = pac207_decode_frame_data(gspca_dev, frame, data, len); + if (n) + frame = gspca_frame_add(gspca_dev, LAST_PACKET, + frame, NULL, 0); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + pac207_write_reg(gspca_dev, 0x08, sd->brightness); + pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ + pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ +} + +static void setexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + pac207_write_reg(gspca_dev, 0x02, sd->exposure); + pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ + pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ +} + +static void setgain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + pac207_write_reg(gspca_dev, 0x0e, sd->gain); + pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ + pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* don't allow mucking with exposure when using autogain */ + if (sd->autogain) + return -EINVAL; + + sd->exposure = val; + if (gspca_dev->streaming) + setexposure(gspca_dev); + return 0; +} + +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->exposure; + return 0; +} + +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* don't allow mucking with gain when using autogain */ + if (sd->autogain) + return -EINVAL; + + sd->gain = val; + if (gspca_dev->streaming) + setgain(gspca_dev); + return 0; +} + +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gain; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + /* when switching to autogain set defaults to make sure + we are on a valid point of the autogain gain / + exposure knee graph, and give this change time to + take effect before doing autogain. */ + if (sd->autogain) { + sd->exposure = PAC207_EXPOSURE_DEFAULT; + sd->gain = PAC207_GAIN_DEFAULT; + if (gspca_dev->streaming) { + sd->autogain_ignore_frames = + PAC207_AUTOGAIN_IGNORE_FRAMES; + setexposure(gspca_dev); + setgain(gspca_dev); + } + } + + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .dq_callback = pac207_do_auto_gain, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, + {USB_DEVICE(0x093a, 0x2460), DVNM("PAC207 Qtec Webcam 100")}, + {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, + {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")}, + {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")}, + {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")}, + {USB_DEVICE(0x093a, 0x2471), DVNM("PAC207 Genius VideoCam ge111")}, + {USB_DEVICE(0x093a, 0x2472), DVNM("PAC207 Genius VideoCam ge110")}, + {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + PDEBUG(D_PROBE, "camera probe"); + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd)); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + init_pixart_decoder(); + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); -- cgit v1.2.3 From 4aa0d037a6c8e6b37ecfd986a444f83190c32a21 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 4 May 2008 06:46:21 -0300 Subject: V4L/DVB (8154): Fix protection problems in the main driver. - Protect format change when streaming active. - Protect USB exchanges on close. - Set a timeout in frame wait. - Have only one capture file and free the resources when closing this file. - Simplify the URB buffer. - Don't reset the control values at open time in pac207. - Fix compilation warnings of stk014. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 163 ++++++++++++++++++++++--------------- drivers/media/video/gspca/gspca.h | 16 ++-- drivers/media/video/gspca/pac207.c | 11 +-- drivers/media/video/gspca/stk014.c | 7 +- 4 files changed, 113 insertions(+), 84 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index c4735e133611..04dbaba4b78f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -39,8 +39,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30) -static const char version[] = "0.0.30"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 1) +static const char version[] = "0.1.1"; static int video_nr = -1; @@ -346,22 +346,17 @@ static int gspca_kill_transfer(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "kill transfer"); for (i = 0; i < NURBS; ++i) { - urb = gspca_dev->pktbuf[i].urb; + urb = gspca_dev->urb[i]; if (urb == NULL) continue; - gspca_dev->pktbuf[i].urb = NULL; + gspca_dev->urb[i] = NULL; usb_kill_urb(urb); - - /* urb->transfer_buffer_length is not touched by USB core, - * so we can use it here as the buffer length */ - if (gspca_dev->pktbuf[i].data) { + if (urb->transfer_buffer != 0) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, - gspca_dev->pktbuf[i].data, + urb->transfer_buffer, urb->transfer_dma); - gspca_dev->pktbuf[i].data = NULL; - } usb_free_urb(urb); } return 0; @@ -460,25 +455,25 @@ static int create_urbs(struct gspca_dev *gspca_dev, err("usb_alloc_urb failed"); return -ENOMEM; } - gspca_dev->pktbuf[n].data = usb_buffer_alloc(gspca_dev->dev, + urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, bsize, GFP_KERNEL, &urb->transfer_dma); - if (gspca_dev->pktbuf[n].data == NULL) { + if (urb->transfer_buffer == NULL) { usb_free_urb(urb); gspca_kill_transfer(gspca_dev); err("usb_buffer_urb failed"); return -ENOMEM; } - gspca_dev->pktbuf[n].urb = urb; + gspca_dev->urb[n] = urb; urb->dev = gspca_dev->dev; urb->context = gspca_dev; urb->pipe = usb_rcvisocpipe(gspca_dev->dev, ep->desc.bEndpointAddress); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = URB_ISO_ASAP + | URB_NO_TRANSFER_DMA_MAP; urb->interval = ep->desc.bInterval; - urb->transfer_buffer = gspca_dev->pktbuf[n].data; urb->complete = isoc_irq; urb->number_of_packets = npkt; urb->transfer_buffer_length = bsize; @@ -523,8 +518,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) /* submit the URBs */ for (n = 0; n < NURBS; n++) { - ret = usb_submit_urb(gspca_dev->pktbuf[n].urb, - GFP_KERNEL); + ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); if (ret < 0) { PDEBUG(D_ERR|D_STREAM, "usb_submit_urb [%d] err %d", n, ret); @@ -732,15 +726,13 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, return 0; } -static int try_fmt_cap(struct file *file, - void *priv, +static int try_fmt_cap(struct gspca_dev *gspca_dev, struct v4l2_format *fmt) { - struct gspca_dev *gspca_dev = priv; int w, h, mode, mode2, frsz; - w = (int) fmt->fmt.pix.width; - h = (int) fmt->fmt.pix.height; + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; #ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); @@ -786,9 +778,10 @@ static int vidioc_try_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) { + struct gspca_dev *gspca_dev = priv; int ret; - ret = try_fmt_cap(file, priv, fmt); + ret = try_fmt_cap(gspca_dev, fmt); if (ret < 0) return ret; return 0; @@ -809,14 +802,19 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, #endif if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - ret = try_fmt_cap(file, priv, fmt); + ret = try_fmt_cap(gspca_dev, fmt); if (ret < 0) goto out; if (ret == gspca_dev->curr_mode) goto out; /* same mode */ was_streaming = gspca_dev->streaming; - if (was_streaming != 0) { + if (was_streaming) { + if (gspca_dev->capt_file != 0 + && gspca_dev->capt_file != file) { + ret = -EBUSY; + goto out; + } if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { ret = -ERESTARTSYS; goto out; @@ -824,8 +822,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, gspca_stream_off(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); } - gspca_dev->width = (int) fmt->fmt.pix.width; - gspca_dev->height = (int) fmt->fmt.pix.height; + gspca_dev->width = fmt->fmt.pix.width; + gspca_dev->height = fmt->fmt.pix.height; gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; gspca_dev->curr_mode = ret; if (was_streaming) @@ -891,17 +889,18 @@ static int dev_close(struct inode *inode, struct file *file) if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; gspca_dev->users--; - if (gspca_dev->users > 0) { - mutex_unlock(&gspca_dev->queue_lock); - return 0; - } - if (gspca_dev->streaming) - gspca_stream_off(gspca_dev); - gspca_dev->sd_desc->close(gspca_dev); - - frame_free(gspca_dev); - file->private_data = NULL; + /* if the file did capture, free the streaming resources */ + if (gspca_dev->capt_file == file) { + mutex_lock(&gspca_dev->usb_lock); + if (gspca_dev->streaming) + gspca_stream_off(gspca_dev); + gspca_dev->sd_desc->close(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + frame_free(gspca_dev); + file->private_data = NULL; + gspca_dev->capt_file = 0; + } mutex_unlock(&gspca_dev->queue_lock); PDEBUG(D_STREAM, "closed"); return 0; @@ -1052,12 +1051,19 @@ static int vidioc_reqbufs(struct file *file, void *priv, return frsz; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; + if (gspca_dev->capt_file != 0) { /* only one file may do capture */ + ret = -EBUSY; + goto out; + } ret = frame_alloc(gspca_dev, rb->count, (unsigned int) frsz, rb->memory); - if (ret == 0) + if (ret == 0) { rb->count = gspca_dev->nframes; + gspca_dev->capt_file = file; + } +out: mutex_unlock(&gspca_dev->queue_lock); PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count); return ret; @@ -1099,6 +1105,10 @@ static int vidioc_streamon(struct file *file, void *priv, ret = -EINVAL; goto out; } + if (gspca_dev->capt_file != file) { + ret = -EINVAL; + goto out; + } if (!gspca_dev->streaming) { ret = gspca_init_transfer(gspca_dev); if (ret < 0) @@ -1122,22 +1132,30 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = priv; + int ret; PDEBUG(D_STREAM, "stream off"); if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (gspca_dev->streaming) { - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { - mutex_unlock(&gspca_dev->queue_lock); - return -ERESTARTSYS; - } - gspca_stream_off(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); - mutex_unlock(&gspca_dev->queue_lock); + if (!gspca_dev->streaming) + return 0; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { + ret = -ERESTARTSYS; + goto out; } - return 0; + if (gspca_dev->capt_file != file) { + ret = -EINVAL; + goto out2; + } + gspca_stream_off(gspca_dev); + ret = 0; +out2: + mutex_unlock(&gspca_dev->usb_lock); +out: + mutex_unlock(&gspca_dev->queue_lock); + return ret; } static int vidioc_g_jpegcomp(struct file *file, void *priv, @@ -1187,14 +1205,11 @@ static int vidioc_s_parm(struct file *filp, void *priv, struct gspca_dev *gspca_dev = priv; int n; - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) - return -ERESTARTSYS; n = parm->parm.capture.readbuffers; if (n == 0 || n > GSPCA_MAX_FRAMES) parm->parm.capture.readbuffers = gspca_dev->nbufread; else gspca_dev->nbufread = n; - mutex_unlock(&gspca_dev->usb_lock); return 0; } @@ -1245,7 +1260,11 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) return -ERESTARTSYS; if (!gspca_dev->present) { ret = -ENODEV; - goto done; + goto out; + } + if (gspca_dev->capt_file != file) { + ret = -EINVAL; + goto out; } for (i = 0; i < gspca_dev->nframes; ++i) { @@ -1262,7 +1281,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) if (frame == 0) { PDEBUG(D_STREAM, "mmap no frame buffer found"); ret = -EINVAL; - goto done; + goto out; } #ifdef CONFIG_VIDEO_V4L1_COMPAT if (i == 0 && size == frame->v4l2_buf.length * gspca_dev->nframes) @@ -1272,7 +1291,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) if (size != frame->v4l2_buf.length) { PDEBUG(D_STREAM, "mmap bad size"); ret = -EINVAL; - goto done; + goto out; } /* @@ -1286,7 +1305,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) page = vmalloc_to_page((void *) addr); ret = vm_insert_page(vma, start, page); if (ret < 0) - goto done; + goto out; start += PAGE_SIZE; addr += PAGE_SIZE; size -= PAGE_SIZE; @@ -1304,7 +1323,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) } #endif ret = 0; -done: +out: mutex_unlock(&gspca_dev->queue_lock); return ret; } @@ -1356,10 +1375,14 @@ static int gspca_frame_wait(struct gspca_dev *gspca_dev, /* wait till a frame is ready */ for (;;) { - ret = wait_event_interruptible(gspca_dev->wq, - atomic_read(&gspca_dev->nevent) > 0); - if (ret != 0) - return ret; + ret = wait_event_interruptible_timeout(gspca_dev->wq, + atomic_read(&gspca_dev->nevent) > 0, + msecs_to_jiffies(3000)); + if (ret <= 0) { + if (ret < 0) + return ret; + return -EIO; + } if (!gspca_dev->streaming || !gspca_dev->present) return -EIO; i = gspca_dev->fr_o; @@ -1402,6 +1425,10 @@ static int vidioc_dqbuf(struct file *file, void *priv, return -EINVAL; if (!gspca_dev->streaming) return -EINVAL; + if (gspca_dev->capt_file != file) { + ret = -EINVAL; + goto out; + } /* only one read */ if (mutex_lock_interruptible(&gspca_dev->read_lock)) @@ -1409,14 +1436,14 @@ static int vidioc_dqbuf(struct file *file, void *priv, ret = gspca_frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); if (ret < 0) - goto done; + goto out; i = ret; /* frame index */ frame = &gspca_dev->frame[i]; frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); PDEBUG(D_FRAM, "dqbuf %d", i); ret = 0; -done: +out: mutex_unlock(&gspca_dev->read_lock); return ret; } @@ -1450,6 +1477,8 @@ static int vidioc_qbuf(struct file *file, void *priv, PDEBUG(D_STREAM, "qbuf bad memory type"); return -EINVAL; } + if (gspca_dev->capt_file != file) + return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; @@ -1524,7 +1553,9 @@ static ssize_t dev_read(struct file *file, char __user *data, return ret; } } - } + } else if (gspca_dev->capt_file != file) + return -EINVAL; + if (!gspca_dev->streaming) { ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE); @@ -1719,7 +1750,7 @@ EXPORT_SYMBOL(gspca_dev_probe); */ void gspca_disconnect(struct usb_interface *intf) { - struct gspca_dev *gspca_dev = usb_get_intfdata(intf); + struct gspca_dev *gspca_dev = usb_get_intfdata(intf); if (!gspca_dev) return; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 3bfb3641cf36..c2618c0e6615 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -108,11 +108,6 @@ struct sd_desc { cam_qmnu_op querymenu; }; -struct gspca_pktbuf { - char *data; - struct urb *urb; -}; - /* packet types when moving from iso buf to frame buf */ #define DISCARD_PACKET 0 #define FIRST_PACKET 1 @@ -121,19 +116,20 @@ struct gspca_pktbuf { struct gspca_frame { unsigned char *data; /* frame buffer */ - unsigned char *data_end; /* current end of frame while filling */ + unsigned char *data_end; /* end of frame while filling */ int vma_use_count; struct v4l2_buffer v4l2_buf; }; struct gspca_dev { - struct video_device vdev; /* !! must be the first item */ + struct video_device vdev; /* !! must be the first item */ struct usb_device *dev; + struct file *capt_file; /* file doing video capture */ struct cam cam; /* device information */ const struct sd_desc *sd_desc; /* subdriver description */ - struct gspca_pktbuf pktbuf[NURBS]; + struct urb *urb[NURBS]; __u8 *frbuf; /* buffer for nframes */ struct gspca_frame frame[GSPCA_MAX_FRAMES]; @@ -147,7 +143,7 @@ struct gspca_dev { __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ - char curr_mode; /* current camera mode */ + unsigned char curr_mode; /* current camera mode */ __u32 pixfmt; /* current mode parameters */ short width; short height; @@ -158,7 +154,7 @@ struct gspca_dev { struct mutex read_lock; /* read protection */ struct mutex queue_lock; /* ISOC queue protection */ __u32 sequence; /* frame sequence number */ - signed char streaming; + char streaming; char users; /* # open */ char present; /* device connected */ char nbufread; /* number of buffers for read() */ diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index ac16c7352892..57d48f51e3a0 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 30) -static const char version[] = "0.0.30"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 1) +static const char version[] = "0.1.1"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -251,6 +251,7 @@ int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { + struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; u8 idreg[2]; @@ -282,6 +283,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x05; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); + sd->brightness = PAC207_BRIGHTNESS_DEFAULT; + sd->exposure = PAC207_EXPOSURE_DEFAULT; + sd->gain = PAC207_GAIN_DEFAULT; return 0; } @@ -291,9 +295,6 @@ static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - sd->brightness = PAC207_BRIGHTNESS_DEFAULT; - sd->exposure = PAC207_EXPOSURE_DEFAULT; - sd->gain = PAC207_GAIN_DEFAULT; sd->autogain = 1; return 0; diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 8fd4ff01362e..2e4cf64442ac 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 0, 22) -static const char version[] = "0.0.22"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) +static const char version[] = "0.1.0"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -390,6 +390,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int len) /* iso packet length */ { int l; + static unsigned char ffd9[] = {0xff, 0xd9}; /* a frame starts with: * - 0xff 0xfe @@ -445,7 +446,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, if (len > frame->v4l2_buf.bytesused - 2 - l) len = frame->v4l2_buf.bytesused - 2 - l; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); - gspca_frame_add(gspca_dev, LAST_PACKET, frame, "\xff\xd9", 2); + gspca_frame_add(gspca_dev, LAST_PACKET, frame, ffd9, 2); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) -- cgit v1.2.3 From d43fa32fec442571f10f5d0c3b553413288728de Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 12 Jun 2008 10:58:58 -0300 Subject: V4L/DVB (8156): Many bug fixes, zc3xx added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/Makefile | 4 +- drivers/media/video/gspca/gspca.c | 991 +++-- drivers/media/video/gspca/gspca.h | 18 +- drivers/media/video/gspca/jpeg.h | 2 +- drivers/media/video/gspca/pac207.c | 31 +- drivers/media/video/gspca/stk014.c | 55 +- drivers/media/video/gspca/zc3xx.c | 7523 ++++++++++++++++++++++++++++++++++++ 7 files changed, 8336 insertions(+), 288 deletions(-) create mode 100644 drivers/media/video/gspca/zc3xx.c (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index 81170c19ba47..d959f7771526 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -1,5 +1,7 @@ -obj-$(CONFIG_GSPCA) += gspca_main.o gspca_pac207.o gspca_stk014.o +obj-$(CONFIG_GSPCA) += gspca_main.o \ + gspca_pac207.o gspca_stk014.o gspca_zc3xx.o gspca_main-objs := gspca.o gspca_pac207-objs := pac207.o gspca_stk014-objs := stk014.o +gspca_zc3xx-objs := zc3xx.o diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 04dbaba4b78f..423ebbdc4b4f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -35,12 +35,18 @@ #include "gspca.h" +/* option */ +#define GSPCA_HLP 0 + +/* global values */ +#define DEF_NURBS 2 /* default number of URBs (mmap) */ + MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 1) -static const char version[] = "0.1.1"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) +static const char version[] = "0.2.15"; static int video_nr = -1; @@ -71,6 +77,229 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) #define PDEBUG_MODE(txt, pixfmt, w, h) #endif +/* specific memory types - !! should different from V4L2_MEMORY_xxx */ +#define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ +#define GSPCA_MEMORY_READ 7 + +#ifndef GSPCA_HLP +#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) +#else +#define GSPCA_BUF_FLAG_DECODE 0x1000 /* internal buffer flag */ +#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE \ + | GSPCA_BUF_FLAG_DECODE) + +static int autostart = 4; +module_param(autostart, int, 0644); +MODULE_PARM_DESC(autostart, + "Automatically start the helper process"); + +/* try to start the helper process */ +static void start_hlp(void) +{ + int ret; + static char *argv[] = {"gspca_hlp", NULL}; + static char *env[] = {NULL}; + + if (autostart <= 0) { + if (autostart < 0) + PDEBUG(D_ERR|D_PROBE, "Too many helper restart"); + return; + } + autostart--; + if (autostart == 0) + autostart = -1; + ret = call_usermodehelper("/sbin/gspca_hlp", argv, env, + UMH_WAIT_EXEC); + if (ret != 0) + PDEBUG(D_ERR|D_PROBE, + "/sbin/gspca_hlp start failed %d", ret); +} + +/* /dev/gspca_hlp stuff */ +#include +#include "gspca_hlp.h" + +/* !! possible decodings defined in decoder.c */ +static __u32 bayer_to_tb[] = { + V4L2_PIX_FMT_SBGGR8, + V4L2_PIX_FMT_YUYV, + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_RGB24, + V4L2_PIX_FMT_BGR24, + V4L2_PIX_FMT_RGB565, +}; +static __u32 jpeg_to_tb[] = { + V4L2_PIX_FMT_JPEG, + V4L2_PIX_FMT_YUYV, + V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_RGB24, + V4L2_PIX_FMT_BGR24, + V4L2_PIX_FMT_RGB565, +}; + +/* /dev/gspca_hlp device */ +struct hlp_dev { + struct gspca_dev *gspca_dev; /* associated device */ + struct gspca_frame *frame; /* frame being decoded */ + __u32 pixfmt; /* webcam pixel format */ + atomic_t nevent; /* nb of frames ready to decode */ + wait_queue_head_t wq; /* wait queue */ + char fr_d; /* next frame to decode */ +} *hlp; + +static int hlp_open(struct inode *inode, struct file *file) +{ + struct hlp_dev *hlp_dev; + + PDEBUG(D_CONF, "hlp open"); + if (hlp != 0) + return -EBUSY; + hlp_dev = kzalloc(sizeof *hlp_dev, GFP_KERNEL); + if (hlp_dev == NULL) { + err("couldn't kzalloc hlp struct"); + return -EIO; + } + init_waitqueue_head(&hlp_dev->wq); + file->private_data = hlp_dev; + hlp = hlp_dev; + return 0; +} + +static int hlp_close(struct inode *inode, struct file *file) +{ + struct gspca_dev *gspca_dev; + int mode; + + PDEBUG(D_CONF, "hlp close"); + file->private_data = NULL; + + /* stop decoding */ + gspca_dev = hlp->gspca_dev; + if (gspca_dev != 0) { + mode = gspca_dev->curr_mode; + gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; + } + + /* destroy the helper structure */ + kfree(hlp); + hlp = 0; + + /* try to restart the helper process */ + start_hlp(); + return 0; +} + +static ssize_t hlp_read(struct file *file, char __user *buf, + size_t cnt, loff_t *ppos) +{ + struct hlp_dev *hlp_dev = file->private_data; + struct gspca_dev *gspca_dev; + struct gspca_frame *frame; + struct gspca_hlp_read_hd head; + int i, j, len, ret; + + PDEBUG(D_FRAM, "hlp read (%d)", cnt); + + /* check / wait till a frame is ready */ + for (;;) { + gspca_dev = hlp_dev->gspca_dev; + if (gspca_dev != 0 && gspca_dev->streaming) { + i = hlp_dev->fr_d; /* frame to decode */ + j = gspca_dev->fr_queue[i]; + frame = &gspca_dev->frame[j]; + if (frame->v4l2_buf.flags & GSPCA_BUF_FLAG_DECODE) + break; + } + ret = wait_event_interruptible(hlp_dev->wq, + atomic_read(&hlp_dev->nevent) > 0); + if (ret < 0) { /* helper process is killed */ + autostart = 0; /* don't restart it */ + return ret; + } + } + atomic_dec(&hlp_dev->nevent); + hlp_dev->fr_d = (i + 1) % gspca_dev->nframes; + PDEBUG(D_FRAM, "hlp read q:%d i:%d d:%d o:%d", + gspca_dev->fr_q, + gspca_dev->fr_i, + hlp_dev->fr_d, + gspca_dev->fr_o); + + hlp_dev->frame = frame; /* memorize the current frame */ + len = frame->v4l2_buf.bytesused; + if (cnt < sizeof head - sizeof head.data + len) +/*fixme: special errno?*/ + return -EINVAL; + head.pixfmt_out = gspca_dev->pixfmt; + head.pixfmt_in = hlp_dev->pixfmt; + head.width = gspca_dev->width; + head.height = gspca_dev->height; + copy_to_user(buf, &head, sizeof head); + copy_to_user(buf + sizeof head - sizeof head.data, + frame->data, len); + return sizeof head - sizeof head.data + len; +} + +static ssize_t hlp_write(struct file *file, + const char __user *buf, + size_t cnt, loff_t *ppos) +{ + struct hlp_dev *hlp_dev = file->private_data; + struct gspca_dev *gspca_dev; + struct gspca_frame *frame; + + PDEBUG(D_FRAM, "hlp write (%d)", cnt); + gspca_dev = hlp_dev->gspca_dev; + if (gspca_dev == 0) + return cnt; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + if (!gspca_dev->streaming) + goto out; + frame = hlp_dev->frame; + hlp_dev->frame = 0; + if (frame == 0) + goto out; + if (cnt > frame->v4l2_buf.length) { + PDEBUG(D_ERR|D_FRAM, "bad frame size %d - %d", + cnt, frame->v4l2_buf.length); + cnt = -EINVAL; + goto out; + } + copy_from_user(frame->data, buf, cnt); + frame->v4l2_buf.bytesused = cnt; + frame->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_QUEUED + | GSPCA_BUF_FLAG_DECODE); + frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; + mutex_unlock(&gspca_dev->queue_lock); + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ + PDEBUG(D_FRAM, "hlp write q:%d i:%d d:%d o:%d", + gspca_dev->fr_q, + gspca_dev->fr_i, + hlp_dev->fr_d, + gspca_dev->fr_o); + return cnt; +out: + mutex_unlock(&gspca_dev->queue_lock); + return cnt; +} + +static struct file_operations hlp_fops = { + .owner = THIS_MODULE, + .open = hlp_open, + .release = hlp_close, + .read = hlp_read, + .write = hlp_write, + .llseek = no_llseek +}; +static struct miscdevice hlp_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "gspca_hlp", + .fops = &hlp_fops, +}; +#endif + /* * VMA operations. */ @@ -96,22 +325,16 @@ static struct vm_operations_struct gspca_vm_ops = { }; /* - * ISOC message interrupt from the USB device - * - * Analyse each packet and call the subdriver for doing the copy - * to the frame buffer. + * fill a video frame from an URB and resubmit */ -static void isoc_irq(struct urb *urb) +static void fill_frame(struct gspca_dev *gspca_dev, + struct urb *urb) { - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; struct gspca_frame *frame; unsigned char *data; /* address of data in the iso message */ int i, j, len, st; cam_pkt_op pkt_scan; - PDEBUG(D_PACK, "isoc irq"); - if (!gspca_dev->streaming) - return; pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -119,8 +342,7 @@ static void isoc_irq(struct urb *urb) j = gspca_dev->fr_i; j = gspca_dev->fr_queue[j]; frame = &gspca_dev->frame[j]; - if ((frame->v4l2_buf.flags - & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) + if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; break; @@ -147,16 +369,86 @@ static void isoc_irq(struct urb *urb) } /* resubmit the URB */ +/*fixme: don't do that when userptr and too many URBs sent*/ urb->status = 0; st = usb_submit_urb(urb, GFP_ATOMIC); if (st < 0) PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", st); } +/* + * ISOC message interrupt from the USB device + * + * Analyse each packet and call the subdriver for copy + * to the frame buffer. + * + * There are 2 functions: + * - the first one (isoc_irq_mmap) is used when the application + * buffers are mapped. The frame detection and copy is done + * at interrupt level. + * - the second one (isoc_irq_user) is used when the application + * buffers are in user space (userptr). The frame detection + * and copy is done by the application. + */ +static void isoc_irq_mmap(struct urb *urb) +{ + struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; + + PDEBUG(D_PACK, "isoc irq mmap"); + if (!gspca_dev->streaming) + return; + fill_frame(gspca_dev, urb); +} + +static void isoc_irq_user(struct urb *urb) +{ + struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; + int i; + + PDEBUG(D_PACK, "isoc irq user"); + if (!gspca_dev->streaming) + return; + + i = gspca_dev->urb_in % gspca_dev->nurbs; + if (urb != gspca_dev->urb[i]) { + PDEBUG(D_ERR|D_PACK, "urb out of sequence"); + return; /* should never occur */ + } + + gspca_dev->urb_in++; + atomic_inc(&gspca_dev->nevent); /* new event */ + wake_up_interruptible(&gspca_dev->wq); +/*fixme: submit a new URBs until urb_in == urb_out (% nurbs)*/ +} + +/* + * treat the isoc messages + * + * This routine is called by the application (case userptr). + */ +static void isoc_transfer(struct gspca_dev *gspca_dev) +{ + struct urb *urb; + int i; + + for (;;) { + i = gspca_dev->urb_out; + PDEBUG(D_PACK, "isoc transf i:%d o:%d", gspca_dev->urb_in, i); + if (i == gspca_dev->urb_in) /* isoc message to read */ + break; /* no (more) message */ + atomic_dec(&gspca_dev->nevent); +/*PDEBUG(D_PACK, "isoc_trf nevent: %d", atomic_read(&gspca_dev->nevent));*/ + gspca_dev->urb_out = i + 1; /* message treated */ + urb = gspca_dev->urb[i % gspca_dev->nurbs]; + fill_frame(gspca_dev, urb); + } +} + /* * add data to the current frame * - * This function is called by the subdrivers at interrupt level. + * This function is called by the subdrivers at interrupt level + * or user level. * To build a frame, these ones must add * - one FIRST_PACKET * - 0 or many INTER_PACKETs @@ -177,9 +469,8 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, /* when start of a new frame, if the current frame buffer * is not queued, discard the whole frame */ if (packet_type == FIRST_PACKET) { - if ((frame->v4l2_buf.flags - & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) - != V4L2_BUF_FLAG_QUEUED) { + if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS) + != V4L2_BUF_FLAG_QUEUED) { gspca_dev->last_packet_type = DISCARD_PACKET; return frame; } @@ -187,10 +478,11 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, jiffies_to_timeval(get_jiffies_64(), &frame->v4l2_buf.timestamp); frame->v4l2_buf.sequence = ++gspca_dev->sequence; - } else if (gspca_dev->last_packet_type == DISCARD_PACKET) + } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { return frame; + } - /* append the packet in the frame buffer */ + /* append the packet to the frame buffer */ if (len > 0) { if (frame->data_end - frame->data + len > frame->v4l2_buf.length) { @@ -211,12 +503,25 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, /* if last packet, wake the application and advance in the queue */ if (packet_type == LAST_PACKET) { frame->v4l2_buf.bytesused = frame->data_end - frame->data; +#ifndef GSPCA_HLP frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; atomic_inc(&gspca_dev->nevent); wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ - i = gspca_dev->fr_i; - i = (i + 1) % gspca_dev->nframes; +#else /*GSPCA_HLP*/ + if (hlp != 0 && hlp->gspca_dev == gspca_dev) { + frame->v4l2_buf.flags |= GSPCA_BUF_FLAG_DECODE; + atomic_inc(&hlp->nevent); + wake_up_interruptible(&hlp->wq); + } else { + frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; + frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; + atomic_inc(&gspca_dev->nevent); + wake_up_interruptible(&gspca_dev->wq); /* new frame */ + } +#endif /*GSPCA_HLP*/ + i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; + gspca_dev->fr_i = i; PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", frame->v4l2_buf.bytesused, gspca_dev->fr_q, @@ -224,7 +529,6 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, gspca_dev->fr_o); j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; - gspca_dev->fr_i = i; } return frame; } @@ -245,7 +549,7 @@ static void *rvmalloc(unsigned long size) void *mem; unsigned long adr; - size = PAGE_ALIGN(size); +/* size = PAGE_ALIGN(size); (already done) */ mem = vmalloc_32(size); if (mem != 0) { memset(mem, 0, size); @@ -274,27 +578,65 @@ static void rvfree(void *mem, unsigned long size) vfree(mem); } +static __u32 get_v4l2_depth(__u32 pixfmt) +{ + switch (pixfmt) { + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + return 32; + case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ + case V4L2_PIX_FMT_BGR24: + return 24; + case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ + case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ + case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ + return 16; + case V4L2_PIX_FMT_YUV420: /* 'YU12' planar 4.2.0 */ + return 12; + case V4L2_PIX_FMT_MJPEG: + case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ + return 8; + } + PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", + pixfmt & 0xff, + (pixfmt >> 8) & 0xff, + (pixfmt >> 16) & 0xff, + pixfmt >> 24); + return -EINVAL; +} + +static int gspca_get_buff_size(struct gspca_dev *gspca_dev) +{ + unsigned int size; + + size = gspca_dev->width * gspca_dev->height + * get_v4l2_depth(gspca_dev->pixfmt) / 8; + if (!size) + return -ENOMEM; + return size; +} + static int frame_alloc(struct gspca_dev *gspca_dev, - unsigned int count, - unsigned int frsz, - enum v4l2_memory memory) + unsigned int count) { - int i, ret = 0; + struct gspca_frame *frame; + unsigned int frsz; + int i; + frsz = gspca_get_buff_size(gspca_dev); + if (frsz < 0) + return frsz; PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); - if (gspca_dev->nframes != 0) { - PDEBUG(D_ERR|D_STREAM, "alloc frame already done"); - return -EBUSY; - } if (count > GSPCA_MAX_FRAMES) count = GSPCA_MAX_FRAMES; - /* if compressed, reduce the buffer size */ + /* if compressed (JPEG), reduce the buffer size */ if (gspca_is_compressed(gspca_dev->pixfmt)) - frsz = (frsz * comp_fac) / 100; + frsz = (frsz * comp_fac) / 100 + 600; /* plus JPEG header */ frsz = PAGE_ALIGN(frsz); PDEBUG(D_STREAM, "new fr_sz: %d", frsz); gspca_dev->frsz = frsz; - if (memory == V4L2_MEMORY_MMAP) { + if (gspca_dev->memory == V4L2_MEMORY_MMAP) { gspca_dev->frbuf = rvmalloc(frsz * count); if (!gspca_dev->frbuf) { err("frame alloc failed"); @@ -303,25 +645,36 @@ static int frame_alloc(struct gspca_dev *gspca_dev, } gspca_dev->nframes = count; for (i = 0; i < count; i++) { - gspca_dev->frame[i].v4l2_buf.index = i; - gspca_dev->frame[i].v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - gspca_dev->frame[i].v4l2_buf.flags = 0; - gspca_dev->frame[i].v4l2_buf.field = V4L2_FIELD_NONE; - gspca_dev->frame[i].v4l2_buf.length = frsz; - gspca_dev->frame[i].v4l2_buf.memory = memory; - if (memory == V4L2_MEMORY_MMAP) { - gspca_dev->frame[i].data - = gspca_dev->frame[i].data_end - = gspca_dev->frbuf + i * frsz; - gspca_dev->frame[i].v4l2_buf.m.offset = i * frsz; + frame = &gspca_dev->frame[i]; + frame->v4l2_buf.index = i; + frame->v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + frame->v4l2_buf.flags = 0; + frame->v4l2_buf.field = V4L2_FIELD_NONE; + frame->v4l2_buf.length = frsz; + frame->v4l2_buf.memory = gspca_dev->memory; + frame->v4l2_buf.sequence = 0; + if (gspca_dev->memory == V4L2_MEMORY_MMAP) { + frame->data = frame->data_end = + gspca_dev->frbuf + i * frsz; + frame->v4l2_buf.m.offset = i * frsz; } - gspca_dev->frame[i].v4l2_buf.flags = 0; /* buf in app space */ } gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; +#ifdef GSPCA_HLP + { + struct hlp_dev *hlp_dev; + + hlp_dev = hlp; + if (hlp != 0 && hlp_dev->gspca_dev == gspca_dev) { + hlp_dev->fr_d = 0; + atomic_set(&hlp_dev->nevent, 0); + } + } +#endif /*GSPCA_HLP*/ gspca_dev->last_packet_type = DISCARD_PACKET; gspca_dev->sequence = 0; atomic_set(&gspca_dev->nevent, 0); - return ret; + return 0; } static void frame_free(struct gspca_dev *gspca_dev) @@ -339,16 +692,16 @@ static void frame_free(struct gspca_dev *gspca_dev) gspca_dev->nframes = 0; } -static int gspca_kill_transfer(struct gspca_dev *gspca_dev) +static void destroy_urbs(struct gspca_dev *gspca_dev) { struct urb *urb; unsigned int i; PDEBUG(D_STREAM, "kill transfer"); - for (i = 0; i < NURBS; ++i) { + for (i = 0; i < MAX_NURBS; ++i) { urb = gspca_dev->urb[i]; if (urb == NULL) - continue; + break; gspca_dev->urb[i] = NULL; usb_kill_urb(urb); @@ -359,7 +712,6 @@ static int gspca_kill_transfer(struct gspca_dev *gspca_dev) urb->transfer_dma); usb_free_urb(urb); } - return 0; } /* @@ -417,7 +769,7 @@ struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) err("set interface err %d", ret); return NULL; } - gspca_dev->alt = i; + gspca_dev->alt = i; /* memorize the current alt setting */ return ep; } @@ -428,28 +780,28 @@ static int create_urbs(struct gspca_dev *gspca_dev, struct usb_host_endpoint *ep) { struct urb *urb; - int n, i, psize, npkt, bsize; + int n, nurbs, i, psize, npkt, bsize; + usb_complete_t usb_complete; /* calculate the packet size and the number of packets */ - /* the URB buffer size must be a power of 2 */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); + /* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3)); npkt = ISO_MAX_SIZE / psize; if (npkt > ISO_MAX_PKT) npkt = ISO_MAX_PKT; bsize = psize * npkt; - for (n = ISO_MAX_SIZE; n > 0; n >>= 1) { - if (n & bsize) /* !! assume ISO_MAX_SIZE is a power of 2 */ - break; - } - if (n != 0) { - npkt = n / psize; - bsize = psize * npkt; - } PDEBUG(D_STREAM, "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); - for (n = 0; n < NURBS; n++) { +/*fixme:change for userptr*/ +/*fixme:don't submit all URBs when userptr*/ + gspca_dev->nurbs = nurbs = DEF_NURBS; + if (gspca_dev->memory == V4L2_MEMORY_MMAP) + usb_complete = isoc_irq_mmap; + else + usb_complete = isoc_irq_user; + for (n = 0; n < nurbs; n++) { urb = usb_alloc_urb(npkt, GFP_KERNEL); if (!urb) { err("usb_alloc_urb failed"); @@ -462,7 +814,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, if (urb->transfer_buffer == NULL) { usb_free_urb(urb); - gspca_kill_transfer(gspca_dev); + destroy_urbs(gspca_dev); err("usb_buffer_urb failed"); return -ENOMEM; } @@ -474,7 +826,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = ep->desc.bInterval; - urb->complete = isoc_irq; + urb->complete = usb_complete; urb->number_of_packets = npkt; urb->transfer_buffer_length = bsize; for (i = 0; i < npkt; i++) { @@ -482,6 +834,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, urb->iso_frame_desc[i].offset = psize * i; } } + gspca_dev->urb_in = gspca_dev->urb_out = 0; return 0; } @@ -490,18 +843,17 @@ static int create_urbs(struct gspca_dev *gspca_dev, */ static int gspca_init_transfer(struct gspca_dev *gspca_dev) { - struct usb_interface *intf; struct usb_host_endpoint *ep; int n, ret; if (mutex_lock_interruptible(&gspca_dev->usb_lock)) return -ERESTARTSYS; - /* set the max alternate setting and loop until urb submit succeeds */ - intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); - gspca_dev->alt = intf->num_altsetting; + /* set the higher alternate setting and + * loop until urb submit succeeds */ + gspca_dev->alt = gspca_dev->nbalt; for (;;) { - PDEBUG(D_STREAM, "init transfer nbalt %d", gspca_dev->alt); + PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt); ep = get_isoc_ep(gspca_dev); if (ep == NULL) { ret = -EIO; @@ -517,13 +869,13 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) atomic_set(&gspca_dev->nevent, 0); /* submit the URBs */ - for (n = 0; n < NURBS; n++) { + for (n = 0; n < gspca_dev->nurbs; n++) { ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); if (ret < 0) { PDEBUG(D_ERR|D_STREAM, "usb_submit_urb [%d] err %d", n, ret); gspca_dev->streaming = 0; - gspca_kill_transfer(gspca_dev); + destroy_urbs(gspca_dev); if (ret == -ENOSPC) break; /* try the previous alt */ goto out; @@ -551,21 +903,32 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev) static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; + atomic_set(&gspca_dev->nevent, 0); +#ifdef GSPCA_HLP + { + struct hlp_dev *hlp_dev; + + hlp_dev = hlp; + if (hlp_dev != 0 + && hlp_dev->gspca_dev == gspca_dev) + atomic_set(&hlp_dev->nevent, 0); + } +#endif if (gspca_dev->present) { gspca_dev->sd_desc->stopN(gspca_dev); - gspca_kill_transfer(gspca_dev); + destroy_urbs(gspca_dev); gspca_set_alt0(gspca_dev); gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); } else { - gspca_kill_transfer(gspca_dev); + destroy_urbs(gspca_dev); atomic_inc(&gspca_dev->nevent); wake_up_interruptible(&gspca_dev->wq); PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); } } -static int gspca_set_default_mode(struct gspca_dev *gspca_dev) +static void gspca_set_default_mode(struct gspca_dev *gspca_dev) { int i; @@ -574,7 +937,6 @@ static int gspca_set_default_mode(struct gspca_dev *gspca_dev) gspca_dev->width = gspca_dev->cam.cam_mode[i].width; gspca_dev->height = gspca_dev->cam.cam_mode[i].height; gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; - return 0; } static int wxh_to_mode(struct gspca_dev *gspca_dev, @@ -582,46 +944,14 @@ static int wxh_to_mode(struct gspca_dev *gspca_dev, { int i; - for (i = gspca_dev->cam.nmodes - 1; --i >= 0; ) { - if (width > gspca_dev->cam.cam_mode[i].width) + for (i = gspca_dev->cam.nmodes; --i > 0; ) { + if (width >= gspca_dev->cam.cam_mode[i].width + && height >= gspca_dev->cam.cam_mode[i].height) break; } - i++; - while (i < gspca_dev->cam.nmodes - 1 - && width == gspca_dev->cam.cam_mode[i + 1].width - && height < gspca_dev->cam.cam_mode[i + 1].height) - i++; return i; } -static __u32 get_v4l2_depth(__u32 pixfmt) -{ - switch (pixfmt) { - case V4L2_PIX_FMT_BGR32: - case V4L2_PIX_FMT_RGB32: - return 32; - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - return 24; - case V4L2_PIX_FMT_RGB565: - case V4L2_PIX_FMT_YUYV: /* packed 4.2.2 */ - case V4L2_PIX_FMT_YYUV: - return 16; - case V4L2_PIX_FMT_YUV420: /* planar 4.2.0 */ - return 12; - case V4L2_PIX_FMT_MJPEG: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_SBGGR8: /* Bayer */ - return 8; - } - PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", - pixfmt & 0xff, - (pixfmt >> 8) & 0xff, - (pixfmt >> 16) & 0xff, - pixfmt >> 24); - return -EINVAL; -} - /* * search a mode with the right pixel format */ @@ -649,11 +979,15 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fmtdesc) { struct gspca_dev *gspca_dev = priv; - int i, j, index; + int i; +#ifndef GSPCA_HLP + int j, index; __u32 fmt_tb[8]; +#endif PDEBUG(D_CONF, "enum fmt cap"); +#ifndef GSPCA_HLP /* give an index to each format */ index = 0; j = 0; @@ -676,10 +1010,40 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, if (i < 0) return -EINVAL; /* no more format */ - fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmtdesc->pixelformat = fmt_tb[index]; if (gspca_is_compressed(fmt_tb[index])) fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; +#else /*GSPCA_HLP*/ + /* !! code tied to the decoding functions in decoder.c */ + i = gspca_dev->cam.nmodes - 1; + if (fmtdesc->index == 0) { /* (assume one format per subdriver) */ + fmtdesc->pixelformat = gspca_dev->cam.cam_mode[i].pixfmt; + if (gspca_is_compressed(fmtdesc->pixelformat)) + fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; + } else { + if (hlp == 0 + || (hlp->gspca_dev != 0 + && hlp->gspca_dev != gspca_dev)) + return -EINVAL; + switch (gspca_dev->cam.cam_mode[i].pixfmt) { + case V4L2_PIX_FMT_JPEG: + if (fmtdesc->index >= sizeof jpeg_to_tb + / sizeof jpeg_to_tb[0]) + return -EINVAL; + fmtdesc->pixelformat = jpeg_to_tb[fmtdesc->index]; + break; + case V4L2_PIX_FMT_SBGGR8: + if (fmtdesc->index >= sizeof bayer_to_tb + / sizeof bayer_to_tb[0]) + return -EINVAL; + fmtdesc->pixelformat = bayer_to_tb[fmtdesc->index]; + break; + default: + return -EINVAL; + } + } +#endif /*GSPCA_HLP*/ + fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff; @@ -688,22 +1052,26 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int gspca_get_buff_size(struct gspca_dev *gspca_dev) -{ - unsigned int size; - - size = gspca_dev->width * gspca_dev->height - * get_v4l2_depth(gspca_dev->pixfmt) / 8; - if (!size) - return -ENOMEM; - return size; -} - static int vidioc_g_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; +#ifdef GSPCA_HLP + int i; + + /* if the pixel format is not the one of the device and + * if the helper is inactive or busy, restore */ + i = gspca_dev->curr_mode; + if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[i].pixfmt) { + struct hlp_dev *hlp_dev; + + hlp_dev = hlp; + if (hlp_dev == 0 || hlp_dev->gspca_dev != gspca_dev) + gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; + } +#endif /*GSPCA_HLP*/ + fmt->fmt.pix.width = gspca_dev->width; fmt->fmt.pix.height = gspca_dev->height; fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; @@ -733,6 +1101,10 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, w = fmt->fmt.pix.width; h = fmt->fmt.pix.height; + + /* (luvcview problem) */ + if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) + fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; #ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); @@ -746,13 +1118,46 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, /* else, search the closest mode with the same pixel format */ mode2 = gspca_get_mode(gspca_dev, mode, fmt->fmt.pix.pixelformat); - if (mode2 >= 0) + if (mode2 >= 0) { mode = mode2; - else { + } else { + __u32 pixfmt; + + pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; +#ifndef GSPCA_HLP /* no chance, return this mode */ - fmt->fmt.pix.pixelformat - = gspca_dev->cam.cam_mode[mode].pixfmt; + fmt->fmt.pix.pixelformat = pixfmt; +#else /*GSPCA_HLP*/ + if (hlp != 0 + && (hlp->gspca_dev == 0 + || hlp->gspca_dev == gspca_dev) +/* decoding works for JPEG and Bayer only */ + && (pixfmt == V4L2_PIX_FMT_JPEG + || pixfmt == V4L2_PIX_FMT_SBGGR8)) { + switch (fmt->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_YUYV: /* 'YUYV' */ + case V4L2_PIX_FMT_BGR24: /* 'BGR3' */ + case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ + case V4L2_PIX_FMT_YUV420: /* 'YU12' */ + case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ + break; + default: { + /* return any of the supported fmt's */ + __u8 u; + + u = get_jiffies_64(); + u %= sizeof bayer_to_tb + / sizeof bayer_to_tb[0] - 1; + fmt->fmt.pix.pixelformat = + bayer_to_tb[u + 1]; + break; + } + } + } else { + fmt->fmt.pix.pixelformat = pixfmt; + } +#endif /*GSPCA_HLP*/ #ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) { PDEBUG_MODE("new format", @@ -791,7 +1196,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; - int ret, was_streaming; + int ret; #ifdef GSPCA_DEBUG if (gspca_debug & D_CONF) { @@ -802,32 +1207,56 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, #endif if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; + ret = try_fmt_cap(gspca_dev, fmt); if (ret < 0) goto out; + if (gspca_dev->nframes != 0 + && fmt->fmt.pix.sizeimage > gspca_dev->frsz) { + ret = -EINVAL; + goto out; + } + +#ifndef GSPCA_HLP if (ret == gspca_dev->curr_mode) goto out; /* same mode */ - was_streaming = gspca_dev->streaming; - if (was_streaming) { - if (gspca_dev->capt_file != 0 - && gspca_dev->capt_file != file) { - ret = -EBUSY; - goto out; - } - if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { - ret = -ERESTARTSYS; - goto out; - } - gspca_stream_off(gspca_dev); - mutex_unlock(&gspca_dev->usb_lock); +#else /*GSPCA_HLP*/ + if (ret == gspca_dev->curr_mode + && gspca_dev->pixfmt == fmt->fmt.pix.pixelformat) + goto out; /* same mode */ +#endif /*GSPCA_HLP*/ + + if (gspca_dev->streaming) { + ret = -EBUSY; + goto out; } gspca_dev->width = fmt->fmt.pix.width; gspca_dev->height = fmt->fmt.pix.height; gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; gspca_dev->curr_mode = ret; - if (was_streaming) - ret = gspca_init_transfer(gspca_dev); + +#ifdef GSPCA_HLP + /* if frame decoding is required */ + if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[ret].pixfmt) { + struct hlp_dev *hlp_dev; + + hlp_dev = hlp; + if (hlp_dev == 0 + || (hlp_dev->gspca_dev != 0 + && hlp_dev->gspca_dev != gspca_dev)) { /* helper busy */ + fmt->fmt.pix.pixelformat = + gspca_dev->pixfmt = + gspca_dev->cam.cam_mode[ret].pixfmt; + } else { /* helper active */ + hlp_dev->gspca_dev = gspca_dev; + hlp_dev->pixfmt = gspca_dev->cam.cam_mode[ret].pixfmt; + hlp_dev->fr_d = gspca_dev->fr_i; + } + } else if (hlp != 0 && hlp->gspca_dev == gspca_dev) + hlp->gspca_dev = 0; +#endif /*GSPCA_HLP*/ + ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); return ret; @@ -838,7 +1267,7 @@ static int dev_open(struct inode *inode, struct file *file) struct gspca_dev *gspca_dev; int ret; - PDEBUG(D_STREAM, "opening"); + PDEBUG(D_STREAM, "%s open", current->comm); gspca_dev = (struct gspca_dev *) video_devdata(file); if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; @@ -867,7 +1296,7 @@ static int dev_open(struct inode *inode, struct file *file) file->private_data = gspca_dev; #ifdef GSPCA_DEBUG /* activate the v4l2 debug */ - if (gspca_debug & D_CONF) + if (gspca_debug & D_V4L2) gspca_dev->vdev.debug |= 3; else gspca_dev->vdev.debug &= ~3; @@ -877,7 +1306,7 @@ out: if (ret != 0) PDEBUG(D_ERR|D_STREAM, "open failed err %d", ret); else - PDEBUG(D_STREAM, "open OK"); + PDEBUG(D_STREAM, "open done"); return ret; } @@ -885,7 +1314,7 @@ static int dev_close(struct inode *inode, struct file *file) { struct gspca_dev *gspca_dev = file->private_data; - PDEBUG(D_STREAM, "closing"); + PDEBUG(D_STREAM, "%s close", current->comm); if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; gspca_dev->users--; @@ -898,11 +1327,28 @@ static int dev_close(struct inode *inode, struct file *file) gspca_dev->sd_desc->close(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); frame_free(gspca_dev); - file->private_data = NULL; gspca_dev->capt_file = 0; + gspca_dev->memory = GSPCA_MEMORY_NO; +#ifdef GSPCA_HLP + { + struct hlp_dev *hlp_dev; + int mode; + + hlp_dev = hlp; + if (hlp_dev != 0 + && hlp_dev->gspca_dev == gspca_dev) { + hlp_dev->gspca_dev = 0; + hlp_dev->frame = 0; + mode = gspca_dev->curr_mode; + gspca_dev->pixfmt = + gspca_dev->cam.cam_mode[mode].pixfmt; + } + } +#endif /*GSPCA_HLP*/ } + file->private_data = NULL; mutex_unlock(&gspca_dev->queue_lock); - PDEBUG(D_STREAM, "closed"); + PDEBUG(D_STREAM, "close done"); return 0; } @@ -1036,32 +1482,50 @@ static int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *rb) { struct gspca_dev *gspca_dev = priv; - int frsz, ret; + int i, ret = 0; PDEBUG(D_STREAM, "reqbufs %d", rb->count); if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (rb->memory != V4L2_MEMORY_MMAP - && rb->memory != V4L2_MEMORY_USERPTR) + switch (rb->memory) { + case V4L2_MEMORY_MMAP: + break; + case V4L2_MEMORY_USERPTR: +#ifdef GSPCA_HLP + if (hlp == 0 || hlp->gspca_dev != gspca_dev) + break; +#endif return -EINVAL; - if (rb->count == 0) + default: return -EINVAL; - frsz = gspca_get_buff_size(gspca_dev); - if (frsz < 0) - return frsz; + } if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - if (gspca_dev->capt_file != 0) { /* only one file may do capture */ + + for (i = 0; i < gspca_dev->nframes; i++) { + if (gspca_dev->frame[i].vma_use_count) { + ret = -EBUSY; + goto out; + } + } + + /* only one file may do capture */ + if ((gspca_dev->capt_file != 0 && gspca_dev->capt_file != file) + || gspca_dev->streaming) { ret = -EBUSY; goto out; } - ret = frame_alloc(gspca_dev, - rb->count, - (unsigned int) frsz, - rb->memory); - if (ret == 0) { - rb->count = gspca_dev->nframes; - gspca_dev->capt_file = file; + + if (rb->count == 0) { /* unrequest? */ + frame_free(gspca_dev); + gspca_dev->capt_file = 0; + } else { + gspca_dev->memory = rb->memory; + ret = frame_alloc(gspca_dev, rb->count); + if (ret == 0) { + rb->count = gspca_dev->nframes; + gspca_dev->capt_file = file; + } } out: mutex_unlock(&gspca_dev->queue_lock); @@ -1224,12 +1688,25 @@ static int vidiocgmbuf(struct file *file, void *priv, if (gspca_dev->nframes == 0) { struct v4l2_requestbuffers rb; int ret; - + __u32 pixfmt; + short width, height; + + /* as the final format is not yet defined, allocate + buffers with the max size */ + pixfmt = gspca_dev->pixfmt; + width = gspca_dev->width; + height = gspca_dev->height; + gspca_dev->pixfmt = V4L2_PIX_FMT_BGR32; + gspca_dev->width = 640; + gspca_dev->height = 480; memset(&rb, 0, sizeof rb); rb.count = 4; rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; rb.memory = V4L2_MEMORY_MMAP; ret = vidioc_reqbufs(file, priv, &rb); + gspca_dev->pixfmt = pixfmt; + gspca_dev->width = width; + gspca_dev->height = height; if (ret != 0) return ret; } @@ -1328,43 +1805,22 @@ out: return ret; } -static unsigned int dev_poll(struct file *file, poll_table * wait) -{ - struct gspca_dev *gspca_dev = file->private_data; - int i, ret; - - PDEBUG(D_FRAM, "poll"); - - poll_wait(file, &gspca_dev->wq, wait); - - if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) - return POLLERR; - if (gspca_dev->dev == 0 - || !gspca_dev->streaming) /* if not streaming */ - ret = POLLERR; - else { - i = gspca_dev->fr_o; - i = gspca_dev->fr_queue[i]; - if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) - ret = POLLIN | POLLRDNORM; /* something to read */ - else - ret = 0; - } - mutex_unlock(&gspca_dev->queue_lock); - return ret; -} - /* * wait for a video frame * * If a frame is ready, its index is returned. */ -static int gspca_frame_wait(struct gspca_dev *gspca_dev, +static int frame_wait(struct gspca_dev *gspca_dev, int nonblock_ing) { struct gspca_frame *frame; int i, j, ret; + /* if userptr, treat the awaiting URBs */ + if (gspca_dev->memory == V4L2_MEMORY_USERPTR) + isoc_transfer(gspca_dev); + + /* check if a frame is ready */ i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; @@ -1385,13 +1841,14 @@ static int gspca_frame_wait(struct gspca_dev *gspca_dev, } if (!gspca_dev->streaming || !gspca_dev->present) return -EIO; + if (gspca_dev->memory == V4L2_MEMORY_USERPTR) + isoc_transfer(gspca_dev); i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) break; } - ok: atomic_dec(&gspca_dev->nevent); gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; @@ -1434,7 +1891,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->read_lock)) return -ERESTARTSYS; - ret = gspca_frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); + ret = frame_wait(gspca_dev, file->f_flags & O_NONBLOCK); if (ret < 0) goto out; i = ret; /* frame index */ @@ -1467,14 +1924,14 @@ static int vidioc_qbuf(struct file *file, void *priv, index = v4l2_buf->index; if ((unsigned) index >= gspca_dev->nframes) { - PDEBUG(D_STREAM, + PDEBUG(D_FRAM, "qbuf idx %d >= %d", index, gspca_dev->nframes); return -EINVAL; } frame = &gspca_dev->frame[index]; if (v4l2_buf->memory != frame->v4l2_buf.memory) { - PDEBUG(D_STREAM, "qbuf bad memory type"); + PDEBUG(D_FRAM, "qbuf bad memory type"); return -EINVAL; } if (gspca_dev->capt_file != file) @@ -1483,17 +1940,16 @@ static int vidioc_qbuf(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - if (frame->v4l2_buf.flags - & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE)) { - PDEBUG(D_STREAM, "qbuf bad state"); + if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { + PDEBUG(D_FRAM, "qbuf bad state"); ret = -EINVAL; goto out; } frame->v4l2_buf.flags |= V4L2_BUF_FLAG_QUEUED; - frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; +/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */ - if (v4l2_buf->memory == V4L2_MEMORY_USERPTR) { + if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { frame->data = frame->data_end = (unsigned char *) v4l2_buf->m.userptr; frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; @@ -1517,16 +1973,16 @@ out: return ret; } -static ssize_t dev_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) +/* + * allocate the resources for read() + */ +static int read_alloc(struct gspca_dev *gspca_dev, + struct file *file) { - struct gspca_dev *gspca_dev = file->private_data; - struct gspca_frame *frame; struct v4l2_buffer v4l2_buf; - struct timeval timestamp; - int i, ret, ret2; + int i, ret; - PDEBUG(D_FRAM, "read (%p, %d)", data, count); + PDEBUG(D_STREAM, "read alloc"); if (gspca_dev->nframes == 0) { struct v4l2_requestbuffers rb; @@ -1536,7 +1992,7 @@ static ssize_t dev_read(struct file *file, char __user *data, rb.memory = V4L2_MEMORY_MMAP; ret = vidioc_reqbufs(file, gspca_dev, &rb); if (ret != 0) { - PDEBUG(D_STREAM, "read reqbuf err: %d", ret); + PDEBUG(D_STREAM, "read reqbuf err %d", ret); return ret; } memset(&v4l2_buf, 0, sizeof v4l2_buf); @@ -1553,18 +2009,89 @@ static ssize_t dev_read(struct file *file, char __user *data, return ret; } } - } else if (gspca_dev->capt_file != file) - return -EINVAL; + gspca_dev->memory = GSPCA_MEMORY_READ; + } + /* start streaming */ + ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE); + if (ret != 0) + PDEBUG(D_STREAM, "read streamon err %d", ret); + return ret; +} + +static unsigned int dev_poll(struct file *file, poll_table *wait) +{ + struct gspca_dev *gspca_dev = file->private_data; + int i, ret; + + PDEBUG(D_FRAM, "poll"); + + poll_wait(file, &gspca_dev->wq, wait); + if (!gspca_dev->present) + return POLLERR; + + /* if not streaming, the user would use read() */ if (!gspca_dev->streaming) { - ret = vidioc_streamon(file, gspca_dev, - V4L2_BUF_TYPE_VIDEO_CAPTURE); + if (gspca_dev->memory != GSPCA_MEMORY_NO) { + ret = POLLERR; /* not the 1st time */ + goto out; + } + ret = read_alloc(gspca_dev, file); if (ret != 0) { - PDEBUG(D_STREAM, "read streamon err %d", ret); - return ret; + ret = POLLERR; + goto out; } } + if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) + return POLLERR; + if (!gspca_dev->present) { + ret = POLLERR; + goto out; + } + + /* if not mmap, treat the awaiting URBs */ + if (gspca_dev->memory == V4L2_MEMORY_USERPTR + && gspca_dev->capt_file == file) + isoc_transfer(gspca_dev); + + i = gspca_dev->fr_o; + i = gspca_dev->fr_queue[i]; + if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) + ret = POLLIN | POLLRDNORM; /* something to read */ + else + ret = 0; +out: + mutex_unlock(&gspca_dev->queue_lock); + return ret; +} + +static ssize_t dev_read(struct file *file, char __user *data, + size_t count, loff_t *ppos) +{ + struct gspca_dev *gspca_dev = file->private_data; + struct gspca_frame *frame; + struct v4l2_buffer v4l2_buf; + struct timeval timestamp; + int i, ret, ret2; + + PDEBUG(D_FRAM, "read (%d)", count); + if (!gspca_dev->present) + return -ENODEV; + switch (gspca_dev->memory) { + case GSPCA_MEMORY_NO: /* first time */ + ret = read_alloc(gspca_dev, file); + if (ret != 0) + return ret; + break; + case GSPCA_MEMORY_READ: + if (gspca_dev->capt_file != file) + return -EINVAL; + break; + default: + return -EINVAL; + } + /* get a frame */ jiffies_to_timeval(get_jiffies_64(), ×tamp); timestamp.tv_sec--; @@ -1615,7 +2142,7 @@ out: return ret; } -static void gspca_dev_release(struct video_device *vfd) +static void dev_release(struct video_device *vfd) { /* nothing */ } @@ -1635,7 +2162,7 @@ static struct video_device gspca_template = { .name = "gspca main driver", .type = VID_TYPE_CAPTURE, .fops = &dev_fops, - .release = gspca_dev_release, /* mandatory */ + .release = dev_release, /* mandatory */ .minor = -1, .vidioc_querycap = vidioc_querycap, .vidioc_dqbuf = vidioc_dqbuf, @@ -1673,7 +2200,8 @@ static struct video_device gspca_template = { int gspca_dev_probe(struct usb_interface *intf, const struct usb_device_id *id, const struct sd_desc *sd_desc, - int dev_size) + int dev_size, + struct module *module) { struct usb_interface_descriptor *interface; struct gspca_dev *gspca_dev; @@ -1682,8 +2210,8 @@ int gspca_dev_probe(struct usb_interface *intf, __u16 vendor; __u16 product; - vendor = le16_to_cpu(dev->descriptor.idVendor); - product = le16_to_cpu(dev->descriptor.idProduct); + vendor = id->idVendor; + product = id->idProduct; PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product); /* we don't handle multi-config cameras */ @@ -1703,6 +2231,7 @@ int gspca_dev_probe(struct usb_interface *intf, } gspca_dev->dev = dev; gspca_dev->iface = interface->bInterfaceNumber; + gspca_dev->nbalt = intf->num_altsetting; gspca_dev->sd_desc = sd_desc; /* gspca_dev->users = 0; (done by kzalloc) */ gspca_dev->nbufread = 2; @@ -1724,6 +2253,9 @@ int gspca_dev_probe(struct usb_interface *intf, /* init video stuff */ memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); gspca_dev->vdev.dev = &dev->dev; + memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); + gspca_dev->vdev.fops = &gspca_dev->fops; + gspca_dev->fops.owner = module; /* module protection */ ret = video_register_device(&gspca_dev->vdev, VFL_TYPE_GRABBER, video_nr); @@ -1758,7 +2290,7 @@ void gspca_disconnect(struct usb_interface *intf) mutex_lock(&gspca_dev->queue_lock); mutex_lock(&gspca_dev->usb_lock); gspca_dev->streaming = 0; - gspca_kill_transfer(gspca_dev); + destroy_urbs(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); mutex_unlock(&gspca_dev->queue_lock); while (gspca_dev->users != 0) { /* wait until fully closed */ @@ -1777,11 +2309,23 @@ EXPORT_SYMBOL(gspca_disconnect); /* -- module insert / remove -- */ static int __init gspca_init(void) { +#ifdef GSPCA_HLP + int ret; + + /* create /dev/gspca_hlp */ + ret = misc_register(&hlp_device); + if (ret < 0) + err("misc_register err %d", ret); + start_hlp(); /* try to start the helper process */ +#endif info("main v%s registered", version); return 0; } static void __exit gspca_exit(void) { +#ifdef GSPCA_HLP + misc_deregister(&hlp_device); +#endif info("main deregistered"); } @@ -1791,7 +2335,8 @@ module_exit(gspca_exit); module_param_named(debug, gspca_debug, int, 0644); MODULE_PARM_DESC(debug, "Debug (bit) 0x01:error 0x02:probe 0x04:config" - " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout"); + " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" + " 0x0100: v4l2"); module_param(comp_fac, int, 0644); MODULE_PARM_DESC(comp_fac, diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index c2618c0e6615..e69d8472a284 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -25,6 +25,7 @@ extern int gspca_debug; #define D_PACK 0x20 #define D_USBI 0x40 #define D_USBO 0x80 +#define D_V4L2 0x0100 #else #define PDEBUG(level, fmt, args...) #endif @@ -46,9 +47,9 @@ extern int gspca_debug; #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ /* ISOC transfers */ -#define NURBS 4 /* number of URBs */ +#define MAX_NURBS 32 /* max number of URBs (read & userptr) */ #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ -#define ISO_MAX_SIZE 0x10000 /* max size of one URB buffer (64 Kb) */ +#define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ /* device information - set at probe time */ struct cam_mode { @@ -123,13 +124,14 @@ struct gspca_frame { struct gspca_dev { struct video_device vdev; /* !! must be the first item */ + struct file_operations fops; struct usb_device *dev; struct file *capt_file; /* file doing video capture */ struct cam cam; /* device information */ const struct sd_desc *sd_desc; /* subdriver description */ - struct urb *urb[NURBS]; + struct urb *urb[MAX_NURBS]; __u8 *frbuf; /* buffer for nframes */ struct gspca_frame frame[GSPCA_MAX_FRAMES]; @@ -155,15 +157,21 @@ struct gspca_dev { struct mutex queue_lock; /* ISOC queue protection */ __u32 sequence; /* frame sequence number */ char streaming; - char users; /* # open */ + char users; /* number of opens */ char present; /* device connected */ char nbufread; /* number of buffers for read() */ + char nurbs; /* number of allocated URBs */ + char memory; /* memory type (V4L2_MEMORY_xxx) */ + __u8 urb_in; /* URB pointers - used when !mmap */ + __u8 urb_out; + __u8 nbalt; /* number of USB alternate settings */ }; int gspca_dev_probe(struct usb_interface *intf, const struct usb_device_id *id, const struct sd_desc *sd_desc, - int dev_size); + int dev_size, + struct module *module); void gspca_disconnect(struct usb_interface *intf); struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h index c4087c0ebc46..d823b47bd4e6 100644 --- a/drivers/media/video/gspca/jpeg.h +++ b/drivers/media/video/gspca/jpeg.h @@ -265,7 +265,7 @@ static unsigned char eoh[] = { 0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */ 0x03, 0x11, 0x01, - 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan */ + 0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */ 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00 }; #endif diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 57d48f51e3a0..482ef4a6afc0 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 1) -static const char version[] = "0.1.1"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) +static const char version[] = "0.2.15"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -188,7 +188,8 @@ static const __u8 pac207_sensor_init[][8] = { /* 48 reg_72 Rate Control end BalSize_4a =0x36 */ static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; -static const char pac207_sof_marker[5] = { 0xff, 0xff, 0x00, 0xff, 0x96 }; +static const unsigned char pac207_sof_marker[5] = + { 0xff, 0xff, 0x00, 0xff, 0x96 }; int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, const u8 *buffer, u16 length) @@ -327,11 +328,12 @@ static void sd_start(struct gspca_dev *gspca_dev) pac207_write_reg(gspca_dev, 0x02, sd->exposure); /* PXCK = 12MHz /n */ mode = 0x02; /* Image Format (Bit 0), LED (1), Compr. test mode (2) */ - if (gspca_dev->width == 176) { /* 176x144 */ + if (gspca_dev->width == 176) { /* 176x144 */ mode |= 0x01; PDEBUG(D_STREAM, "pac207_start mode 176x144"); - } else/* 352x288 */ + } else { /* 352x288 */ PDEBUG(D_STREAM, "pac207_start mode 352x288"); + } pac207_write_reg(gspca_dev, 0x41, mode); pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ @@ -425,7 +427,7 @@ void init_pixart_decoder(void) } /* auto gain and exposure algorithm based on the knee algorithm described here: - http://ytse.tricolour.net/docs/LowLightOptimization.html */ + * */ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -508,8 +510,9 @@ static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, sd->sof_read = 0; return m + i + 1; } - } else + } else { sd->sof_read = 0; + } } return NULL; @@ -556,9 +559,9 @@ static int pac207_decompress_row(struct gspca_dev *gspca_dev, decoder_state->line_read++; decoder_state->get_abs = 0; } else { - if (table[code].is_abs) + if (table[code].is_abs) { decoder_state->get_abs = 1; - else { + } else { /* relative to left pixel */ val = outp[-2] + table[code].val; @@ -894,13 +897,13 @@ static struct sd_desc sd_desc = { #define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, - {USB_DEVICE(0x093a, 0x2460), DVNM("PAC207 Qtec Webcam 100")}, + {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")}, {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")}, {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")}, {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")}, - {USB_DEVICE(0x093a, 0x2471), DVNM("PAC207 Genius VideoCam ge111")}, - {USB_DEVICE(0x093a, 0x2472), DVNM("PAC207 Genius VideoCam ge110")}, + {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")}, + {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")}, {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")}, {} }; @@ -910,8 +913,8 @@ MODULE_DEVICE_TABLE(usb, device_table); static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - PDEBUG(D_PROBE, "camera probe"); - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd)); + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); } static struct usb_driver sd_driver = { diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 2e4cf64442ac..d8c203e99cd3 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -1,7 +1,7 @@ /* * Syntek DV4000 (STK014) subdriver * - * Copyright (C) Jean-Francois Moine (http://moinejf.free.fr) + * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,7 +16,6 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #define MODULE_NAME "stk014" @@ -24,8 +23,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) -static const char version[] = "0.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 7) +static const char version[] = "0.2.7"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -389,64 +388,32 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, unsigned char *data, /* isoc packet */ int len) /* iso packet length */ { - int l; static unsigned char ffd9[] = {0xff, 0xd9}; /* a frame starts with: * - 0xff 0xfe - * - 0x08 0x00 // length (little endian ?!) - * - 4 bytes = size of whole frame (big endian - including header) + * - 0x08 0x00 - length (little endian ?!) + * - 4 bytes = size of whole frame (BE - including header) * - 0x00 0x0c * - 0xff 0xd8 * - .. JPEG image with escape sequences (ff 00) + * (without ending - ff d9) */ if (data[0] == 0xff && data[1] == 0xfe) { - if (gspca_dev->last_packet_type == INTER_PACKET) { - PDEBUG(D_ERR|D_FRAM, "sof actual l: %d init l: %d", - frame->data_end - frame->data, - frame->v4l2_buf.bytesused); - } + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + ffd9, 2); - /* put the JPEG headaer */ + /* put the JPEG 411 header */ jpeg_put_header(gspca_dev, frame, sd_quant, 0x22); /* beginning of the frame */ #define STKHDRSZ 12 - l = (data[4] << 24) /* frame size */ - + (data[5] << 16) - + (data[6] << 8) - + data[7] - - STKHDRSZ - + (frame->data_end - frame->data) - + 2; /* EOF (ff d9) */ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data + STKHDRSZ, len - STKHDRSZ); #undef STKHDRSZ - frame->v4l2_buf.bytesused = l; - return; - } - if (gspca_dev->last_packet_type != INTER_PACKET) { - if (gspca_dev->last_packet_type == LAST_PACKET) { - PDEBUG(D_ERR|D_PACK, "mof actual l: %d init l: %d", - frame->data_end - frame->data, - frame->v4l2_buf.bytesused); - } - return; - } - - /* intermediate packet */ - l = frame->data_end - frame->data; - if (len < frame->v4l2_buf.bytesused - 2 - l) { - gspca_frame_add(gspca_dev, INTER_PACKET, frame, - data, len); return; } - - /* last packet */ - if (len > frame->v4l2_buf.bytesused - 2 - l) - len = frame->v4l2_buf.bytesused - 2 - l; gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); - gspca_frame_add(gspca_dev, LAST_PACKET, frame, ffd9, 2); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -529,8 +496,8 @@ MODULE_DEVICE_TABLE(usb, device_table); static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - PDEBUG(D_PROBE, "camera probe"); - return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd)); + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); } static struct usb_driver sd_driver = { diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c new file mode 100644 index 000000000000..03cc7fc58dbc --- /dev/null +++ b/drivers/media/video/gspca/zc3xx.c @@ -0,0 +1,7523 @@ +/* + * Z-Star/Vimicro zc301/zc302p/vc30x library + * Copyright (C) 2004 2005 2006 Michel Xhaard + * mxhaard@magic.fr + * + * V4L2 by Jean-François Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define MODULE_NAME "zc3xx" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 13) +static const char version[] = "0.2.13"; + +MODULE_AUTHOR("Michel Xhaard , " + "Serge A. Suchkov "); +MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); +MODULE_LICENSE("GPL"); + +static int lightfreq = 50; +static int force_sensor = -1; + +#include "jpeg.h" + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char autogain; + unsigned char gamma; + + char qindex; + char sensor; /* Type of image sensor chip */ +/* !! values used in different tables */ +#define SENSOR_CS2102 0 +#define SENSOR_CS2102K 1 +#define SENSOR_GC0305 2 +#define SENSOR_HDCS2020 3 +#define SENSOR_HDCS2020b 4 +#define SENSOR_HV7131B 5 +#define SENSOR_HV7131C 6 +#define SENSOR_ICM105A 7 +#define SENSOR_MC501CB 8 +#define SENSOR_OV7620 9 +/*#define SENSOR_OV7648 9 - same values */ +#define SENSOR_OV7630C 10 +/*#define SENSOR_free 11 */ +#define SENSOR_PAS106 12 +#define SENSOR_PB0330 13 +#define SENSOR_PO2030 14 +#define SENSOR_TAS5130CK 15 +#define SENSOR_TAS5130CXX 16 +#define SENSOR_TAS5130C_VF0250 17 +#define SENSOR_MAX 18 + unsigned short chip_revision; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 128, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 256, + .step = 1, + .default_value = 128, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_AUTOGAIN 2 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +#define SD_GAMMA 3 + { + { + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = 1, + .maximum = 6, + .step = 1, + .default_value = 4, + }, + .set = sd_setcontrast, + .get = sd_getgamma, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_JPEG, 176, 144, 1}, + {V4L2_PIX_FMT_JPEG, 352, 288, 0}, +}; + +/* usb exchanges */ +struct usb_action { + __u8 req; + __u8 val; + __u16 idx; +}; + +static struct usb_action cs2102_Initial[] = { + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x00, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x20, 0x0080}, + {0xa0, 0x21, 0x0081}, + {0xa0, 0x30, 0x0083}, + {0xa0, 0x31, 0x0084}, + {0xa0, 0x32, 0x0085}, + {0xa0, 0x23, 0x0086}, + {0xa0, 0x24, 0x0087}, + {0xa0, 0x25, 0x0088}, + {0xa0, 0xb3, 0x008b}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xaa, 0x02, 0x0008}, + {0xaa, 0x03, 0x0000}, + {0xaa, 0x11, 0x0000}, + {0xaa, 0x12, 0x0089}, + {0xaa, 0x13, 0x0000}, + {0xaa, 0x14, 0x00e9}, + {0xaa, 0x20, 0x0000}, + {0xaa, 0x22, 0x0000}, + {0xaa, 0x0b, 0x0004}, + {0xaa, 0x30, 0x0030}, + {0xaa, 0x31, 0x0030}, + {0xaa, 0x32, 0x0030}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x10, 0x01ae}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x68, 0x018d}, + {0xa0, 0x00, 0x01ad}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x08, 0x01c6}, /* clock ? */ + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x24, 0x0120}, /* gamma 5 */ + {0xa0, 0x44, 0x0121}, + {0xa0, 0x64, 0x0122}, + {0xa0, 0x84, 0x0123}, + {0xa0, 0x9d, 0x0124}, + {0xa0, 0xb2, 0x0125}, + {0xa0, 0xc4, 0x0126}, + {0xa0, 0xd3, 0x0127}, + {0xa0, 0xe0, 0x0128}, + {0xa0, 0xeb, 0x0129}, + {0xa0, 0xf4, 0x012a}, + {0xa0, 0xfb, 0x012b}, + {0xa0, 0xff, 0x012c}, + {0xa0, 0xff, 0x012d}, + {0xa0, 0xff, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x18, 0x0130}, + {0xa0, 0x20, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0e, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x00, 0x013c}, + {0xa0, 0x00, 0x013d}, + {0xa0, 0x00, 0x013e}, + {0xa0, 0x01, 0x013f}, + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x23, 0x0001}, + {0xaa, 0x24, 0x0055}, + {0xaa, 0x25, 0x00cc}, + {0xaa, 0x21, 0x003f}, + {0xa0, 0x02, 0x0190}, + {0xa0, 0xab, 0x0191}, + {0xa0, 0x98, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x30, 0x0196}, + {0xa0, 0xd4, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x39, 0x001d}, + {0xa0, 0x70, 0x001e}, + {0xa0, 0xb0, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; + +static struct usb_action cs2102_InitialScale[] = { + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x00, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x20, 0x0080}, + {0xa0, 0x21, 0x0081}, + {0xa0, 0x30, 0x0083}, + {0xa0, 0x31, 0x0084}, + {0xa0, 0x32, 0x0085}, + {0xa0, 0x23, 0x0086}, + {0xa0, 0x24, 0x0087}, + {0xa0, 0x25, 0x0088}, + {0xa0, 0xb3, 0x008b}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xaa, 0x02, 0x0008}, + {0xaa, 0x03, 0x0000}, + {0xaa, 0x11, 0x0001}, + {0xaa, 0x12, 0x0087}, + {0xaa, 0x13, 0x0001}, + {0xaa, 0x14, 0x00e7}, + {0xaa, 0x20, 0x0000}, + {0xaa, 0x22, 0x0000}, + {0xaa, 0x0b, 0x0004}, + {0xaa, 0x30, 0x0030}, + {0xaa, 0x31, 0x0030}, + {0xaa, 0x32, 0x0030}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x68, 0x018d}, + {0xa0, 0x00, 0x01ad}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x08, 0x01c6}, /* clock ? */ + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x24, 0x0120}, /* gamma 5 */ + {0xa0, 0x44, 0x0121}, + {0xa0, 0x64, 0x0122}, + {0xa0, 0x84, 0x0123}, + {0xa0, 0x9d, 0x0124}, + {0xa0, 0xb2, 0x0125}, + {0xa0, 0xc4, 0x0126}, + {0xa0, 0xd3, 0x0127}, + {0xa0, 0xe0, 0x0128}, + {0xa0, 0xeb, 0x0129}, + {0xa0, 0xf4, 0x012a}, + {0xa0, 0xfb, 0x012b}, + {0xa0, 0xff, 0x012c}, + {0xa0, 0xff, 0x012d}, + {0xa0, 0xff, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x18, 0x0130}, + {0xa0, 0x20, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0e, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x00, 0x013c}, + {0xa0, 0x00, 0x013d}, + {0xa0, 0x00, 0x013e}, + {0xa0, 0x01, 0x013f}, + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x23, 0x0000}, + {0xaa, 0x24, 0x00aa}, + {0xaa, 0x25, 0x00e6}, + {0xaa, 0x21, 0x003f}, + {0xa0, 0x01, 0x0190}, + {0xa0, 0x55, 0x0191}, + {0xa0, 0xcc, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x18, 0x0196}, + {0xa0, 0x6a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x3f, 0x001d}, + {0xa0, 0xa5, 0x001e}, + {0xa0, 0xf0, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; +static struct usb_action cs2102_50HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x00ac}, /* 00,11,ac,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x42, 0x0197}, /* 01,97,42,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0x8c, 0x001d}, /* 00,1d,8c,cc */ + {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ + {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ + {0, 0, 0} +}; +static struct usb_action cs2102_50HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x00a1}, /* 00,11,a1,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xf7, 0x0192}, /* 01,92,f7,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0x93, 0x001d}, /* 00,1d,93,cc */ + {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ + {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ + {0, 0, 0} +}; +static struct usb_action cs2102_60HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x00aa}, /* 00,11,aa,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xe4, 0x0192}, /* 01,92,e4,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x3a, 0x0197}, /* 01,97,3a,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0x5d, 0x001d}, /* 00,1d,5d,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ + {0, 0, 0} +}; +static struct usb_action cs2102_60HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x00be}, /* 00,11,be,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xfc, 0x0192}, /* 01,92,fc,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x69, 0x0197}, /* 01,97,69,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0xb7, 0x001d}, /* 00,1d,b7,cc */ + {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ + {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ + {0, 0, 0} +}; +static struct usb_action cs2102_NoFliker[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0, 0, 0} +}; +static struct usb_action cs2102_NoFlikerScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ + {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ + {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ + {0xaa, 0x10, 0x0005}, /* 00,10,05,aa */ + {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ + {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ + {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0, 0, 0} +}; + +/* CS2102_KOCOM */ +static struct usb_action cs2102K_Initial[] = { + {0xa0, 0x11, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x55, 0x008b}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0a, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0b, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0c, 0x0092}, + {0xa0, 0x7c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0d, 0x0092}, + {0xa0, 0xa3, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x03, 0x0092}, + {0xa0, 0xfb, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x05, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x06, 0x0092}, + {0xa0, 0x03, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x09, 0x0092}, + {0xa0, 0x08, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0e, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0f, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x10, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x11, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x12, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x15, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x16, 0x0092}, + {0xa0, 0x0c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x17, 0x0092}, + {0xa0, 0x0c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0xb7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x78, 0x018d}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x20, 0x0087}, + {0xa0, 0x21, 0x0088}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x01, 0x01b1}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x01, 0x00a3}, + {0xa0, 0x22, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xee, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x3a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x0c, 0x01a9}, + {0xa0, 0x28, 0x01aa}, + {0xa0, 0x04, 0x001d}, + {0xa0, 0x0f, 0x001e}, + {0xa0, 0x19, 0x001f}, + {0xa0, 0x1f, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x5c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x5c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x96, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x96, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0, 0, 0} +}; + +static struct usb_action cs2102K_InitialScale[] = { + {0xa0, 0x11, 0x0002}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x55, 0x008b}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0a, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0b, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0c, 0x0092}, + {0xa0, 0x7b, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0d, 0x0092}, + {0xa0, 0xa3, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x03, 0x0092}, + {0xa0, 0xfb, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x05, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x06, 0x0092}, + {0xa0, 0x03, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x09, 0x0092}, + {0xa0, 0x08, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0e, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0f, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x10, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x11, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x12, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x15, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x16, 0x0092}, + {0xa0, 0x0c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x17, 0x0092}, + {0xa0, 0x0c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0xf7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x78, 0x018d}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x20, 0x0087}, + {0xa0, 0x21, 0x0088}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x01, 0x01b1}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x01, 0x00a3}, + {0xa0, 0x22, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xee, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x3a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x0c, 0x01a9}, + {0xa0, 0x28, 0x01aa}, + {0xa0, 0x04, 0x001d}, + {0xa0, 0x0f, 0x001e}, + {0xa0, 0x19, 0x001f}, + {0xa0, 0x1f, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x55, 0x008b}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0A, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0B, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0C, 0x0092}, + {0xa0, 0x7b, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0D, 0x0092}, + {0xa0, 0xA3, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x03, 0x0092}, + {0xa0, 0xfb, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x05, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x06, 0x0092}, + {0xa0, 0x03, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x09, 0x0092}, + {0xa0, 0x08, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0E, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x0f, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x10, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x11, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x12, 0x0092}, + {0xa0, 0x18, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x15, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x16, 0x0092}, + {0xa0, 0x0c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x17, 0x0092}, + {0xa0, 0x0C, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0xf7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x78, 0x018d}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x20, 0x0087}, + {0xa0, 0x21, 0x0088}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x01, 0x01b1}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x22, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x01, 0x00a3}, + {0xa0, 0x22, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xee, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x3a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x0c, 0x01a9}, + {0xa0, 0x28, 0x01aa}, + {0xa0, 0x04, 0x001d}, + {0xa0, 0x0f, 0x001e}, + {0xa0, 0x19, 0x001f}, + {0xa0, 0x1f, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x4c, 0x0118}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x5c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x5c, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x96, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x96, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0xd0, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0xd0, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x02, 0x0008}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x0a, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x0a, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x44, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x44, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x21, 0x0092}, + {0xa0, 0x7e, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x13, 0x0092}, + {0xa0, 0x7e, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x14, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x18, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x04, 0x01a7}, + {0, 0, 0} +}; + +static struct usb_action gc0305_Initial[] = { /* 640x480 */ + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x04, 0x0002}, /* 00,02,04,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xe6, 0x009c}, /* 00,9c,e6,cc */ + {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc */ + {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */ + {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */ + {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ + {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ + {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ + {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ + {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ + {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ + {0xa0, 0x82, 0x0086}, /* 00,86,82,cc */ + {0xa0, 0x83, 0x0087}, /* 00,87,83,cc */ + {0xa0, 0x84, 0x0088}, /* 00,88,84,cc */ + {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ + {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ + {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ + {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ + {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ + {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ + {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ + {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ + {0xaa, 0x17, 0x00e6}, /* 00,17,e6,aa */ + {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ + {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */ + {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ + {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ + {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x76, 0x0189}, /* 01,89,76,cc */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ + {0xa0, 0x85, 0x018d}, /* 01,8d,85,cc */ + {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ + {0xa0, 0x52, 0x0116}, /* 01,16,52,cc */ + {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ + {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ + {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ + {0,0,0} +}; +static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc */ + {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc */ + {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ + {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */ + {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ + {0xaa, 0x02, 0x0000}, /* 00,02,00,aa */ + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ + {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa */ + {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ + {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ + {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ + {0xa0, 0x82, 0x0086}, /* 00,86,82,cc */ + {0xa0, 0x83, 0x0087}, /* 00,87,83,cc */ + {0xa0, 0x84, 0x0088}, /* 00,88,84,cc */ + {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ + {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ + {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ + {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa */ + {0xaa, 0x0d, 0x00b0}, /* 00,0d,b0,aa */ + {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa */ + {0xaa, 0x0f, 0x00b0}, /* 00,0f,b0,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x11, 0x00b0}, /* 00,11,b0,aa */ + {0xaa, 0x16, 0x0001}, /* 00,16,01,aa */ + {0xaa, 0x17, 0x00e8}, /* 00,17,e8,aa */ + {0xaa, 0x18, 0x0002}, /* 00,18,02,aa */ + {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */ + {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ + {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ + {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x76, 0x0189}, /* 01,89,76,cc */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ + {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ + {0xa0, 0x52, 0x0116}, /* 01,16,52,cc */ + {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ + {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ + {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ + {0,0,0} +}; +static struct usb_action gc0305_50HZ[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ + {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc */ + {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ /* win: 01,92,10 */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x8e, 0x0197}, /* 01,97,8e,cc */ /* win: 01,97,ec */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ +/* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ + {0,0,0} +}; +static struct usb_action gc0305_60HZ[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ + {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc */ + {0xa0, 0x10, 0x0192}, /* 01,92,10,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0xec, 0x0197}, /* 01,97,ec,cc */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ + {0,0,0} +}; + +static struct usb_action gc0305_NoFliker[] = { + {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc */ + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ + {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x00, 0x0191}, /* 01,91,00,cc */ + {0xa0, 0x48, 0x0192}, /* 01,92,48,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ + {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ + {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ + {0,0,0} +}; + +/* play poker with registers at your own risk !! */ +static struct usb_action hdcs2020xx_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0e, 0x0010}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xd0, 0x0006}, /* D0 ?? E0 did not start */ + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x08, 0x008d}, + {0xa0, 0x08, 0x0098}, + {0xa0, 0x02, 0x009a}, + {0xa0, 0x08, 0x011a}, + {0xa0, 0x02, 0x011c}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xd8, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x88, 0x009e}, + {0xaa, 0x02, 0x0002}, + {0xaa, 0x07, 0x0006}, + {0xaa, 0x08, 0x0002}, + {0xaa, 0x09, 0x0006}, + {0xaa, 0x0a, 0x0001}, + {0xaa, 0x0b, 0x0001}, + {0xaa, 0x0c, 0x0008}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x10, 0x0000}, + {0xaa, 0x12, 0x0005}, + {0xaa, 0x13, 0x0063}, + {0xaa, 0x15, 0x0070}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x70, 0x018d}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x04, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x07, 0x01cb}, + {0xa0, 0x11, 0x0120}, /* gamma ~4 */ + {0xa0, 0x37, 0x0121}, + {0xa0, 0x58, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x91, 0x0124}, + {0xa0, 0xa6, 0x0125}, + {0xa0, 0xb8, 0x0126}, + {0xa0, 0xc7, 0x0127}, + {0xa0, 0xd3, 0x0128}, + {0xa0, 0xde, 0x0129}, + {0xa0, 0xe6, 0x012a}, + {0xa0, 0xed, 0x012b}, + {0xa0, 0xf3, 0x012c}, + {0xa0, 0xf8, 0x012d}, + {0xa0, 0xfb, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x23, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + + {0xa0, 0x4c, 0x010a}, /* matrix */ + {0xa0, 0xf5, 0x010b}, + {0xa0, 0xff, 0x010c}, + {0xa0, 0xf9, 0x010d}, + {0xa0, 0x51, 0x010e}, + {0xa0, 0xf5, 0x010f}, + {0xa0, 0xfb, 0x0110}, + {0xa0, 0xed, 0x0111}, + {0xa0, 0x5f, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x20, 0x0087}, + {0xa0, 0x21, 0x0088}, + {0xaa, 0x20, 0x0004}, + {0xaa, 0x21, 0x003d}, + {0xaa, 0x03, 0x0041}, + {0xaa, 0x04, 0x0010}, + {0xaa, 0x05, 0x003d}, + {0xaa, 0x0e, 0x0001}, + {0xaa, 0x0f, 0x0000}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x04, 0x0191}, + {0xa0, 0x3d, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x9b, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x41, 0x001d}, + {0xa0, 0x6f, 0x001e}, + {0xa0, 0xad, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x0f, 0x0087}, + {0xa0, 0x0e, 0x0088}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0195}, + {0xa1, 0x01, 0x0196}, + {0xa1, 0x01, 0x0197}, + {0xa0, 0x3d, 0x0192}, + {0xa0, 0x04, 0x0191}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x1d, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x85, 0x0118}, + {0xa1, 0x01, 0x0116}, + {0xa1, 0x01, 0x0118}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x1d, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x85, 0x0118}, + {0xa1, 0x01, 0x0116}, + {0xa1, 0x01, 0x0118}, +/* {0xa0, 0x02, 0x0008}, */ + {0xa0, 0x00, 0x0007}, + {0, 0, 0} +}; + +static struct usb_action hdcs2020xx_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0e, 0x0010}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x08, 0x008d}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x03, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x03, 0x011c}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xe6, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x86, 0x009e}, + {0xaa, 0x02, 0x0002}, + {0xaa, 0x07, 0x0006}, + {0xaa, 0x08, 0x0002}, + {0xaa, 0x09, 0x0006}, + {0xaa, 0x0a, 0x0001}, + {0xaa, 0x0b, 0x0001}, + {0xaa, 0x0c, 0x0008}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x10, 0x0000}, + {0xaa, 0x12, 0x0005}, + {0xaa, 0x13, 0x0063}, + {0xaa, 0x15, 0x0070}, + {0xa0, 0xb7, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x70, 0x018d}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x04, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x07, 0x01cb}, + {0xa0, 0x11, 0x0120}, /* gamma ~4*/ + {0xa0, 0x37, 0x0121}, + {0xa0, 0x58, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x91, 0x0124}, + {0xa0, 0xa6, 0x0125}, + {0xa0, 0xb8, 0x0126}, + {0xa0, 0xc7, 0x0127}, + {0xa0, 0xd3, 0x0128}, + {0xa0, 0xde, 0x0129}, + {0xa0, 0xe6, 0x012a}, + {0xa0, 0xed, 0x012b}, + {0xa0, 0xf3, 0x012c}, + {0xa0, 0xf8, 0x012d}, + {0xa0, 0xfb, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x23, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x60, 0x010a}, /* matrix */ + {0xa0, 0xff, 0x010b}, + {0xa0, 0xff, 0x010c}, + {0xa0, 0xff, 0x010d}, + {0xa0, 0x60, 0x010e}, + {0xa0, 0xff, 0x010f}, + {0xa0, 0xff, 0x0110}, + {0xa0, 0xff, 0x0111}, + {0xa0, 0x60, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x20, 0x0087}, + {0xa0, 0x21, 0x0088}, + {0xaa, 0x20, 0x0002}, + {0xaa, 0x21, 0x001b}, + {0xaa, 0x03, 0x0044}, + {0xaa, 0x04, 0x0008}, + {0xaa, 0x05, 0x001b}, + {0xaa, 0x0e, 0x0001}, + {0xaa, 0x0f, 0x0000}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x02, 0x0191}, + {0xa0, 0x1b, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x4d, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x44, 0x001d}, + {0xa0, 0x6f, 0x001e}, + {0xa0, 0xad, 0x001f}, + {0xa0, 0xeb, 0x0020}, + {0xa0, 0x0f, 0x0087}, + {0xa0, 0x0e, 0x0088}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0195}, + {0xa1, 0x01, 0x0196}, + {0xa1, 0x01, 0x0197}, + {0xa0, 0x1b, 0x0192}, + {0xa0, 0x02, 0x0191}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x1d, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x99, 0x0118}, + {0xa1, 0x01, 0x0116}, + {0xa1, 0x01, 0x0118}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x1d, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x99, 0x0118}, +/* {0xa0, 0x02, 0x0008}, */ + {0xa0, 0x00, 0x0007}, +/* {0xa0, 0x18, 0x00fe}, */ + {0, 0, 0} +}; +static struct usb_action hdcs2020xb_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x11, 0x0002}, + {0xa0, 0x03, 0x0008}, /* qtable 0x05 */ + {0xa0, 0x08, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xaa, 0x1c, 0x0000}, + {0xaa, 0x0a, 0x0001}, + {0xaa, 0x0b, 0x0006}, + {0xaa, 0x0c, 0x007b}, + {0xaa, 0x0d, 0x00a7}, + {0xaa, 0x03, 0x00fb}, + {0xaa, 0x05, 0x0000}, + {0xaa, 0x06, 0x0003}, + {0xaa, 0x09, 0x0008}, + + {0xaa, 0x0f, 0x0018}, /* set sensor gain */ + {0xaa, 0x10, 0x0018}, + {0xaa, 0x11, 0x0018}, + {0xaa, 0x12, 0x0018}, + + {0xaa, 0x15, 0x004e}, + {0xaa, 0x1c, 0x0004}, + {0xa0, 0xb7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x70, 0x018d}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + + {0xa0, 0x66, 0x010a}, /* matrix */ + {0xa0, 0xed, 0x010b}, + {0xa0, 0xed, 0x010c}, + {0xa0, 0xed, 0x010d}, + {0xa0, 0x66, 0x010e}, + {0xa0, 0xed, 0x010f}, + {0xa0, 0xed, 0x0110}, + {0xa0, 0xed, 0x0111}, + {0xa0, 0x66, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x13, 0x0031}, + {0xaa, 0x14, 0x0001}, + {0xaa, 0x0e, 0x0004}, + {0xaa, 0x19, 0x00cd}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x02, 0x0191}, + {0xa0, 0x62, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x3d, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + + {0xa0, 0x0c, 0x01a9}, /* 0x14 */ + {0xa0, 0x28, 0x01aa}, + {0xa0, 0x04, 0x001d}, + {0xa0, 0x18, 0x001e}, + {0xa0, 0x2c, 0x001f}, + {0xa0, 0x41, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; +static struct usb_action hdcs2020xb_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xaa, 0x1c, 0x0000}, + {0xaa, 0x0a, 0x0001}, + {0xaa, 0x0b, 0x0006}, + {0xaa, 0x0c, 0x007a}, + {0xaa, 0x0d, 0x00a7}, + {0xaa, 0x03, 0x00fb}, + {0xaa, 0x05, 0x0000}, + {0xaa, 0x06, 0x0003}, + {0xaa, 0x09, 0x0008}, + {0xaa, 0x0f, 0x0018}, /* original setting */ + {0xaa, 0x10, 0x0018}, + {0xaa, 0x11, 0x0018}, + {0xaa, 0x12, 0x0018}, + {0xaa, 0x15, 0x004e}, + {0xaa, 0x1c, 0x0004}, + {0xa0, 0xf7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x70, 0x018d}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x66, 0x010a}, /* matrix */ + {0xa0, 0xed, 0x010b}, + {0xa0, 0xed, 0x010c}, + {0xa0, 0xed, 0x010d}, + {0xa0, 0x66, 0x010e}, + {0xa0, 0xed, 0x010f}, + {0xa0, 0xed, 0x0110}, + {0xa0, 0xed, 0x0111}, + {0xa0, 0x66, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + /**** set exposure ***/ + {0xaa, 0x13, 0x0031}, + {0xaa, 0x14, 0x0001}, + {0xaa, 0x0e, 0x0004}, + {0xaa, 0x19, 0x00cd}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x02, 0x0191}, + {0xa0, 0x62, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x3d, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x0c, 0x01a9}, + {0xa0, 0x28, 0x01aa}, + {0xa0, 0x04, 0x001d}, + {0xa0, 0x18, 0x001e}, + {0xa0, 0x2c, 0x001f}, + {0xa0, 0x41, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; +static struct usb_action hdcs2020b_50HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ + {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ + {0xa0, 0x76, 0x0192}, /* 01,92,76,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x46, 0x0197}, /* 01,97,46,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x28, 0x01aa}, /* 01,aa,28,cc */ + {0xa0, 0x05, 0x001d}, /* 00,1d,05,cc */ + {0xa0, 0x1a, 0x001e}, /* 00,1e,1a,cc */ + {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ + {0, 0, 0} +}; +static struct usb_action hdcs2020b_60HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ + {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ + {0xa0, 0x62, 0x0192}, /* 01,92,62,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x3d, 0x0197}, /* 01,97,3d,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x28, 0x01aa}, /* 01,aa,28,cc */ + {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ + {0xa0, 0x18, 0x001e}, /* 00,1e,18,cc */ + {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ + {0, 0, 0} +}; +static struct usb_action hdcs2020b_NoFliker[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ + {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ + {0xa0, 0x70, 0x0192}, /* 01,92,70,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ + {0xa0, 0x17, 0x001e}, /* 00,1e,17,cc */ + {0xa0, 0x2a, 0x001f}, /* 00,1f,2a,cc */ + {0, 0, 0} +}; + +static struct usb_action hv7131bxx_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x00, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xaa, 0x30, 0x002d}, + {0xaa, 0x01, 0x0005}, + {0xaa, 0x11, 0x0000}, + {0xaa, 0x13, 0x0001}, /* {0xaa, 0x13, 0x0000}, */ + {0xaa, 0x14, 0x0001}, + {0xaa, 0x15, 0x00e8}, + {0xaa, 0x16, 0x0002}, + {0xaa, 0x17, 0x0086}, + {0xaa, 0x31, 0x0038}, + {0xaa, 0x32, 0x0038}, + {0xaa, 0x33, 0x0038}, + {0xaa, 0x5b, 0x0001}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x68, 0x018d}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0xc0, 0x019b}, + {0xa0, 0xa0, 0x019c}, + {0xa0, 0x02, 0x0188}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ + {0xa1, 0x01, 0x0002}, + {0xa0, 0x00, 0x0092}, + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x25, 0x0007}, + {0xaa, 0x26, 0x00a1}, + {0xaa, 0x27, 0x0020}, + {0xaa, 0x20, 0x0000}, + {0xaa, 0x21, 0x00a0}, + {0xaa, 0x22, 0x0016}, + {0xaa, 0x23, 0x0040}, + + {0xa0, 0x10, 0x0190}, /* 2F */ + {0xa0, 0x04, 0x0191}, /* 4d */ + {0xa0, 0x60, 0x0192}, + {0xa0, 0x01, 0x0195}, + {0xa0, 0x86, 0x0196}, + {0xa0, 0xa0, 0x0197}, + {0xa0, 0x07, 0x018c}, + {0xa0, 0x0f, 0x018f}, + {0xa0, 0x18, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x00, 0x001d}, + {0xa0, 0xa0, 0x001e}, + {0xa0, 0x16, 0x001f}, + {0xa0, 0x40, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa1, 0x01, 0x001d}, + {0xa1, 0x01, 0x001e}, + {0xa1, 0x01, 0x001f}, + {0xa1, 0x01, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, +/* {0xa0, 0x02, 0x0008}, */ + {0, 0, 0} +}; + +static struct usb_action hv7131bxx_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x00, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xaa, 0x30, 0x002d}, + {0xaa, 0x01, 0x0005}, + {0xaa, 0x11, 0x0001}, + {0xaa, 0x13, 0x0000}, /* {0xaa, 0x13, 0x0001}; */ + {0xaa, 0x14, 0x0001}, + {0xaa, 0x15, 0x00e6}, + {0xaa, 0x16, 0x0002}, + {0xaa, 0x17, 0x0086}, + {0xaa, 0x31, 0x0038}, + {0xaa, 0x32, 0x0038}, + {0xaa, 0x33, 0x0038}, + {0xaa, 0x5b, 0x0001}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x70, 0x018d}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0xc0, 0x019b}, + {0xa0, 0xa0, 0x019c}, + {0xa0, 0x02, 0x0188}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ + {0xa1, 0x01, 0x0002}, + {0xa0, 0x00, 0x0092}, + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x25, 0x0007}, + {0xaa, 0x26, 0x00a1}, + {0xaa, 0x27, 0x0020}, + {0xaa, 0x20, 0x0000}, + {0xaa, 0x21, 0x0040}, + {0xaa, 0x22, 0x0013}, + {0xaa, 0x23, 0x004c}, + {0xa0, 0x10, 0x0190}, /* 2f */ + {0xa0, 0x04, 0x0191}, /* 4d */ + {0xa0, 0x60, 0x0192}, /* 60 */ + {0xa0, 0x00, 0x0195}, + {0xa0, 0xc3, 0x0196}, + {0xa0, 0x50, 0x0197}, + {0xa0, 0x0c, 0x018c}, + {0xa0, 0x18, 0x018f}, + {0xa0, 0x18, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0x00, 0x001d}, + {0xa0, 0x40, 0x001e}, + {0xa0, 0x13, 0x001f}, + {0xa0, 0x4c, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa1, 0x01, 0x001d}, + {0xa1, 0x01, 0x001e}, + {0xa1, 0x01, 0x001f}, + {0xa1, 0x01, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, +/* {0xa0, 0x02, 0x0008}, */ + {0, 0, 0} +}; + +static struct usb_action hv7131cxx_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x01, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x0012}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0x05, 0x0012}, + {0xaa, 0x01, 0x000c}, + {0xaa, 0x11, 0x0000}, + {0xaa, 0x13, 0x0000}, + {0xaa, 0x14, 0x0001}, + {0xaa, 0x15, 0x00e8}, + {0xaa, 0x16, 0x0002}, + {0xaa, 0x17, 0x0088}, + + {0xa0, 0x00, 0x0019}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x89, 0x018d}, + {0xa0, 0x50, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0xc0, 0x019b}, + {0xa0, 0xa0, 0x019c}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa0, 0x00, 0x0092}, + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x60, 0x010a}, /* matrix */ + {0xa0, 0xf0, 0x010b}, + {0xa0, 0xf0, 0x010c}, + {0xa0, 0xf0, 0x010d}, + {0xa0, 0x60, 0x010e}, + {0xa0, 0xf0, 0x010f}, + {0xa0, 0xf0, 0x0110}, + {0xa0, 0xf0, 0x0111}, + {0xa0, 0x60, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x25, 0x0007}, + {0xaa, 0x26, 0x0053}, + {0xaa, 0x27, 0x0000}, + + {0xa0, 0x10, 0x0190}, /* 2f */ + {0xa0, 0x04, 0x0191}, /* 9b */ + {0xa0, 0x60, 0x0192}, /* 80 */ + {0xa0, 0x01, 0x0195}, + {0xa0, 0xd4, 0x0196}, + {0xa0, 0xc0, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x13, 0x01aa}, + {0xa1, 0x01, 0x001d}, + {0xa1, 0x01, 0x001e}, + {0xa1, 0x01, 0x001f}, + {0xa1, 0x01, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action hv7131cxx_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + + {0xa0, 0x00, 0x0002}, /* diff */ + {0xa0, 0x01, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x03, 0x0008}, + + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x0012}, + + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, /* 1e0 */ + + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0x05, 0x0012}, + {0xaa, 0x01, 0x000c}, + {0xaa, 0x11, 0x0000}, + {0xaa, 0x13, 0x0000}, + {0xaa, 0x14, 0x0001}, + {0xaa, 0x15, 0x00e8}, + {0xaa, 0x16, 0x0002}, + {0xaa, 0x17, 0x0088}, + + {0xa0, 0x00, 0x0019}, /* 00 */ + + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x89, 0x018d}, + {0xa0, 0x50, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0xc0, 0x019b}, + {0xa0, 0xa0, 0x019c}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa0, 0x00, 0x0092}, /* read the i2c chips ident */ + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x60, 0x010a}, /* matrix */ + {0xa0, 0xf0, 0x010b}, + {0xa0, 0xf0, 0x010c}, + {0xa0, 0xf0, 0x010d}, + {0xa0, 0x60, 0x010e}, + {0xa0, 0xf0, 0x010f}, + {0xa0, 0xf0, 0x0110}, + {0xa0, 0xf0, 0x0111}, + {0xa0, 0x60, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x25, 0x0007}, + {0xaa, 0x26, 0x0053}, + {0xaa, 0x27, 0x0000}, + + {0xa0, 0x10, 0x0190}, /* 2f */ + {0xa0, 0x04, 0x0191}, /* 9b */ + {0xa0, 0x60, 0x0192}, /* 80 */ + + {0xa0, 0x01, 0x0195}, + {0xa0, 0xd4, 0x0196}, + {0xa0, 0xc0, 0x0197}, + + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x13, 0x01aa}, + {0xa1, 0x01, 0x001d}, + {0xa1, 0x01, 0x001e}, + {0xa1, 0x01, 0x001f}, + {0xa1, 0x01, 0x0020}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action icm105axx_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0c, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0xa1, 0x008b}, + {0xa0, 0x00, 0x0097}, + {0xa0, 0x01, 0x0098}, + {0xa0, 0x00, 0x0099}, + {0xa0, 0x01, 0x009a}, + {0xa0, 0x01, 0x011a}, + {0xa0, 0x01, 0x011c}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xaa, 0x01, 0x0010}, + {0xaa, 0x03, 0x0000}, + {0xaa, 0x04, 0x0001}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0001}, + {0xaa, 0x04, 0x0011}, + {0xaa, 0x05, 0x00a0}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0002}, + {0xaa, 0x04, 0x0013}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0003}, + {0xaa, 0x04, 0x0015}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0004}, + {0xaa, 0x04, 0x0017}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x000d}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0005}, + {0xaa, 0x04, 0x0019}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0006}, + {0xaa, 0x04, 0x0017}, + {0xaa, 0x05, 0x0026}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0007}, + {0xaa, 0x04, 0x0019}, + {0xaa, 0x05, 0x0022}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0008}, + {0xaa, 0x04, 0x0021}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0009}, + {0xaa, 0x04, 0x0023}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x000d}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000a}, + {0xaa, 0x04, 0x0025}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000b}, + {0xaa, 0x04, 0x00ec}, + {0xaa, 0x05, 0x002e}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000c}, + {0xaa, 0x04, 0x00fa}, + {0xaa, 0x05, 0x002a}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x07, 0x000d}, + {0xaa, 0x01, 0x0005}, + {0xaa, 0x94, 0x0002}, + {0xaa, 0x90, 0x0000}, + {0xaa, 0x91, 0x001f}, + {0xaa, 0x10, 0x0064}, + {0xaa, 0x9b, 0x00f0}, + {0xaa, 0x9c, 0x0002}, + {0xaa, 0x14, 0x001a}, + {0xaa, 0x20, 0x0080}, + {0xaa, 0x22, 0x0080}, + {0xaa, 0x24, 0x0080}, + {0xaa, 0x26, 0x0080}, + {0xaa, 0x00, 0x0084}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xaa, 0xa8, 0x00c0}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0xa1, 0x01, 0x0008}, + + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x52, 0x010a}, /* matrix */ + {0xa0, 0xf7, 0x010b}, + {0xa0, 0xf7, 0x010c}, + {0xa0, 0xf7, 0x010d}, + {0xa0, 0x52, 0x010e}, + {0xa0, 0xf7, 0x010f}, + {0xa0, 0xf7, 0x0110}, + {0xa0, 0xf7, 0x0111}, + {0xa0, 0x52, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x0d, 0x0003}, + {0xaa, 0x0c, 0x008c}, + {0xaa, 0x0e, 0x0095}, + {0xaa, 0x0f, 0x0002}, + {0xaa, 0x1c, 0x0094}, + {0xaa, 0x1d, 0x0002}, + {0xaa, 0x20, 0x0080}, + {0xaa, 0x22, 0x0080}, + {0xaa, 0x24, 0x0080}, + {0xaa, 0x26, 0x0080}, + {0xaa, 0x00, 0x0084}, + {0xa0, 0x02, 0x00a3}, + {0xa0, 0x94, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x04, 0x0191}, + {0xa0, 0x20, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x84, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x12, 0x01aa}, + {0xa0, 0xe3, 0x001d}, + {0xa0, 0xec, 0x001e}, + {0xa0, 0xf5, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0xc0, 0x01a8}, + {0xa0, 0xc0, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; + +static struct usb_action icm105axx_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0c, 0x0010}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0xa1, 0x008b}, + {0xa0, 0x00, 0x0097}, + {0xa0, 0x02, 0x0098}, + {0xa0, 0x00, 0x0099}, + {0xa0, 0x02, 0x009a}, + {0xa0, 0x02, 0x011a}, + {0xa0, 0x02, 0x011c}, + {0xa0, 0x01, 0x009b}, + {0xa0, 0xe6, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x86, 0x009e}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xaa, 0x01, 0x0010}, + {0xaa, 0x03, 0x0000}, + {0xaa, 0x04, 0x0001}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0001}, + {0xaa, 0x04, 0x0011}, + {0xaa, 0x05, 0x00a0}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0002}, + {0xaa, 0x04, 0x0013}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0001}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0003}, + {0xaa, 0x04, 0x0015}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0004}, + {0xaa, 0x04, 0x0017}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x000d}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0005}, + {0xa0, 0x04, 0x0092}, + {0xa0, 0x19, 0x0093}, + {0xa0, 0x01, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xaa, 0x05, 0x0020}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0006}, + {0xaa, 0x04, 0x0017}, + {0xaa, 0x05, 0x0026}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0007}, + {0xaa, 0x04, 0x0019}, + {0xaa, 0x05, 0x0022}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0008}, + {0xaa, 0x04, 0x0021}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x0009}, + {0xaa, 0x04, 0x0023}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x000d}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000a}, + {0xaa, 0x04, 0x0025}, + {0xaa, 0x05, 0x00aa}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000b}, + {0xaa, 0x04, 0x00ec}, + {0xaa, 0x05, 0x002e}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x03, 0x000c}, + {0xaa, 0x04, 0x00fa}, + {0xaa, 0x05, 0x002a}, + {0xaa, 0x06, 0x0005}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x07, 0x000d}, + {0xaa, 0x01, 0x0005}, + {0xaa, 0x94, 0x0002}, + {0xaa, 0x90, 0x0000}, + {0xaa, 0x91, 0x0010}, + {0xaa, 0x10, 0x0064}, + {0xaa, 0x9b, 0x00f0}, + {0xaa, 0x9c, 0x0002}, + {0xaa, 0x14, 0x001a}, + {0xaa, 0x20, 0x0080}, + {0xaa, 0x22, 0x0080}, + {0xaa, 0x24, 0x0080}, + {0xaa, 0x26, 0x0080}, + {0xaa, 0x00, 0x0084}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xaa, 0xa8, 0x0080}, + {0xa0, 0x78, 0x018d}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0xa1, 0x01, 0x0008}, + + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x52, 0x010a}, /* matrix */ + {0xa0, 0xf7, 0x010b}, + {0xa0, 0xf7, 0x010c}, + {0xa0, 0xf7, 0x010d}, + {0xa0, 0x52, 0x010e}, + {0xa0, 0xf7, 0x010f}, + {0xa0, 0xf7, 0x0110}, + {0xa0, 0xf7, 0x0111}, + {0xa0, 0x52, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x0d, 0x0003}, + {0xaa, 0x0c, 0x0020}, + {0xaa, 0x0e, 0x000e}, + {0xaa, 0x0f, 0x0002}, + {0xaa, 0x1c, 0x000d}, + {0xaa, 0x1d, 0x0002}, + {0xaa, 0x20, 0x0080}, + {0xaa, 0x22, 0x0080}, + {0xaa, 0x24, 0x0080}, + {0xaa, 0x26, 0x0080}, + {0xaa, 0x00, 0x0084}, + {0xa0, 0x02, 0x00a3}, + {0xa0, 0x0d, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x04, 0x0191}, + {0xa0, 0x1a, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x4b, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x12, 0x01aa}, + {0xa0, 0xc8, 0x001d}, + {0xa0, 0xd8, 0x001e}, + {0xa0, 0xea, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x00, 0x01a7}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, 0x0116}, + {0xa0, 0x40, 0x0117}, + {0xa0, 0x40, 0x0118}, + {0, 0, 0} +}; +static struct usb_action icm105a_50HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ + {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x000d}, /* 00,1c,0d,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x0d, 0x00a4}, /* 00,a4,0d,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x1a, 0x0192}, /* 01,92,1a,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x4b, 0x0197}, /* 01,97,4b,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ + {0xa0, 0xc8, 0x001d}, /* 00,1d,c8,cc */ + {0xa0, 0xd8, 0x001e}, /* 00,1e,d8,cc */ + {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0, 0, 0} +}; +static struct usb_action icm105a_50HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ + {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x0094}, /* 00,1c,94,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x94, 0x00a4}, /* 00,a4,94,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x84, 0x0197}, /* 01,97,84,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ + {0xa0, 0xe3, 0x001d}, /* 00,1d,e3,cc */ + {0xa0, 0xec, 0x001e}, /* 00,1e,ec,cc */ + {0xa0, 0xf5, 0x001f}, /* 00,1f,f5,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ + {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0, 0, 0} +}; +static struct usb_action icm105a_60HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ + {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x0008}, /* 00,1c,08,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x08, 0x00a4}, /* 00,a4,08,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x10, 0x0192}, /* 01,92,10,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x41, 0x0197}, /* 01,97,41,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ + {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0, 0, 0} +}; +static struct usb_action icm105a_60HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ + {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x0085}, /* 00,1c,85,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x85, 0x00a4}, /* 00,a4,85,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x08, 0x0192}, /* 01,92,08,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x81, 0x0197}, /* 01,97,81,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ + {0xa0, 0xc2, 0x001d}, /* 00,1d,c2,cc */ + {0xa0, 0xd6, 0x001e}, /* 00,1e,d6,cc */ + {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ + {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0, 0, 0} +}; +static struct usb_action icm105a_NoFliker[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ + {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x0000}, /* 00,1c,00,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x00, 0x00a4}, /* 00,a4,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0, 0, 0} +}; +static struct usb_action icm105a_NoFlikerScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ + {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ + {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */ + {0xaa, 0x0f, 0x0002}, /* 00,0f,02,aa */ + {0xaa, 0x1c, 0x0080}, /* 00,1c,80,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x20, 0x0080}, /* 00,20,80,aa */ + {0xaa, 0x22, 0x0080}, /* 00,22,80,aa */ + {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ + {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ + {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ + {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ + {0xa0, 0x80, 0x00a4}, /* 00,a4,80,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ + {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_InitialScale[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x00, 0x0002}, /* 00,02,00,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xd8, 0x0006}, /* 00,06,d8,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0x01, 0x009b}, /* 00,9b,01,cc */ + {0xa0, 0xde, 0x009c}, /* 00,9c,de,cc */ + {0xa0, 0x02, 0x009d}, /* 00,9d,02,cc */ + {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xa0, 0x33, 0x0086}, /* 00,86,33,cc */ + {0xa0, 0x34, 0x0087}, /* 00,87,34,cc */ + {0xa0, 0x35, 0x0088}, /* 00,88,35,cc */ + {0xa0, 0xb0, 0x008b}, /* 00,8b,b0,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ + {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ + {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ + {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ + {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ + {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ + {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ + {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ + {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ + {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ + {0xaa, 0x18, 0x00de}, /* 00,18,de,aa */ + {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ + {0xaa, 0x1a, 0x0086}, /* 00,1a,86,aa */ + {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ + {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ + {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ + {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ + {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ + {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ + {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ + {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ + {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ + {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ + {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ + {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ + {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ + {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ + {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ + {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ + {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ + {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ + {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ + {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ + {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ + {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ + {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ + {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ + {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ + {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ + {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ + {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ + {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ + {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ + {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ + {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ + {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ + {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ + {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ + {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ + {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ + {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ + {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ + {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ + {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x1c, 0x0050}, /* 00,1C,50,aa */ + {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ + {0xaa, 0x3b, 0x001d}, /* 00,3b,1D,aa */ + {0xaa, 0x3c, 0x004c}, /* 00,3c,4C,aa */ + {0xaa, 0x3d, 0x0018}, /* 00,3d,18,aa */ + {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */ + {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ + {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x37, 0x0101}, /* 01,01,37,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ + {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */ + {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ + {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ + {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ + {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ + {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ + {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ + + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ + {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ + {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_Initial[] = { /* 320x240 */ + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xd0, 0x0006}, /* 00,06,d0,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0x01, 0x009b}, /* 00,9b,01,cc */ + {0xa0, 0xd8, 0x009c}, /* 00,9c,d8,cc */ + {0xa0, 0x02, 0x009d}, /* 00,9d,02,cc */ + {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xa0, 0x33, 0x0086}, /* 00,86,33,cc */ + {0xa0, 0x34, 0x0087}, /* 00,87,34,cc */ + {0xa0, 0x35, 0x0088}, /* 00,88,35,cc */ + {0xa0, 0xb0, 0x008b}, /* 00,8b,b0,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ + {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ + {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ + {0xaa, 0x03, 0x0000}, /* 00,03,00,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x11, 0x0080}, /* 00,11,80,aa */ + {0xaa, 0x12, 0x0000}, /* 00,12,00,aa */ + {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ + {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ + {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ + {0xaa, 0x16, 0x0000}, /* 00,16,00,aa */ + {0xaa, 0x17, 0x0001}, /* 00,17,01,aa */ + {0xaa, 0x18, 0x00d8}, /* 00,18,d8,aa */ + {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ + {0xaa, 0x1a, 0x0088}, /* 00,1a,88,aa */ + {0xaa, 0x20, 0x00a8}, /* 00,20,a8,aa */ + {0xaa, 0x22, 0x0000}, /* 00,22,00,aa */ + {0xaa, 0x23, 0x0000}, /* 00,23,00,aa */ + {0xaa, 0x24, 0x0000}, /* 00,24,00,aa */ + {0xaa, 0x40, 0x0033}, /* 00,40,33,aa */ + {0xaa, 0x41, 0x0077}, /* 00,41,77,aa */ + {0xaa, 0x42, 0x0053}, /* 00,42,53,aa */ + {0xaa, 0x43, 0x00b0}, /* 00,43,b0,aa */ + {0xaa, 0x4b, 0x0001}, /* 00,4b,01,aa */ + {0xaa, 0x72, 0x0020}, /* 00,72,20,aa */ + {0xaa, 0x73, 0x0000}, /* 00,73,00,aa */ + {0xaa, 0x80, 0x0000}, /* 00,80,00,aa */ + {0xaa, 0x85, 0x0050}, /* 00,85,50,aa */ + {0xaa, 0x91, 0x0070}, /* 00,91,70,aa */ + {0xaa, 0x92, 0x0072}, /* 00,92,72,aa */ + {0xaa, 0x03, 0x0001}, /* 00,03,01,aa */ + {0xaa, 0x10, 0x00a0}, /* 00,10,a0,aa */ + {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ + {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ + {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ + {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ + {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ + {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ + {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ + {0xaa, 0xa4, 0x0010}, /* 00,a4,10,aa */ + {0xaa, 0xa5, 0x0020}, /* 00,a5,20,aa */ + {0xaa, 0xb1, 0x0044}, /* 00,b1,44,aa */ + {0xaa, 0xd0, 0x0001}, /* 00,d0,01,aa */ + {0xaa, 0xd1, 0x0085}, /* 00,d1,85,aa */ + {0xaa, 0xd2, 0x0080}, /* 00,d2,80,aa */ + {0xaa, 0xd3, 0x0080}, /* 00,d3,80,aa */ + {0xaa, 0xd4, 0x0080}, /* 00,d4,80,aa */ + {0xaa, 0xd5, 0x0080}, /* 00,d5,80,aa */ + {0xaa, 0xc0, 0x00c3}, /* 00,c0,c3,aa */ + {0xaa, 0xc2, 0x0044}, /* 00,c2,44,aa */ + {0xaa, 0xc4, 0x0040}, /* 00,c4,40,aa */ + {0xaa, 0xc5, 0x0020}, /* 00,c5,20,aa */ + {0xaa, 0xc6, 0x0008}, /* 00,c6,08,aa */ + {0xaa, 0x03, 0x0004}, /* 00,03,04,aa */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa */ + {0xaa, 0x40, 0x0030}, /* 00,40,30,aa */ + {0xaa, 0x41, 0x0020}, /* 00,41,20,aa */ + {0xaa, 0x42, 0x002d}, /* 00,42,2d,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x1c, 0x0050}, /* 00,1c,50,aa */ + {0xaa, 0x11, 0x0081}, /* 00,11,81,aa */ + {0xaa, 0x3b, 0x003a}, /* 00,3b,3A,aa */ + {0xaa, 0x3c, 0x0098}, /* 00,3c,98,aa */ + {0xaa, 0x3d, 0x0030}, /* 00,3d,30,aa */ + {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ + {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ + {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x37, 0x0101}, /* 01,01,37,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ + {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */ + {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x50, 0x0010}, /* 00,50,10,aa */ + {0xaa, 0x51, 0x0010}, /* 00,51,10,aa */ + {0xaa, 0x54, 0x0010}, /* 00,54,10,aa */ + {0xaa, 0x55, 0x0010}, /* 00,55,10,aa */ + {0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */ + {0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ + {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ + {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_50HZ[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ + {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ + {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ + {0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */ + {0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */ + {0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ + {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ + {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_50HZScale[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ + {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ + {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ + {0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */ + {0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */ + {0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ + {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ + {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_60HZ[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ + {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ + {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ + {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ + {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ + {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ + {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ + {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_60HZScale[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ + {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ + {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ + {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ + {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ + {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ + {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ + {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_NoFliker[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ + {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ + {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ + {0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */ + {0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */ + {0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */ + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ + {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ + {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ + {0, 0, 0} +}; + +static struct usb_action MC501CB_NoFlikerScale[] = { + {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ + {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ + {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ + {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ + {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ + {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ + {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ + {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ + {0, 0, 0} +}; + +/* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ +static struct usb_action OV7620_mode0[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x40, 0x0002}, /* 00,02,40,cc */ + {0xa0, 0x00, 0x0008}, /* 00,08,00,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x06, 0x0010}, /* 00,10,06,cc */ + {0xa0, 0x02, 0x0083}, /* 00,83,02,cc */ + {0xa0, 0x01, 0x0085}, /* 00,85,01,cc */ + {0xa0, 0x80, 0x0086}, /* 00,86,80,cc */ + {0xa0, 0x81, 0x0087}, /* 00,87,81,cc */ + {0xa0, 0x10, 0x0088}, /* 00,88,10,cc */ + {0xa0, 0xa1, 0x008b}, /* 00,8b,a1,cc */ + {0xa0, 0x08, 0x008d}, /* 00,8d,08,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xd8, 0x0006}, /* 00,06,d8,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xde, 0x009c}, /* 00,9c,de,cc */ + {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ + {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ + {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ + {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ + {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ + {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ + {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ + {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ + {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ + {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ + {0xaa, 0x1a, 0x00f1}, /* 00,1a,f1,aa */ + {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ + {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ + {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ + {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ + {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ + {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ + {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ + {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ + {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ + {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ + {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ + {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ + {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ + {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ + {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ + {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ + {0xa0, 0x77, 0x0101}, /* 01,01,77,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x68, 0x0116}, /* 01,16,68,cc */ + {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ + {0xa0, 0x40, 0x011d}, /* 01,1d,40,cc */ + {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ + {0, 0, 0} +}; + +/* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ +static struct usb_action OV7620_mode1[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x50, 0x0002}, /* 00,02,50,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,00,cc */ /* mx change? */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x06, 0x0010}, /* 00,10,06,cc */ + {0xa0, 0x02, 0x0083}, /* 00,83,02,cc */ + {0xa0, 0x01, 0x0085}, /* 00,85,01,cc */ + {0xa0, 0x80, 0x0086}, /* 00,86,80,cc */ + {0xa0, 0x81, 0x0087}, /* 00,87,81,cc */ + {0xa0, 0x10, 0x0088}, /* 00,88,10,cc */ + {0xa0, 0xa1, 0x008b}, /* 00,8b,a1,cc */ + {0xa0, 0x08, 0x008d}, /* 00,8d,08,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xd0, 0x0006}, /* 00,06,d0,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xd6, 0x009c}, /* 00,9c,d6,cc */ /* OV7648 00,9c,d8,cc */ + {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ + {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ + {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ + {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ + {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ + {0xaa, 0x14, 0x0000}, /* 00,14,00,aa */ + {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ + {0xaa, 0x24, 0x0088}, /* 00,24,88,aa */ + {0xaa, 0x25, 0x0078}, /* 00,25,78,aa */ + {0xaa, 0x17, 0x0018}, /* 00,17,18,aa */ + {0xaa, 0x18, 0x00ba}, /* 00,18,ba,aa */ + {0xaa, 0x19, 0x0002}, /* 00,19,02,aa */ + {0xaa, 0x1a, 0x00f2}, /* 00,1a,f2,aa */ + {0xaa, 0x20, 0x0040}, /* 00,20,40,aa */ + {0xaa, 0x27, 0x00f6}, /* 00,27,f6,aa */ + {0xaa, 0x28, 0x00a0}, /* 00,28,a0,aa */ + {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ + {0xaa, 0x2a, 0x0083}, /* 00,2a,83,aa */ + {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ + {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ + {0xaa, 0x74, 0x0020}, /* 00,74,20,aa */ + {0xaa, 0x61, 0x0068}, /* 00,61,68,aa */ + {0xaa, 0x64, 0x0088}, /* 00,64,88,aa */ + {0xaa, 0x00, 0x0000}, /* 00,00,00,aa */ + {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ + {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ + {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ + {0xa0, 0x77, 0x0101}, /* 01,01,77,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x68, 0x0116}, /* 01,16,68,cc */ + {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ + {0xa0, 0x50, 0x011d}, /* 01,1d,50,cc */ + {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ + {0, 0, 0} +}; + +/* from zs211.inf - HKR,%OV7620%\AE,50HZ */ +static struct usb_action OV7620_50HZ[] = { + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ + {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ + {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ + {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ + {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ +/* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ + {0, 0, 0} +}; + +/* from zs211.inf - HKR,%OV7620%\AE,60HZ */ +static struct usb_action OV7620_60HZ[] = { + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ + {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ + {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ + {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */ + {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ +/* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ +/* ?? in gspca v1, it was + {0xa0, 0x00, 0x0039}, * 00,00,00,dd * + {0xa1, 0x01, 0x0037}, */ + {0, 0, 0} +}; + +/* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ +static struct usb_action OV7620_NoFliker[] = { + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ + {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */ + {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ + {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x01, 0x0197}, /* 01,97,01,cc */ +/* {0xa0, 0x44, 0x0002}, * 00,02,44,cc - if mode1 (320x240) */ +/* ?? was + {0xa0, 0x00, 0x0039}, * 00,00,00,dd * + {0xa1, 0x01, 0x0037}, */ + {0, 0, 0} +}; + +static struct usb_action ov7630c_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x06, 0x0010}, + {0xa0, 0xa1, 0x008b}, + {0xa0, 0x08, 0x008d}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0012}, + {0xaa, 0x12, 0x0080}, + {0xa0, 0x02, 0x0083}, + {0xa0, 0x01, 0x0085}, + {0xa0, 0x90, 0x0086}, + {0xa0, 0x91, 0x0087}, + {0xa0, 0x10, 0x0088}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xd8, 0x009c}, + {0xa0, 0x88, 0x009e}, + {0xaa, 0x12, 0x0069}, + {0xaa, 0x04, 0x0020}, + {0xaa, 0x06, 0x0050}, + {0xaa, 0x13, 0x0083}, + {0xaa, 0x14, 0x0000}, + {0xaa, 0x15, 0x0024}, + {0xaa, 0x17, 0x0018}, + {0xaa, 0x18, 0x00ba}, + {0xaa, 0x19, 0x0002}, + {0xaa, 0x1a, 0x00f6}, + {0xaa, 0x1b, 0x0002}, + {0xaa, 0x20, 0x00c2}, + {0xaa, 0x24, 0x0060}, + {0xaa, 0x25, 0x0040}, + {0xaa, 0x26, 0x0030}, + {0xaa, 0x27, 0x00ea}, + {0xaa, 0x28, 0x00a0}, + {0xaa, 0x21, 0x0000}, + {0xaa, 0x2a, 0x0081}, + {0xaa, 0x2b, 0x0096}, + {0xaa, 0x2d, 0x0094}, + {0xaa, 0x2f, 0x003d}, + {0xaa, 0x30, 0x0024}, + {0xaa, 0x60, 0x0000}, + {0xaa, 0x61, 0x0040}, + {0xaa, 0x68, 0x007c}, + {0xaa, 0x6f, 0x0015}, + {0xaa, 0x75, 0x0088}, + {0xaa, 0x77, 0x00b5}, + {0xaa, 0x01, 0x0060}, + {0xaa, 0x02, 0x0060}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x46, 0x0118}, + {0xa0, 0x04, 0x0113}, +/* 0x10, */ + {0xa1, 0x01, 0x0002}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, +/* 0x03, */ + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, +/* 0x05, */ + {0xa1, 0x01, 0x01c8}, +/* 0x07, */ + {0xa1, 0x01, 0x01c9}, +/* 0x0f, */ + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x01, 0x0120}, /* gamma 2 ?*/ + {0xa0, 0x0c, 0x0121}, + {0xa0, 0x1f, 0x0122}, + {0xa0, 0x3a, 0x0123}, + {0xa0, 0x53, 0x0124}, + {0xa0, 0x6d, 0x0125}, + {0xa0, 0x85, 0x0126}, + {0xa0, 0x9c, 0x0127}, + {0xa0, 0xb0, 0x0128}, + {0xa0, 0xc2, 0x0129}, + {0xa0, 0xd1, 0x012a}, + {0xa0, 0xde, 0x012b}, + {0xa0, 0xe9, 0x012c}, + {0xa0, 0xf2, 0x012d}, + {0xa0, 0xf9, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x05, 0x0130}, + {0xa0, 0x0f, 0x0131}, + {0xa0, 0x16, 0x0132}, + {0xa0, 0x1a, 0x0133}, + {0xa0, 0x19, 0x0134}, + {0xa0, 0x19, 0x0135}, + {0xa0, 0x17, 0x0136}, + {0xa0, 0x15, 0x0137}, + {0xa0, 0x12, 0x0138}, + {0xa0, 0x10, 0x0139}, + {0xa0, 0x0e, 0x013a}, + {0xa0, 0x0b, 0x013b}, + {0xa0, 0x09, 0x013c}, + {0xa0, 0x08, 0x013d}, + {0xa0, 0x06, 0x013e}, + {0xa0, 0x03, 0x013f}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xaa, 0x10, 0x001b}, + {0xaa, 0x76, 0x0002}, + {0xaa, 0x2a, 0x0081}, + {0xaa, 0x2b, 0x0000}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x01, 0x0191}, + {0xa0, 0xb8, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x37, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x26, 0x01aa}, + {0xa0, 0x50, 0x011d}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0180}, + {0xaa, 0x13, 0x0083}, /* 40 */ + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action ov7630c_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x06, 0x0010}, + {0xa0, 0xa1, 0x008b}, + {0xa0, 0x08, 0x008d}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0012}, + + {0xaa, 0x12, 0x0080}, + {0xa0, 0x02, 0x0083}, + {0xa0, 0x01, 0x0085}, + {0xa0, 0x90, 0x0086}, + {0xa0, 0x91, 0x0087}, + {0xa0, 0x10, 0x0088}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xe6, 0x009c}, + {0xa0, 0x86, 0x009e}, + {0xaa, 0x12, 0x0069}, /* i2c */ + {0xaa, 0x04, 0x0020}, + {0xaa, 0x06, 0x0050}, + {0xaa, 0x13, 0x00c3}, + {0xaa, 0x14, 0x0000}, + {0xaa, 0x15, 0x0024}, + {0xaa, 0x19, 0x0003}, + {0xaa, 0x1a, 0x00f6}, + {0xaa, 0x1b, 0x0002}, + {0xaa, 0x20, 0x00c2}, + {0xaa, 0x24, 0x0060}, + {0xaa, 0x25, 0x0040}, + {0xaa, 0x26, 0x0030}, + {0xaa, 0x27, 0x00ea}, + {0xaa, 0x28, 0x00a0}, + {0xaa, 0x21, 0x0000}, + {0xaa, 0x2a, 0x0081}, + {0xaa, 0x2b, 0x0096}, + {0xaa, 0x2d, 0x0084}, + {0xaa, 0x2f, 0x003d}, + {0xaa, 0x30, 0x0024}, + {0xaa, 0x60, 0x0000}, + {0xaa, 0x61, 0x0040}, + {0xaa, 0x68, 0x007c}, + {0xaa, 0x6f, 0x0015}, + {0xaa, 0x75, 0x0088}, + {0xaa, 0x77, 0x00b5}, + {0xaa, 0x01, 0x0060}, + {0xaa, 0x02, 0x0060}, + {0xaa, 0x17, 0x0018}, + {0xaa, 0x18, 0x00ba}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x77, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x04, 0x01a7}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x0116}, + {0xa0, 0x46, 0x0118}, + {0xa0, 0x04, 0x0113}, + + {0xa1, 0x01, 0x0002}, + {0xa0, 0x4e, 0x010a}, /* matrix */ + {0xa0, 0xfe, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf7, 0x010d}, + {0xa0, 0x4d, 0x010e}, + {0xa0, 0xfc, 0x010f}, + {0xa0, 0x00, 0x0110}, + {0xa0, 0xf6, 0x0111}, + {0xa0, 0x4a, 0x0112}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + + {0xa1, 0x01, 0x01c8}, + + {0xa1, 0x01, 0x01c9}, + + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x16, 0x0120}, /* gamma ~4 */ + {0xa0, 0x3a, 0x0121}, + {0xa0, 0x5b, 0x0122}, + {0xa0, 0x7c, 0x0123}, + {0xa0, 0x94, 0x0124}, + {0xa0, 0xa9, 0x0125}, + {0xa0, 0xbb, 0x0126}, + {0xa0, 0xca, 0x0127}, + {0xa0, 0xd7, 0x0128}, + {0xa0, 0xe1, 0x0129}, + {0xa0, 0xea, 0x012a}, + {0xa0, 0xf1, 0x012b}, + {0xa0, 0xf7, 0x012c}, + {0xa0, 0xfc, 0x012d}, + {0xa0, 0xff, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x20, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x00, 0x013e}, + {0xa0, 0x01, 0x013f}, + {0xa0, 0x4e, 0x010a}, /* matrix */ + {0xa0, 0xfe, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf7, 0x010d}, + {0xa0, 0x4d, 0x010e}, + {0xa0, 0xfc, 0x010f}, + {0xa0, 0x00, 0x0110}, + {0xa0, 0xf6, 0x0111}, + {0xa0, 0x4a, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xaa, 0x10, 0x000d}, + {0xaa, 0x76, 0x0002}, + {0xaa, 0x2a, 0x0081}, + {0xaa, 0x2b, 0x0000}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x00, 0x0191}, + {0xa0, 0xd8, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x1b, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x10, 0x01a9}, + {0xa0, 0x26, 0x01aa}, + {0xa0, 0x50, 0x011d}, + {0xa0, 0x02, 0x0180}, + {0xa0, 0x40, 0x0180}, + {0xaa, 0x13, 0x00c3}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action pas106b_Initial_com[] = { +/* Sream and Sensor specific */ + {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */ +/* System */ + {0xa0, 0x01, 0x0000}, /* SystemControl */ + {0xa0, 0x01, 0x0000}, /* SystemControl */ +/* Picture size */ + {0xa0, 0x00, 0x0002}, /* ClockSelect */ + {0xa0, 0x03, 0x003a}, + {0xa0, 0x0c, 0x003b}, + {0xa0, 0x04, 0x0038}, + {0, 0, 0} +}; + +static struct usb_action pas106b_Initial[] = { /* 176x144 */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Sream and Sensor specific */ + {0xa0, 0x0f, 0x0010}, /* CMOSSensorSelect */ +/* Picture size */ + {0xa0, 0x00, 0x0003}, /* FrameWidthHigh 00 */ + {0xa0, 0xb0, 0x0004}, /* FrameWidthLow B0 */ + {0xa0, 0x00, 0x0005}, /* FrameHeightHigh 00 */ + {0xa0, 0x90, 0x0006}, /* FrameHightLow 90 */ +/* System */ + {0xa0, 0x01, 0x0001}, /* SystemOperating */ +/* Sream and Sensor specific */ + {0xa0, 0x03, 0x0012}, /* VideoControlFunction */ + {0xa0, 0x01, 0x0012}, /* VideoControlFunction */ +/* Sensor Interface */ + {0xa0, 0x08, 0x008d}, /* Compatibily Mode */ +/* Window inside sensor array */ + {0xa0, 0x03, 0x009a}, /* WinXStartLow */ + {0xa0, 0x00, 0x011a}, /* FirstYLow */ + {0xa0, 0x03, 0x011c}, /* FirstxLow */ + {0xa0, 0x28, 0x009c}, /* WinHeightLow */ + {0xa0, 0x68, 0x009e}, /* WinWidthLow */ +/* Init the sensor */ + {0xaa, 0x02, 0x0004}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x09, 0x0005}, + {0xaa, 0x0a, 0x0002}, + {0xaa, 0x0b, 0x0002}, + {0xaa, 0x0c, 0x0005}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x0e, 0x0002}, + {0xaa, 0x14, 0x0081}, + +/* Other registors */ + {0xa0, 0x37, 0x0101}, /* SensorCorrection */ +/* Frame retreiving */ + {0xa0, 0x00, 0x0019}, /* AutoAdjustFPS */ +/* Gains */ + {0xa0, 0xa0, 0x01a8}, /* DigitalGain */ +/* Unknown */ + {0xa0, 0x00, 0x01ad}, +/* Sharpness */ + {0xa0, 0x03, 0x01c5}, /* SharpnessMode */ + {0xa0, 0x13, 0x01cb}, /* Sharpness05 */ +/* Other registors */ + {0xa0, 0x0d, 0x0100}, /* OperationMode */ +/* Auto exposure and white balance */ + {0xa0, 0x06, 0x0189}, /* AWBStatus */ +/*Dead pixels */ + {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ +/* EEPROM */ + {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Unknown */ + {0xa0, 0x08, 0x01c6}, +/* Sharpness */ + {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ +/* Other registers */ + {0xa0, 0x0d, 0x0100}, /* OperationMode */ +/* Auto exposure and white balance */ + {0xa0, 0x06, 0x0189}, /* AWBStatus */ +/*Dead pixels */ + {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ +/* EEPROM */ + {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Sharpness */ + {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ + {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, +/* Auto correction */ + {0xa0, 0x03, 0x0181}, /* WinXstart */ + {0xa0, 0x08, 0x0182}, /* WinXWidth */ + {0xa0, 0x16, 0x0183}, /* WinXCenter */ + {0xa0, 0x03, 0x0184}, /* WinYStart */ + {0xa0, 0x05, 0x0185}, /* WinYWidth */ + {0xa0, 0x14, 0x0186}, /* WinYCenter */ + {0xa0, 0x00, 0x0180}, /* AutoCorrectEnable */ + +/* Auto exposure and white balance */ + {0xa0, 0x00, 0x0190}, /* ExposureLimitHigh */ + {0xa0, 0x03, 0x0191}, /* ExposureLimitMid */ + {0xa0, 0xb1, 0x0192}, /* ExposureLimitLow */ + {0xa0, 0x00, 0x0195}, /* AntiFlickerHigh */ + {0xa0, 0x00, 0x0196}, /* AntiFlickerLow */ + {0xa0, 0x87, 0x0197}, /* AntiFlickerLow */ + {0xa0, 0x0c, 0x018c}, /* AEBFreeze */ + {0xa0, 0x18, 0x018f}, /* AEBUnfreeze */ +/* sensor on */ + {0xaa, 0x07, 0x00b1}, + {0xaa, 0x05, 0x0003}, + {0xaa, 0x04, 0x0001}, + {0xaa, 0x03, 0x003b}, +/* Gains */ + {0xa0, 0x20, 0x01a9}, /* DigitalLimitDiff */ + {0xa0, 0x26, 0x01aa}, /* DigitalGainStep */ + {0xa0, 0xa0, 0x011d}, /* GlobalGain */ + {0xa0, 0x60, 0x011d}, /* GlobalGain */ +/* Auto correction */ + {0xa0, 0x40, 0x0180}, /* AutoCorrectEnable */ + {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x42, 0x0180}, /* AutoCorrectEnable */ +/* Gains */ + {0xa0, 0x40, 0x0116}, /* RGain */ + {0xa0, 0x40, 0x0117}, /* GGain */ + {0xa0, 0x40, 0x0118}, /* BGain */ + {0, 0, 0} +}; + +static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Sream and Sensor specific */ + {0xa0, 0x0f, 0x0010}, /* CMOSSensorSelect */ +/* Picture size */ + {0xa0, 0x01, 0x0003}, /* FrameWidthHigh */ + {0xa0, 0x60, 0x0004}, /* FrameWidthLow */ + {0xa0, 0x01, 0x0005}, /* FrameHeightHigh */ + {0xa0, 0x20, 0x0006}, /* FrameHightLow */ +/* System */ + {0xa0, 0x01, 0x0001}, /* SystemOperating */ +/* Sream and Sensor specific */ + {0xa0, 0x03, 0x0012}, /* VideoControlFunction */ + {0xa0, 0x01, 0x0012}, /* VideoControlFunction */ +/* Sensor Interface */ + {0xa0, 0x08, 0x008d}, /* Compatibily Mode */ +/* Window inside sensor array */ + {0xa0, 0x03, 0x009a}, /* WinXStartLow */ + {0xa0, 0x00, 0x011a}, /* FirstYLow */ + {0xa0, 0x03, 0x011c}, /* FirstxLow */ + {0xa0, 0x28, 0x009c}, /* WinHeightLow */ + {0xa0, 0x68, 0x009e}, /* WinWidthLow */ +/* Init the sensor */ + {0xaa, 0x02, 0x0004}, + {0xaa, 0x08, 0x0000}, + {0xaa, 0x09, 0x0005}, + {0xaa, 0x0a, 0x0002}, + {0xaa, 0x0b, 0x0002}, + {0xaa, 0x0c, 0x0005}, + {0xaa, 0x0d, 0x0000}, + {0xaa, 0x0e, 0x0002}, + {0xaa, 0x14, 0x0081}, + +/* Other registors */ + {0xa0, 0x37, 0x0101}, /* SensorCorrection */ +/* Frame retreiving */ + {0xa0, 0x00, 0x0019}, /* AutoAdjustFPS */ +/* Gains */ + {0xa0, 0xa0, 0x01a8}, /* DigitalGain */ +/* Unknown */ + {0xa0, 0x00, 0x01ad}, +/* Sharpness */ + {0xa0, 0x03, 0x01c5}, /* SharpnessMode */ + {0xa0, 0x13, 0x01cb}, /* Sharpness05 */ +/* Other registors */ + {0xa0, 0x0d, 0x0100}, /* OperationMode */ +/* Auto exposure and white balance */ + {0xa0, 0x06, 0x0189}, /* AWBStatus */ + {0xa0, 0x80, 0x018d}, /* ????????? */ +/*Dead pixels */ + {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ +/* EEPROM */ + {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Unknown */ + {0xa0, 0x08, 0x01c6}, +/* Sharpness */ + {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ +/* Other registers */ + {0xa0, 0x0d, 0x0100}, /* OperationMode */ +/* Auto exposure and white balance */ + {0xa0, 0x06, 0x0189}, /* AWBStatus */ +/*Dead pixels */ + {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ +/* EEPROM */ + {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ +/* JPEG control */ + {0xa0, 0x03, 0x0008}, /* ClockSetting */ +/* Sharpness */ + {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ + {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + + {0xa0, 0x58, 0x010a}, /* matrix */ + {0xa0, 0xf4, 0x010b}, + {0xa0, 0xf4, 0x010c}, + {0xa0, 0xf4, 0x010d}, + {0xa0, 0x58, 0x010e}, + {0xa0, 0xf4, 0x010f}, + {0xa0, 0xf4, 0x0110}, + {0xa0, 0xf4, 0x0111}, + {0xa0, 0x58, 0x0112}, +/* Auto correction */ + {0xa0, 0x03, 0x0181}, /* WinXstart */ + {0xa0, 0x08, 0x0182}, /* WinXWidth */ + {0xa0, 0x16, 0x0183}, /* WinXCenter */ + {0xa0, 0x03, 0x0184}, /* WinYStart */ + {0xa0, 0x05, 0x0185}, /* WinYWidth */ + {0xa0, 0x14, 0x0186}, /* WinYCenter */ + {0xa0, 0x00, 0x0180}, /* AutoCorrectEnable */ + +/* Auto exposure and white balance */ + {0xa0, 0x00, 0x0190}, /* ExposureLimitHigh 0 */ + {0xa0, 0x03, 0x0191}, /* ExposureLimitMid */ + {0xa0, 0xb1, 0x0192}, /* ExposureLimitLow 0xb1 */ + + {0xa0, 0x00, 0x0195}, /* AntiFlickerHigh 0x00 */ + {0xa0, 0x00, 0x0196}, /* AntiFlickerLow 0x00 */ + {0xa0, 0x87, 0x0197}, /* AntiFlickerLow 0x87 */ + + {0xa0, 0x10, 0x018c}, /* AEBFreeze 0x10 0x0c */ + {0xa0, 0x20, 0x018f}, /* AEBUnfreeze 0x30 0x18 */ +/* sensor on */ + {0xaa, 0x07, 0x00b1}, + {0xaa, 0x05, 0x0003}, + {0xaa, 0x04, 0x0001}, + {0xaa, 0x03, 0x003b}, +/* Gains */ + {0xa0, 0x20, 0x01a9}, /* DigitalLimitDiff */ + {0xa0, 0x26, 0x01aa}, /* DigitalGainStep */ + {0xa0, 0xa0, 0x011d}, /* GlobalGain */ + {0xa0, 0x60, 0x011d}, /* GlobalGain */ +/* Auto correction */ + {0xa0, 0x40, 0x0180}, /* AutoCorrectEnable */ + {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x42, 0x0180}, /* AutoCorrectEnable */ +/* Gains */ + {0xa0, 0x40, 0x0116}, /* RGain */ + {0xa0, 0x40, 0x0117}, /* GGain */ + {0xa0, 0x40, 0x0118}, /* BGain */ + + {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ + {0xa0, 0xff, 0x0018}, /* Frame adjust */ + {0, 0, 0} +}; +static struct usb_action pas106b_50HZ[] = { + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ + {0xa0, 0x54, 0x0192}, /* 01,92,54,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x87, 0x0197}, /* 01,97,87,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x30, 0x018f}, /* 01,8f,30,cc */ + {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */ + {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */ + {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ + {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ + {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ + {0, 0, 0} +}; +static struct usb_action pas106b_60HZ[] = { + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ + {0xa0, 0x2e, 0x0192}, /* 01,92,2e,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x71, 0x0197}, /* 01,97,71,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x30, 0x018f}, /* 01,8f,30,cc */ + {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */ + {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */ + {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ + {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ + {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ + {0, 0, 0} +}; +static struct usb_action pas106b_NoFliker[] = { + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ + {0xa0, 0x50, 0x0192}, /* 01,92,50,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */ + {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ + {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ + {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0, 0, 0} +}; + +/* Aurelien setting from snoop */ +static struct usb_action pb03303x_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0xdc, 0x008b}, /* 8b -> dc */ + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xdc, 0x008b}, + {0xaa, 0x01, 0x0001}, + {0xaa, 0x06, 0x0000}, + {0xaa, 0x08, 0x0483}, + {0xaa, 0x01, 0x0004}, + {0xaa, 0x08, 0x0006}, + {0xaa, 0x02, 0x0011}, + {0xaa, 0x03, 0x01e7}, + {0xaa, 0x04, 0x0287}, + {0xaa, 0x07, 0x3002}, + {0xaa, 0x20, 0x1100}, + {0xaa, 0x35, 0x0050}, + {0xaa, 0x30, 0x0005}, + {0xaa, 0x31, 0x0000}, + {0xaa, 0x58, 0x0078}, + {0xaa, 0x62, 0x0411}, + {0xaa, 0x2b, 0x0028}, + {0xaa, 0x2c, 0x0030}, + {0xaa, 0x2d, 0x0030}, + {0xaa, 0x2e, 0x0028}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x78, 0x018d}, + {0xa0, 0x61, 0x0116}, + {0xa0, 0x65, 0x0118}, + + {0xa1, 0x01, 0x0002}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x0d, 0x003a}, + {0xa0, 0x02, 0x003b}, + {0xa0, 0x00, 0x0038}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x05, 0x0009}, + {0xaa, 0x09, 0x0134}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xec, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x9c, 0x0197}, + {0xa0, 0x0e, 0x018c}, + {0xa0, 0x1c, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0xd7, 0x001d}, + {0xa0, 0xf4, 0x001e}, + {0xa0, 0xf9, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action pb03303x_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0xdc, 0x008b}, /* 8b -> dc */ + {0xa0, 0x01, 0x0001}, + {0xa0, 0x03, 0x0012}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xdc, 0x008b}, + {0xaa, 0x01, 0x0001}, + {0xaa, 0x06, 0x0000}, + {0xaa, 0x08, 0x0483}, + {0xaa, 0x01, 0x0004}, + {0xaa, 0x08, 0x0006}, + {0xaa, 0x02, 0x0011}, + {0xaa, 0x03, 0x01e7}, + {0xaa, 0x04, 0x0287}, + {0xaa, 0x07, 0x3002}, + {0xaa, 0x20, 0x1100}, + {0xaa, 0x35, 0x0050}, + {0xaa, 0x30, 0x0005}, + {0xaa, 0x31, 0x0000}, + {0xaa, 0x58, 0x0078}, + {0xaa, 0x62, 0x0411}, + {0xaa, 0x2b, 0x0028}, + {0xaa, 0x2c, 0x0030}, + {0xaa, 0x2d, 0x0030}, + {0xaa, 0x2e, 0x0028}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x78, 0x018d}, + {0xa0, 0x61, 0x0116}, + {0xa0, 0x65, 0x0118}, + + {0xa1, 0x01, 0x0002}, + + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + + {0xa0, 0x0d, 0x003a}, + {0xa0, 0x02, 0x003b}, + {0xa0, 0x00, 0x0038}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x13, 0x0120}, /* gamma 4 */ + {0xa0, 0x38, 0x0121}, + {0xa0, 0x59, 0x0122}, + {0xa0, 0x79, 0x0123}, + {0xa0, 0x92, 0x0124}, + {0xa0, 0xa7, 0x0125}, + {0xa0, 0xb9, 0x0126}, + {0xa0, 0xc8, 0x0127}, + {0xa0, 0xd4, 0x0128}, + {0xa0, 0xdf, 0x0129}, + {0xa0, 0xe7, 0x012a}, + {0xa0, 0xee, 0x012b}, + {0xa0, 0xf4, 0x012c}, + {0xa0, 0xf9, 0x012d}, + {0xa0, 0xfc, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x26, 0x0130}, + {0xa0, 0x22, 0x0131}, + {0xa0, 0x20, 0x0132}, + {0xa0, 0x1c, 0x0133}, + {0xa0, 0x16, 0x0134}, + {0xa0, 0x13, 0x0135}, + {0xa0, 0x10, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x06, 0x013b}, + {0xa0, 0x05, 0x013c}, + {0xa0, 0x04, 0x013d}, + {0xa0, 0x03, 0x013e}, + {0xa0, 0x02, 0x013f}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x05, 0x0009}, + {0xaa, 0x09, 0x0134}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xec, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x9c, 0x0197}, + {0xa0, 0x0e, 0x018c}, + {0xa0, 0x1c, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0xd7, 0x001d}, + {0xa0, 0xf4, 0x001e}, + {0xa0, 0xf9, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; +static struct usb_action pb0330xx_Initial[] = { + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0x05, 0x0012}, + {0xaa, 0x01, 0x0006}, + {0xaa, 0x02, 0x0011}, + {0xaa, 0x03, 0x01e7}, + {0xaa, 0x04, 0x0287}, + {0xaa, 0x06, 0x0003}, + {0xaa, 0x07, 0x3002}, + {0xaa, 0x20, 0x1100}, + {0xaa, 0x2f, 0xf7b0}, + {0xaa, 0x30, 0x0005}, + {0xaa, 0x31, 0x0000}, + {0xaa, 0x34, 0x0100}, + {0xaa, 0x35, 0x0060}, + {0xaa, 0x3d, 0x068f}, + {0xaa, 0x40, 0x01e0}, + {0xaa, 0x58, 0x0078}, + {0xaa, 0x62, 0x0411}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x6c, 0x018d}, + {0xa1, 0x01, 0x0002}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x00, 0x0092}, + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x05, 0x0066}, + {0xaa, 0x09, 0x02b2}, + {0xaa, 0x10, 0x0002}, + + {0xa0, 0x60, 0x011d}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0x8c, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x8a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0xd7, 0x001d}, + {0xa0, 0xf0, 0x001e}, + {0xa0, 0xf8, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0007}, +/* {0xa0, 0x30, 0x0007}, */ +/* {0xa0, 0x00, 0x0007}, */ + {0, 0, 0} +}; + +static struct usb_action pb0330xx_InitialScale[] = { + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, /* 00 */ + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x00, 0x0002}, /* 10 */ + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0x05, 0x0012}, + {0xaa, 0x01, 0x0006}, + {0xaa, 0x02, 0x0011}, + {0xaa, 0x03, 0x01e7}, + {0xaa, 0x04, 0x0287}, + {0xaa, 0x06, 0x0003}, + {0xaa, 0x07, 0x3002}, + {0xaa, 0x20, 0x1100}, + {0xaa, 0x2f, 0xf7b0}, + {0xaa, 0x30, 0x0005}, + {0xaa, 0x31, 0x0000}, + {0xaa, 0x34, 0x0100}, + {0xaa, 0x35, 0x0060}, + {0xaa, 0x3d, 0x068f}, + {0xaa, 0x40, 0x01e0}, + {0xaa, 0x58, 0x0078}, + {0xaa, 0x62, 0x0411}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x6c, 0x018d}, + {0xa1, 0x01, 0x0002}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x00, 0x0092}, + {0xa0, 0x02, 0x0090}, + {0xa1, 0x01, 0x0091}, + {0xa1, 0x01, 0x0095}, + {0xa1, 0x01, 0x0096}, + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x50, 0x010a}, /* matrix */ + {0xa0, 0xf8, 0x010b}, + {0xa0, 0xf8, 0x010c}, + {0xa0, 0xf8, 0x010d}, + {0xa0, 0x50, 0x010e}, + {0xa0, 0xf8, 0x010f}, + {0xa0, 0xf8, 0x0110}, + {0xa0, 0xf8, 0x0111}, + {0xa0, 0x50, 0x0112}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0x05, 0x0066}, + {0xaa, 0x09, 0x02b2}, + {0xaa, 0x10, 0x0002}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0x8c, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x8a, 0x0197}, + {0xa0, 0x10, 0x018c}, + {0xa0, 0x20, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0xd7, 0x001d}, + {0xa0, 0xf0, 0x001e}, + {0xa0, 0xf8, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa1, 0x01, 0x0008}, + {0xa1, 0x01, 0x0007}, +/* {0xa0, 0x30, 0x0007}, */ +/* {0xa0, 0x00, 0x0007}, */ + {0, 0, 0} +}; +static struct usb_action pb0330_50HZ[] = { + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xee, 0x0192}, /* 01,92,ee,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x46, 0x0197}, /* 01,97,46,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0x68, 0x001d}, /* 00,1d,68,cc */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0, 0, 0} +}; +static struct usb_action pb0330_50HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xa0, 0x0192}, /* 01,92,a0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x7a, 0x0197}, /* 01,97,7a,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0xe5, 0x001d}, /* 00,1d,e5,cc */ + {0xa0, 0xf0, 0x001e}, /* 00,1e,f0,cc */ + {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ + {0, 0, 0} +}; +static struct usb_action pb0330_60HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xdd, 0x0192}, /* 01,92,dd,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x3d, 0x0197}, /* 01,97,3d,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0x43, 0x001d}, /* 00,1d,43,cc */ + {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ + {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0, 0, 0} +}; +static struct usb_action pb0330_60HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xa0, 0x0192}, /* 01,92,a0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x7a, 0x0197}, /* 01,97,7a,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0x41, 0x001d}, /* 00,1d,41,cc */ + {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ + {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0, 0, 0} +}; +static struct usb_action pb0330_NoFliker[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ + {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ + {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0, 0, 0} +}; +static struct usb_action pb0330_NoFlikerScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ + {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ + {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0, 0, 0} +}; + +/* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ +static struct usb_action PO2030_mode0[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x04, 0x0002}, /* 00,02,04,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x04, 0x0080}, /* 00,80,04,cc */ + {0xa0, 0x05, 0x0081}, /* 00,81,05,cc */ + {0xa0, 0x16, 0x0083}, /* 00,83,16,cc */ + {0xa0, 0x18, 0x0085}, /* 00,85,18,cc */ + {0xa0, 0x1a, 0x0086}, /* 00,86,1a,cc */ + {0xa0, 0x1b, 0x0087}, /* 00,87,1b,cc */ + {0xa0, 0x1c, 0x0088}, /* 00,88,1c,cc */ + {0xa0, 0xee, 0x008b}, /* 00,8b,ee,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xe6, 0x009c}, /* 00,9c,e6,cc */ + {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */ + {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ + {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */ + {0xaa, 0x0f, 0x00eb}, /* 00,0f,eb,aa */ + {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ + {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ + {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ + {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ + {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ + {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ + {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ + {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ + {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ + {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ + {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ + {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ + {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ + {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ + {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ + {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ + {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ + {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ + {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ + {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ + {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ + {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ + {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ + {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ + {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ + {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ + {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ + {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ + {0xa0, 0xf7, 0x0101}, /* 01,01,f7,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ + {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ + {0, 0, 0} +}; + +/* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ +static struct usb_action PO2030_mode1[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ + {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ + {0xa0, 0x04, 0x0080}, /* 00,80,04,cc */ + {0xa0, 0x05, 0x0081}, /* 00,81,05,cc */ + {0xa0, 0x16, 0x0083}, /* 00,83,16,cc */ + {0xa0, 0x18, 0x0085}, /* 00,85,18,cc */ + {0xa0, 0x1a, 0x0086}, /* 00,86,1a,cc */ + {0xa0, 0x1b, 0x0087}, /* 00,87,1b,cc */ + {0xa0, 0x1c, 0x0088}, /* 00,88,1c,cc */ + {0xa0, 0xee, 0x008b}, /* 00,8b,ee,cc */ + {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ + {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc */ + {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */ + {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ + {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */ + {0xaa, 0x0f, 0x00ed}, /* 00,0f,ed,aa */ + {0xaa, 0x87, 0x0000}, /* 00,87,00,aa */ + {0xaa, 0x88, 0x0004}, /* 00,88,04,aa */ + {0xaa, 0x89, 0x0000}, /* 00,89,00,aa */ + {0xaa, 0x8a, 0x0005}, /* 00,8a,05,aa */ + {0xaa, 0x13, 0x0003}, /* 00,13,03,aa */ + {0xaa, 0x16, 0x0040}, /* 00,16,40,aa */ + {0xaa, 0x18, 0x0040}, /* 00,18,40,aa */ + {0xaa, 0x1d, 0x0002}, /* 00,1d,02,aa */ + {0xaa, 0x29, 0x00e8}, /* 00,29,e8,aa */ + {0xaa, 0x45, 0x0045}, /* 00,45,45,aa */ + {0xaa, 0x50, 0x00ed}, /* 00,50,ed,aa */ + {0xaa, 0x51, 0x0025}, /* 00,51,25,aa */ + {0xaa, 0x52, 0x0042}, /* 00,52,42,aa */ + {0xaa, 0x53, 0x002f}, /* 00,53,2f,aa */ + {0xaa, 0x79, 0x0025}, /* 00,79,25,aa */ + {0xaa, 0x7b, 0x0000}, /* 00,7b,00,aa */ + {0xaa, 0x7e, 0x0025}, /* 00,7e,25,aa */ + {0xaa, 0x7f, 0x0025}, /* 00,7f,25,aa */ + {0xaa, 0x21, 0x0000}, /* 00,21,00,aa */ + {0xaa, 0x33, 0x0036}, /* 00,33,36,aa */ + {0xaa, 0x36, 0x0060}, /* 00,36,60,aa */ + {0xaa, 0x37, 0x0008}, /* 00,37,08,aa */ + {0xaa, 0x3b, 0x0031}, /* 00,3b,31,aa */ + {0xaa, 0x44, 0x000f}, /* 00,44,0f,aa */ + {0xaa, 0x58, 0x0002}, /* 00,58,02,aa */ + {0xaa, 0x66, 0x00c0}, /* 00,66,c0,aa */ + {0xaa, 0x67, 0x0044}, /* 00,67,44,aa */ + {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ + {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ + {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ + {0xa0, 0xf7, 0x0101}, /* 01,01,f7,cc */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ + {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ + {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ + {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ + {0, 0, 0} +}; + +static struct usb_action PO2030_50HZ[] = { + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ + {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ + {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */ + {0xa0, 0x05, 0x0190}, /* 01,90,05,cc */ + {0xa0, 0x35, 0x0191}, /* 01,91,35,cc */ + {0xa0, 0x70, 0x0192}, /* 01,92,70,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x85, 0x0196}, /* 01,96,85,cc */ + {0xa0, 0x58, 0x0197}, /* 01,97,58,cc */ + {0xa0, 0x0c, 0x018c}, /* 01,8c,0c,cc */ + {0xa0, 0x18, 0x018f}, /* 01,8f,18,cc */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x22, 0x01aa}, /* 01,aa,22,cc */ + {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0, 0, 0} +}; + +static struct usb_action PO2030_60HZ[] = { + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ + {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ + {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */ + {0xa0, 0x08, 0x0190}, /* 01,90,08,cc */ + {0xa0, 0xae, 0x0191}, /* 01,91,ae,cc */ + {0xa0, 0x80, 0x0192}, /* 01,92,80,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x6f, 0x0196}, /* 01,96,6f,cc */ + {0xa0, 0x20, 0x0197}, /* 01,97,20,cc */ + {0xa0, 0x0c, 0x018c}, /* 01,8c,0c,cc */ + {0xa0, 0x18, 0x018f}, /* 01,8f,18,cc */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ + {0xa0, 0x22, 0x01aa}, /* 01,aa,22,cc */ + {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ /* win: 01,8d,80 */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0, 0, 0} +}; + +static struct usb_action PO2030_NoFliker[] = { + {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ + {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */ + {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ + {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ + {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ + {0, 0, 0} +}; + +/* TEST */ +static struct usb_action tas5130CK_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, 0x003b}, + {0xa0, 0x0e, 0x003a}, + {0xa0, 0x01, 0x0038}, + {0xa0, 0x0b, 0x0039}, + {0xa0, 0x00, 0x0038}, + {0xa0, 0x0b, 0x0039}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x10, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0xdc, 0x008b}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x07, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xdc, 0x008b}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x06, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x08, 0x0092}, + {0xa0, 0x83, 0x0093}, + {0xa0, 0x04, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x01, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x08, 0x0092}, + {0xa0, 0x06, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x02, 0x0092}, + {0xa0, 0x11, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x03, 0x0092}, + {0xa0, 0xE7, 0x0093}, + {0xa0, 0x01, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x04, 0x0092}, + {0xa0, 0x87, 0x0093}, + {0xa0, 0x02, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x07, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x30, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x51, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x35, 0x0092}, + {0xa0, 0x7F, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x30, 0x0092}, + {0xa0, 0x05, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x31, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x58, 0x0092}, + {0xa0, 0x78, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x62, 0x0092}, + {0xa0, 0x11, 0x0093}, + {0xa0, 0x04, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2B, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2c, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2D, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2e, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0xb7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x6c, 0x018d}, + {0xa0, 0x61, 0x0116}, + {0xa0, 0x65, 0x0118}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x4c, 0x010a}, /* matrix */ + {0xa0, 0xf1, 0x010b}, + {0xa0, 0x03, 0x010c}, + {0xa0, 0xfe, 0x010d}, + {0xa0, 0x51, 0x010e}, + {0xa0, 0xf1, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0x03, 0x0111}, + {0xa0, 0x51, 0x0112}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x01c6}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x38, 0x0120}, /* gamma > 5 */ + {0xa0, 0x51, 0x0121}, + {0xa0, 0x6e, 0x0122}, + {0xa0, 0x8c, 0x0123}, + {0xa0, 0xa2, 0x0124}, + {0xa0, 0xb6, 0x0125}, + {0xa0, 0xc8, 0x0126}, + {0xa0, 0xd6, 0x0127}, + {0xa0, 0xe2, 0x0128}, + {0xa0, 0xed, 0x0129}, + {0xa0, 0xf5, 0x012a}, + {0xa0, 0xfc, 0x012b}, + {0xa0, 0xff, 0x012c}, + {0xa0, 0xff, 0x012d}, + {0xa0, 0xff, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x12, 0x0130}, + {0xa0, 0x1b, 0x0131}, + {0xa0, 0x1d, 0x0132}, + {0xa0, 0x1a, 0x0133}, + {0xa0, 0x15, 0x0134}, + {0xa0, 0x12, 0x0135}, + {0xa0, 0x0f, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x05, 0x013b}, + {0xa0, 0x00, 0x013c}, + {0xa0, 0x00, 0x013d}, + {0xa0, 0x00, 0x013e}, + {0xa0, 0x01, 0x013f}, + {0xa0, 0x4c, 0x010a}, /* matrix */ + {0xa0, 0xf1, 0x010b}, + {0xa0, 0x03, 0x010c}, + {0xa0, 0xfe, 0x010d}, + {0xa0, 0x51, 0x010e}, + {0xa0, 0xf1, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0x03, 0x0111}, + {0xa0, 0x51, 0x0112}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0092}, + {0xa0, 0x09, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x09, 0x0092}, + {0xa0, 0x34, 0x0093}, + {0xa0, 0x01, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x07, 0x0191}, + {0xa0, 0xd2, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x9a, 0x0197}, + {0xa0, 0x0e, 0x018c}, + {0xa0, 0x1c, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x66, 0x01aa}, + {0xa0, 0xd7, 0x001d}, + {0xa0, 0xf4, 0x001e}, + {0xa0, 0xf9, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; + +static struct usb_action tas5130CK_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, 0x003b}, + {0xa0, 0x0e, 0x003a}, + {0xa0, 0x01, 0x0038}, + {0xa0, 0x0b, 0x0039}, + {0xa0, 0x00, 0x0038}, + {0xa0, 0x0b, 0x0039}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x0a, 0x0010}, + {0xa0, 0x00, 0x0002}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0xdc, 0x008b}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x07, 0x0012}, + {0xa0, 0x00, 0x0098}, + {0xa0, 0x00, 0x009a}, + {0xa0, 0x00, 0x011a}, + {0xa0, 0x00, 0x011c}, + {0xa0, 0xdc, 0x008b}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, 0x0092}, + {0xa0, 0x01, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x06, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x08, 0x0092}, + {0xa0, 0x83, 0x0093}, + {0xa0, 0x04, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x01, 0x0092}, + {0xa0, 0x04, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x08, 0x0092}, + {0xa0, 0x06, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x02, 0x0092}, + {0xa0, 0x11, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x03, 0x0092}, + {0xa0, 0xe5, 0x0093}, + {0xa0, 0x01, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x04, 0x0092}, + {0xa0, 0x85, 0x0093}, + {0xa0, 0x02, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x07, 0x0092}, + {0xa0, 0x02, 0x0093}, + {0xa0, 0x30, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x20, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x51, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x35, 0x0092}, + {0xa0, 0x7F, 0x0093}, + {0xa0, 0x50, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x30, 0x0092}, + {0xa0, 0x05, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x31, 0x0092}, + {0xa0, 0x00, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x58, 0x0092}, + {0xa0, 0x78, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x62, 0x0092}, + {0xa0, 0x11, 0x0093}, + {0xa0, 0x04, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2B, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2C, 0x0092}, + {0xa0, 0x7F, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2D, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x2e, 0x0092}, + {0xa0, 0x7f, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x10, 0x0087}, + {0xa0, 0xb7, 0x0101}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x6c, 0x018d}, + {0xa0, 0x61, 0x0116}, + {0xa0, 0x65, 0x0118}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x4c, 0x010a}, /* matrix */ + {0xa0, 0xf1, 0x010b}, + {0xa0, 0x03, 0x010c}, + {0xa0, 0xfe, 0x010d}, + {0xa0, 0x51, 0x010e}, + {0xa0, 0xf1, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0x03, 0x0111}, + {0xa0, 0x51, 0x0112}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x08, 0x01c6}, + {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x38, 0x0120}, /* gamma > 5 */ + {0xa0, 0x51, 0x0121}, + {0xa0, 0x6e, 0x0122}, + {0xa0, 0x8c, 0x0123}, + {0xa0, 0xa2, 0x0124}, + {0xa0, 0xb6, 0x0125}, + {0xa0, 0xc8, 0x0126}, + {0xa0, 0xd6, 0x0127}, + {0xa0, 0xe2, 0x0128}, + {0xa0, 0xed, 0x0129}, + {0xa0, 0xf5, 0x012a}, + {0xa0, 0xfc, 0x012b}, + {0xa0, 0xff, 0x012c}, + {0xa0, 0xff, 0x012d}, + {0xa0, 0xff, 0x012e}, + {0xa0, 0xff, 0x012f}, + {0xa0, 0x12, 0x0130}, + {0xa0, 0x1b, 0x0131}, + {0xa0, 0x1d, 0x0132}, + {0xa0, 0x1a, 0x0133}, + {0xa0, 0x15, 0x0134}, + {0xa0, 0x12, 0x0135}, + {0xa0, 0x0f, 0x0136}, + {0xa0, 0x0d, 0x0137}, + {0xa0, 0x0b, 0x0138}, + {0xa0, 0x09, 0x0139}, + {0xa0, 0x07, 0x013a}, + {0xa0, 0x05, 0x013b}, + {0xa0, 0x00, 0x013c}, + {0xa0, 0x00, 0x013d}, + {0xa0, 0x00, 0x013e}, + {0xa0, 0x01, 0x013f}, + {0xa0, 0x4c, 0x010a}, /* matrix */ + {0xa0, 0xf1, 0x010b}, + {0xa0, 0x03, 0x010c}, + {0xa0, 0xfe, 0x010d}, + {0xa0, 0x51, 0x010e}, + {0xa0, 0xf1, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0x03, 0x0111}, + {0xa0, 0x51, 0x0112}, + {0xa0, 0x10, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xa0, 0x05, 0x0092}, + {0xa0, 0x62, 0x0093}, + {0xa0, 0x00, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x09, 0x0092}, + {0xa0, 0xaa, 0x0093}, + {0xa0, 0x01, 0x0094}, + {0xa0, 0x01, 0x0090}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x03, 0x0191}, + {0xa0, 0x9b, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x47, 0x0197}, + {0xa0, 0x0e, 0x018c}, + {0xa0, 0x1c, 0x018f}, + {0xa0, 0x14, 0x01a9}, + {0xa0, 0x66, 0x01aa}, + {0xa0, 0x62, 0x001d}, + {0xa0, 0x90, 0x001e}, + {0xa0, 0xc8, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x60, 0x011d}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x09, 0x01ad}, + {0xa0, 0x15, 0x01ae}, + {0xa0, 0x40, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0xa0, 0x30, 0x0007}, + {0xa0, 0x02, 0x0008}, + {0xa0, 0x00, 0x0007}, + {0xa0, 0x03, 0x0008}, + {0, 0, 0} +}; + +static struct usb_action tas5130cxx_Initial[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x50, 0x0002}, + {0xa0, 0x03, 0x0008}, + {0xa0, 0x02, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x00, 0x0001}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x00a5}, + {0xa0, 0x02, 0x00a6}, + + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + + {0xa0, 0x04, 0x0098}, + {0xa0, 0x0f, 0x009a}, + {0xa0, 0x04, 0x011a}, + {0xa0, 0x0f, 0x011c}, + {0xa0, 0xe8, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x88, 0x009e}, + {0xa0, 0x06, 0x008d}, + {0xa0, 0xf7, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x68, 0x018d}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + {0xa0, 0x03, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x68, 0x010a}, /* matrix */ + {0xa0, 0xec, 0x010b}, + {0xa0, 0xec, 0x010c}, + {0xa0, 0xec, 0x010d}, + {0xa0, 0x68, 0x010e}, + {0xa0, 0xec, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0xec, 0x0111}, + {0xa0, 0x68, 0x0112}, + + {0xa1, 0x01, 0x018d}, + {0xa0, 0x90, 0x018d}, /* 90 */ + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + + {0xaa, 0xa3, 0x0001}, + {0xaa, 0xa4, 0x0077}, + {0xa0, 0x01, 0x00a3}, + {0xa0, 0x77, 0x00a4}, + + {0xa0, 0x00, 0x0190}, /* 00 */ + {0xa0, 0x03, 0x0191}, /* 03 */ + {0xa0, 0xe8, 0x0192}, /* e8 */ + {0xa0, 0x00, 0x0195}, /* 0 */ + {0xa0, 0x00, 0x0196}, /* 0 */ + {0xa0, 0x7d, 0x0197}, /* 7d */ + + {0xa0, 0x0c, 0x018c}, + {0xa0, 0x18, 0x018f}, + {0xa0, 0x08, 0x01a9}, /* 08 */ + {0xa0, 0x24, 0x01aa}, /* 24 */ + {0xa0, 0xf0, 0x001d}, + {0xa0, 0xf4, 0x001e}, + {0xa0, 0xf8, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x03, 0x009f}, + {0xa0, 0xc0, 0x00a0}, + {0xa0, 0x50, 0x011d}, /* 50 */ + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; +static struct usb_action tas5130cxx_InitialScale[] = { + {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, 0x0000}, + {0xa0, 0x40, 0x0002}, + + {0xa0, 0x03, 0x0008}, + {0xa1, 0x01, 0x0008}, + + {0xa0, 0x02, 0x0010}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x00, 0x0001}, + {0xa0, 0x01, 0x0012}, + {0xa0, 0x01, 0x0001}, + {0xa0, 0x05, 0x0012}, + {0xa0, 0x07, 0x00a5}, + {0xa0, 0x02, 0x00a6}, + {0xa0, 0x02, 0x0003}, + {0xa0, 0x80, 0x0004}, + {0xa0, 0x01, 0x0005}, + {0xa0, 0xe0, 0x0006}, + {0xa0, 0x05, 0x0098}, + {0xa0, 0x0f, 0x009a}, + {0xa0, 0x05, 0x011a}, + {0xa0, 0x0f, 0x011c}, + {0xa0, 0xe6, 0x009c}, + {0xa0, 0x02, 0x009d}, + {0xa0, 0x86, 0x009e}, + {0xa0, 0x06, 0x008d}, + {0xa0, 0x37, 0x0101}, + {0xa0, 0x0d, 0x0100}, + {0xa0, 0x06, 0x0189}, + {0xa0, 0x68, 0x018d}, + {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, 0x01ad}, + {0xa0, 0x03, 0x01c5}, + {0xa0, 0x13, 0x01cb}, + {0xa0, 0x08, 0x0250}, + {0xa0, 0x08, 0x0301}, + {0xa1, 0x01, 0x0002}, + {0xa1, 0x01, 0x0008}, + + {0xa0, 0x03, 0x0008}, + {0xa1, 0x01, 0x0008}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, + {0xa1, 0x01, 0x01c8}, + {0xa1, 0x01, 0x01c9}, + {0xa1, 0x01, 0x01ca}, + {0xa0, 0x0f, 0x01cb}, + + {0xa0, 0x68, 0x010a}, /* matrix */ + {0xa0, 0xec, 0x010b}, + {0xa0, 0xec, 0x010c}, + {0xa0, 0xec, 0x010d}, + {0xa0, 0x68, 0x010e}, + {0xa0, 0xec, 0x010f}, + {0xa0, 0xec, 0x0110}, + {0xa0, 0xec, 0x0111}, + {0xa0, 0x68, 0x0112}, + + {0xa1, 0x01, 0x018d}, + {0xa0, 0x90, 0x018d}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, 0x0019}, + {0xaa, 0xa3, 0x0001}, + {0xaa, 0xa4, 0x0063}, + {0xa0, 0x01, 0x00a3}, + {0xa0, 0x63, 0x00a4}, + {0xa0, 0x00, 0x0190}, + {0xa0, 0x02, 0x0191}, + {0xa0, 0x38, 0x0192}, + {0xa0, 0x00, 0x0195}, + {0xa0, 0x00, 0x0196}, + {0xa0, 0x47, 0x0197}, + {0xa0, 0x0c, 0x018c}, + {0xa0, 0x18, 0x018f}, + {0xa0, 0x08, 0x01a9}, + {0xa0, 0x24, 0x01aa}, + {0xa0, 0xd3, 0x001d}, + {0xa0, 0xda, 0x001e}, + {0xa0, 0xea, 0x001f}, + {0xa0, 0xff, 0x0020}, + {0xa0, 0x03, 0x009f}, + {0xa0, 0x4c, 0x00a0}, + {0xa0, 0x50, 0x011d}, + {0xa0, 0x40, 0x0180}, + {0xa1, 0x01, 0x0180}, + {0xa0, 0x42, 0x0180}, + {0, 0, 0} +}; +static struct usb_action tas5130cxx_50HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x63, 0x00a4}, /* 00,a4,63,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ + {0xa0, 0x38, 0x0192}, /* 01,92,38,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x47, 0x0197}, /* 01,97,47,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0xd3, 0x001d}, /* 00,1d,d3,cc */ + {0xa0, 0xda, 0x001e}, /* 00,1e,da,cc */ + {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0, 0, 0} +}; +static struct usb_action tas5130cxx_50HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x77, 0x00a4}, /* 00,a4,77,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ + {0xa0, 0xe8, 0x0192}, /* 01,92,e8,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x7d, 0x0197}, /* 01,97,7d,cc */ + {0xa0, 0x14, 0x018c}, /* 01,8c,14,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0xf0, 0x001d}, /* 00,1d,f0,cc */ + {0xa0, 0xf4, 0x001e}, /* 00,1e,f4,cc */ + {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0, 0, 0} +}; +static struct usb_action tas5130cxx_60HZ[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x36, 0x00a4}, /* 00,a4,36,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x01, 0x0191}, /* 01,91,01,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x3e, 0x0197}, /* 01,97,3e,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0xca, 0x001d}, /* 00,1d,ca,cc */ + {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0, 0, 0} +}; +static struct usb_action tas5130cxx_60HZScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x77, 0x00a4}, /* 00,a4,77,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ + {0xa0, 0xe8, 0x0192}, /* 01,92,e8,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x7d, 0x0197}, /* 01,97,7d,cc */ + {0xa0, 0x14, 0x018c}, /* 01,8c,14,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ + {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ + {0xa0, 0xc8, 0x001d}, /* 00,1d,c8,cc */ + {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0, 0, 0} +}; +static struct usb_action tas5130cxx_NoFliker[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x40, 0x00a4}, /* 00,a4,40,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x01, 0x0191}, /* 01,91,01,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0xbc, 0x001d}, /* 00,1d,bc,cc */ + {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ + {0, 0, 0} +}; + +static struct usb_action tas5130cxx_NoFlikerScale[] = { + {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ + {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */ + {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ + {0xa0, 0x90, 0x00a4}, /* 00,a4,90,cc */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ + {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ + {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ + {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ + {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ + {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ + {0xa0, 0xbc, 0x001d}, /* 00,1d,bc,cc */ + {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ + {0, 0, 0} +}; + +static struct usb_action tas5130c_vf0250_Initial[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ + {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ + {0xa0, 0x10, 0x0002}, /* 00,02,00,cc, 0<->10 */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc, */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc, */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc, */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc, */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc, */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc, */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc, */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc, */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc, */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc, */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc, */ + {0xa0, 0xe8, 0x009c}, /* 00,9c,e6,cc, 6<->8 */ + {0xa0, 0x88, 0x009e}, /* 00,9e,86,cc, 6<->8 */ + {0xa0, 0x10, 0x0087}, /* 00,87,10,cc, */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ + {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ + {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ + {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ + {0xaa, 0x01, 0x0000}, + {0xaa, 0x01, 0x0000}, + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ + {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ + {0xa0, 0x82, 0x0086}, /* 00,86,82,cc, */ + {0xa0, 0x83, 0x0087}, /* 00,87,83,cc, */ + {0xa0, 0x84, 0x0088}, /* 00,88,84,cc, */ + {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ + {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ + {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ + {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ + {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ + {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ + {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ + {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ + {0xa0, 0x00, 0x0039}, + {0xa1, 0x01, 0x0037}, + {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ + {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ + {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ + {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */ + {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ + {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc, */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc, */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc, */ + {0xa0, 0x76, 0x0189}, /* 01,89,76,cc, */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc, */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc, */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc, */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc, */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ + {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ + {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ + {0, 0, 0} +}; + +static struct usb_action tas5130c_vf0250_InitialScale[] = { + {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ + {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ + {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ + {0xa0, 0x00, 0x0002}, /* 00,02,10,cc, */ + {0xa0, 0x02, 0x0003}, /* 00,03,02,cc, */ + {0xa0, 0x80, 0x0004}, /* 00,04,80,cc, */ + {0xa0, 0x01, 0x0005}, /* 00,05,01,cc, */ + {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc, */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xa0, 0x01, 0x0001}, /* 00,01,01,cc, */ + {0xa0, 0x03, 0x0012}, /* 00,12,03,cc, */ + {0xa0, 0x01, 0x0012}, /* 00,12,01,cc, */ + {0xa0, 0x00, 0x0098}, /* 00,98,00,cc, */ + {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc, */ + {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc, */ + {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc, */ + {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc, 8<->6 */ + {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc, 8<->6 */ + {0xa0, 0x10, 0x0087}, /* 00,87,10,cc, */ + {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ + {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ + {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ + {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ + {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ + {0xaa, 0x01, 0x0000}, + {0xaa, 0x01, 0x0000}, + {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ + {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ + {0xa0, 0x82, 0x0086}, /* 00,86,82,cc, */ + {0xa0, 0x83, 0x0087}, /* 00,87,83,cc, */ + {0xa0, 0x84, 0x0088}, /* 00,88,84,cc, */ + {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ + {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ + {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ + {0xaa, 0x0c, 0x0000}, /* 00,0c,00,aa, */ + {0xaa, 0x0d, 0x00a0}, /* 00,0d,a0,aa, */ + {0xaa, 0x0e, 0x0000}, /* 00,0e,00,aa, */ + {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ + {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ + {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ + {0xa0, 0x00, 0x0039}, + {0xa1, 0x01, 0x0037}, + {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ + {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa (e6 -> e8) */ + {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ + {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ + {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ + {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc, */ + {0xa0, 0x05, 0x0012}, /* 00,12,05,cc, */ + {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc, */ + {0xa0, 0x76, 0x0189}, /* 01,89,76,cc, */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ + {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc, */ + {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc, */ + {0xa0, 0x08, 0x0250}, /* 02,50,08,cc, */ + {0xa0, 0x08, 0x0301}, /* 03,01,08,cc, */ + {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ + {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ + {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ + {0, 0, 0} +}; +/* "50HZ" light frequency banding filter */ +static struct usb_action tas5130c_vf0250_50HZ[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ + {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ + {0xa0, 0x06, 0x0191}, /* 01,91,0d,cc, */ + {0xa0, 0xa8, 0x0192}, /* 01,92,50,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ + {0xa0, 0x8e, 0x0197}, /* 01,97,47,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ + {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0, 0, 0} +}; + +/* "50HZScale" light frequency banding filter */ +static struct usb_action tas5130c_vf0250_50HZScale[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ + {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ + {0xa0, 0x0d, 0x0191}, /* 01,91,0d,cc, */ + {0xa0, 0x50, 0x0192}, /* 01,92,50,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ + {0xa0, 0x8e, 0x0197}, /* 01,97,8e,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ + {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0, 0, 0} +}; + +/* "60HZ" light frequency banding filter */ +static struct usb_action tas5130c_vf0250_60HZ[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ + {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ + {0xa0, 0x05, 0x0191}, /* 01,91,05,cc, */ + {0xa0, 0x88, 0x0192}, /* 01,92,88,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ + {0xa0, 0x3b, 0x0197}, /* 01,97,3b,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ + {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ + {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ + {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0, 0, 0} +}; + +/* "60HZScale" light frequency banding ilter */ +static struct usb_action tas5130c_vf0250_60HZScale[] = { + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ + {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ + {0xa0, 0x0b, 0x0191}, /* 01,1,0b,cc, */ + {0xa0, 0x10, 0x0192}, /* 01,2,10,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,5,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,6,00,cc, */ + {0xa0, 0x76, 0x0197}, /* 01,7,76,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,f,15,cc, */ + {0xa0, 0x10, 0x01a9}, /* 01,9,10,cc, */ + {0xa0, 0x24, 0x01aa}, /* 01,a,24,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,0,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,d,58,cc, */ + {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ + {0xa0, 0x78, 0x018d}, /* 01,d,78,cc */ + {0, 0, 0} +}; + +/* "NoFliker" light frequency banding flter */ +static struct usb_action tas5130c_vf0250_NoFliker[] = { + {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ + {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ + {0xa0, 0x00, 0x0190}, /* 01,0,00,cc, */ + {0xa0, 0x05, 0x0191}, /* 01,91,05,cc, */ + {0xa0, 0x88, 0x0192}, /* 01,92,88,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ + {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ + {0, 0, 0} +}; + +/* "NoFlikerScale" light frequency banding filter */ +static struct usb_action tas5130c_vf0250_NoFlikerScale[] = { + {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ + {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ + {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ + {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ + {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ + {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc, */ + {0xa0, 0x10, 0x0192}, /* 01,92,10,cc, */ + {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ + {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ + {0xa0, 0x10, 0x0197}, /* 01,97,10,cc, */ + {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ + {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ + {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ + {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ + {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ + {0, 0, 0} +}; + +static void reg_r_i(struct usb_device *dev, + __u16 index, __u8 *buffer) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0xa1, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x01, /* value */ + index, buffer, 1, + 500); +} + +static void reg_r(struct usb_device *dev, + __u16 index, __u8 *buffer) +{ + reg_r_i(dev, index, buffer); + PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, *buffer); +} + +static void reg_w_i(struct usb_device *dev, + __u8 value, + __u16 index) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0xa0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, + 500); +} + +static void reg_w(struct usb_device *dev, + __u8 value, + __u16 index) +{ + PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index); + reg_w_i(dev, value, index); +} + +static __u16 i2c_read(struct usb_device *dev, __u8 reg) +{ + __u8 retbyte; + __u8 retval[2]; + + reg_w_i(dev, reg, 0x92); + reg_w_i(dev, 0x02, 0x90); /* <- read command */ + msleep(25); + reg_r_i(dev, 0x0091, &retbyte); /* read status */ + reg_r_i(dev, 0x0095, &retval[0]); /* read Lowbyte */ + reg_r_i(dev, 0x0096, &retval[1]); /* read Hightbyte */ + PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x", + reg, retbyte, retval[1], retval[0]); + return (retval[1] << 8) | retval[0]; +} + +static __u8 i2c_write(struct usb_device *dev, + __u8 reg, + __u8 valL, + __u8 valH) +{ + __u8 retbyte; + + reg_w_i(dev, reg, 0x92); + reg_w_i(dev, valL, 0x93); + reg_w_i(dev, valH, 0x94); + reg_w_i(dev, 0x01, 0x90); /* <- write command */ + msleep(5); + reg_r_i(dev, 0x0091, &retbyte); /* read status */ + PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)", + reg, valH, valL, retbyte); + return retbyte; +} + +static void usb_exchange(struct usb_device *dev, + struct usb_action *action) +{ + __u8 buffread; + + while (action->req) { + switch (action->req) { + case 0xa0: /* write register */ + reg_w(dev, action->val, action->idx); + break; + case 0xa1: /* read status */ + reg_r(dev, action->idx, &buffread); + break; + case 0xaa: + i2c_write(dev, + action->val, /* reg */ + action->idx & 0xff, /* valL */ + action->idx >> 8); /* valH */ + break; + default: +/* case 0xdd: * delay */ + msleep(action->val / 64 + 10); + break; + } + action++; +/* msleep(1); */ + } +} + +static void setmatrix(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + __u8 *matrix; + static __u8 gc0305_matrix[9] = + {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; + static __u8 ov7620_matrix[9] = + {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; + static __u8 po2030_matrix[9] = + {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; + + switch (sd->sensor) { + case SENSOR_GC0305: + matrix = gc0305_matrix; + break; + case SENSOR_MC501CB: + return; /* no matrix? */ + case SENSOR_OV7620: +/* case SENSOR_OV7648: */ + matrix = ov7620_matrix; + break; + case SENSOR_PO2030: + matrix = po2030_matrix; + break; + case SENSOR_TAS5130C_VF0250: /* no matrix? */ + return; + default: /* matrix already loaded */ + return; + } + for (i = 0; i < ARRAY_SIZE(ov7620_matrix); i++) + reg_w(gspca_dev->dev, matrix[i], 0x010a + i); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 brightness; + + switch (sd->sensor) { + case SENSOR_GC0305: + case SENSOR_OV7620: + case SENSOR_PO2030: + return; + } +/*fixme: is it really 011d 018d for all other sensors? */ + brightness = sd->brightness; + reg_w(gspca_dev->dev, brightness, 0x011d); + if (brightness < 0x70) + brightness += 0x10; + else + brightness = 0x80; + reg_w(gspca_dev->dev, brightness, 0x018d); +} + +static void setsharpness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int sharpness; + __u8 retbyte; + static __u8 sharpness_tb[][2] = { + {0x02, 0x03}, + {0x04, 0x07}, + {0x08, 0x0f}, + {0x10, 0x1e} + }; + + switch (sd->sensor) { + case SENSOR_GC0305: + sharpness = 3; + break; + case SENSOR_OV7620: + sharpness = 2; + break; + case SENSOR_PO2030: + sharpness = 0; + break; + default: + return; + } +/*fixme: sharpness set by V4L2_CID_SATURATION?*/ + reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); + reg_r(dev, 0x01c8, &retbyte); + reg_r(dev, 0x01c9, &retbyte); + reg_r(dev, 0x01ca, &retbyte); + reg_w(dev, sharpness_tb[sharpness][1], 0x01cb); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 *Tgamma, *Tgradient; + int g, i, k; + static __u8 kgamma_tb[16] = /* delta for contrast */ + {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; + static __u8 kgrad_tb[16] = + {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04}; + static __u8 Tgamma_1[16] = + {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, + 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; + static __u8 Tgradient_1[16] = + {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a, + 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06}; + static __u8 Tgamma_2[16] = + {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, + 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; + static __u8 Tgradient_2[16] = + {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15, + 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03}; + static __u8 Tgamma_3[16] = + {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, + 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; + static __u8 Tgradient_3[16] = + {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12, + 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03}; + static __u8 Tgamma_4[16] = + {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; + static __u8 Tgradient_4[16] = + {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d, + 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02}; + static __u8 Tgamma_5[16] = + {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, + 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; + static __u8 Tgradient_5[16] = + {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, + 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; + static __u8 Tgamma_6[16] = /* ?? was gama 5 */ + {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, + 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; + static __u8 Tgradient_6[16] = + {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e, + 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01}; + static __u8 *gamma_tb[] = { + 0, Tgamma_1, Tgamma_2, + Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6 + }; + static __u8 *gradient_tb[] = { + 0, Tgradient_1, Tgradient_2, + Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 + }; +#ifdef GSPCA_DEBUG + __u8 v[16]; +#endif + + Tgamma = gamma_tb[sd->gamma]; + Tgradient = gradient_tb[sd->gamma]; + + k = (sd->contrast - 128) /* -128 / 128 */ + * Tgamma[0]; + PDEBUG(D_CONF, "gamma:%d contrast:%d gamma coeff: %d/128", + sd->gamma, sd->contrast, k); + for (i = 0; i < 16; i++) { + g = Tgamma[i] + kgamma_tb[i] * k / 128; + if (g > 0xff) + g = 0xff; + else if (g <= 0) + g = 1; + reg_w(dev, g, 0x0120 + i); /* gamma */ +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) + v[i] = g; +#endif + } + PDEBUG(D_CONF, "tb: %02x %02x %02x %02x %02x %02x %02x %02x", + v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); + PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", + v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]); + for (i = 0; i < 16; i++) { + g = Tgradient[i] - kgrad_tb[i] * k / 128; + if (g > 0xff) + g = 0xff; + else if (g <= 0) { + if (i != 15) + g = 0; + else + g = 1; + } + reg_w(dev, g, 0x0130 + i); /* gradient */ +#ifdef GSPCA_DEBUG + if (gspca_debug & D_CONF) + v[i] = g; +#endif + } + PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", + v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); + PDEBUG(D_CONF, " %02x %02x %02x %02x %02x %02x %02x %02x", + v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15]); +} + +static void setquality(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 quality; + __u8 frxt; + + switch (sd->sensor) { + case SENSOR_GC0305: + case SENSOR_OV7620: + case SENSOR_PO2030: + return; + } +/*fixme: is it really 0008 0007 0018 for all other sensors? */ + quality = sd->qindex & 0x0f; + reg_w(dev, quality, 0x0008); + frxt = 0x30; + reg_w(dev, frxt, 0x0007); + switch (quality) { + case 0: + case 1: + case 2: + frxt = 0xff; + break; + case 3: + frxt = 0xf0; + break; + case 4: + frxt = 0xe0; + break; + case 5: + frxt = 0x20; + break; + } + reg_w(dev, frxt, 0x0018); +} + +/* Matches the sensor's internal frame rate to the lighting frequency. + * Valid frequencies are: + * 50Hz, for European and Asian lighting (default) + * 60Hz, for American lighting + * 0 = No Fliker (for outdoore usage) + * Returns: 0 for success + */ +static int setlightfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, mode; + struct usb_action *zc3_freq; + static struct usb_action *freq_tb[SENSOR_MAX][6] = { +/* SENSOR_CS2102 0 */ + {cs2102_50HZ, cs2102_50HZScale, + cs2102_60HZ, cs2102_60HZScale, + cs2102_NoFliker, cs2102_NoFlikerScale}, +/* SENSOR_CS2102K 1 */ + {cs2102_50HZ, cs2102_50HZScale, + cs2102_60HZ, cs2102_60HZScale, + cs2102_NoFliker, cs2102_NoFlikerScale}, +/* SENSOR_GC0305 2 */ + {gc0305_50HZ, gc0305_50HZ, + gc0305_60HZ, gc0305_60HZ, + gc0305_NoFliker, gc0305_NoFliker}, +/* SENSOR_HDCS2020 3 */ + {0, 0, + 0, 0, + 0, 0}, +/* SENSOR_HDCS2020b 4 */ + {hdcs2020b_50HZ, hdcs2020b_50HZ, + hdcs2020b_60HZ, hdcs2020b_60HZ, + hdcs2020b_NoFliker, hdcs2020b_NoFliker}, +/* SENSOR_HV7131B 5 */ + {0, 0, + 0, 0, + 0, 0}, +/* SENSOR_HV7131C 6 */ + {0, 0, + 0, 0, + 0, 0}, +/* SENSOR_ICM105A 7 */ + {icm105a_50HZ, icm105a_50HZScale, + icm105a_60HZ, icm105a_60HZScale, + icm105a_NoFliker, icm105a_NoFlikerScale}, +/* SENSOR_MC501CB 8 */ + {MC501CB_50HZ, MC501CB_50HZScale, + MC501CB_60HZ, MC501CB_60HZScale, + MC501CB_NoFliker, MC501CB_NoFlikerScale}, +/* SENSOR_OV7620 9 */ + {OV7620_50HZ, OV7620_50HZ, + OV7620_60HZ, OV7620_60HZ, + OV7620_NoFliker, OV7620_NoFliker}, +/* SENSOR_OV7630C 10 */ + {0, 0, + 0, 0, + 0, 0}, +/* SENSOR_free 11 */ + {0, 0, + 0, 0, + 0, 0}, +/* SENSOR_PAS106 12 */ + {pas106b_50HZ, pas106b_50HZ, + pas106b_60HZ, pas106b_60HZ, + pas106b_NoFliker, pas106b_NoFliker}, +/* SENSOR_PB0330 13 */ + {pb0330_50HZ, pb0330_50HZScale, + pb0330_60HZ, pb0330_60HZScale, + pb0330_NoFliker, pb0330_NoFlikerScale}, +/* SENSOR_PO2030 14 */ + {PO2030_50HZ, PO2030_50HZ, + PO2030_60HZ, PO2030_60HZ, + PO2030_NoFliker, PO2030_NoFliker}, +/* SENSOR_TAS5130CK 15 */ + {tas5130cxx_50HZ, tas5130cxx_50HZScale, + tas5130cxx_60HZ, tas5130cxx_60HZScale, + tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, +/* SENSOR_TAS5130CXX 16 */ + {tas5130cxx_50HZ, tas5130cxx_50HZScale, + tas5130cxx_60HZ, tas5130cxx_60HZScale, + tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, +/* SENSOR_TAS5130C_VF0250 17 */ + {tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, + tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale, + tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale}, + }; + + switch (lightfreq) { + case 50: + i = 0; + break; + case 60: + i = 2; + break; + default: + PDEBUG(D_ERR, "Invalid light freq value %d", lightfreq); + lightfreq = 0; /* set to default filter value */ + /* fall thru */ + case 0: + i = 4; + break; + } + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + if (!mode) + i++; /* 640x480 */ + zc3_freq = freq_tb[(int) sd->sensor][i]; + if (zc3_freq != 0) { + usb_exchange(gspca_dev->dev, zc3_freq); + switch (sd->sensor) { + case SENSOR_GC0305: + if (mode /* if 320x240 */ + && lightfreq == 50) + reg_w(gspca_dev->dev, 0x85, 0x018d); + /* win: 0x80, 0x018d */ + break; + case SENSOR_OV7620: + if (!mode) { /* if 640x480 */ + if (lightfreq != 0) /* 50 or 60 Hz */ + reg_w(gspca_dev->dev, 0x40, 0x0002); + else + reg_w(gspca_dev->dev, 0x44, 0x0002); + } + break; + } + } + return 0; +} + +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 autoval; + + if (sd->autogain) + autoval = 0x42; + else + autoval = 0x02; + reg_w(gspca_dev->dev, autoval, 0x0180); +} + +static void send_unknown(struct usb_device *dev, int sensor) +{ + switch (sensor) { + case SENSOR_PAS106: + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x03, 0x003a); + reg_w(dev, 0x0c, 0x003b); + reg_w(dev, 0x08, 0x0038); + break; + case SENSOR_GC0305: + case SENSOR_OV7620: + case SENSOR_PB0330: + case SENSOR_PO2030: + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x0d, 0x003a); + reg_w(dev, 0x02, 0x003b); + reg_w(dev, 0x00, 0x0038); + break; + } +} + +/* start probe 2 wires */ +static void start_2wr_probe(struct usb_device *dev, int sensor) +{ + reg_w(dev, 0x01, 0x0000); + reg_w(dev, sensor, 0x0010); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0x03, 0x0012); + reg_w(dev, 0x01, 0x0012); +/* msleep(2); */ +} + +static int sif_probe(struct usb_device *dev) +{ + __u16 checkword; + + start_2wr_probe(dev, 0x0f); /* PAS106 */ + reg_w(dev, 0x08, 0x008d); + msleep(150); + checkword = ((i2c_read(dev, 0x00) & 0x0f) << 4) + | ((i2c_read(dev, 0x01) & 0xf0) >> 4); + PDEBUG(D_PROBE, "probe sif 0x%04x", checkword); + if (checkword == 0x0007) { + send_unknown(dev, SENSOR_PAS106); + return 0x0f; /* PAS106 */ + } + return -1; +} + +static int vga_2wr_probe(struct usb_device *dev) +{ + __u8 retbyte; + __u16 checkword; + + start_2wr_probe(dev, 0x00); /* HV7131B */ + i2c_write(dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(dev, 0x01); + if (retbyte != 0) + return 0x00; /* HV7131B */ + + start_2wr_probe(dev, 0x04); /* CS2102 */ + i2c_write(dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(dev, 0x01); + if (retbyte != 0) + return 0x04; /* CS2102 */ + + start_2wr_probe(dev, 0x06); /* OmniVision */ + reg_w(dev, 0x08, 0x8d); + i2c_write(dev, 0x11, 0xaa, 0x00); + retbyte = i2c_read(dev, 0x11); + if (retbyte != 0) { + /* (should have returned 0xaa) --> Omnivision? */ + /* reg_r 0x10 -> 0x06 --> */ + goto ov_check; + } + + start_2wr_probe(dev, 0x08); /* HDCS2020 */ + i2c_write(dev, 0x15, 0xaa, 0x00); + retbyte = i2c_read(dev, 0x15); + if (retbyte != 0) + return 0x08; /* HDCS2020 */ + + start_2wr_probe(dev, 0x0a); /* PB0330 */ + i2c_write(dev, 0x07, 0xaa, 0xaa); + retbyte = i2c_read(dev, 0x07); + if (retbyte != 0) + return 0x0a; /* PB0330 */ + retbyte = i2c_read(dev, 0x03); + if (retbyte != 0) + return 0x0a; /* PB0330 ?? */ + retbyte = i2c_read(dev, 0x04); + if (retbyte != 0) + return 0x0a; /* PB0330 ?? */ + + start_2wr_probe(dev, 0x0c); /* ICM105A */ + i2c_write(dev, 0x01, 0x11, 0x00); + retbyte = i2c_read(dev, 0x01); + if (retbyte != 0) + return 0x0c; /* ICM105A */ + + start_2wr_probe(dev, 0x0e); /* PAS202BCB */ + reg_w(dev, 0x08, 0x8d); + i2c_write(dev, 0x03, 0xaa, 0x00); + msleep(500); + retbyte = i2c_read(dev, 0x03); + if (retbyte != 0) + return 0x0e; /* PAS202BCB */ + + start_2wr_probe(dev, 0x02); /* ?? */ + i2c_write(dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(dev, 0x01); + if (retbyte != 0) + return 0x02; /* ?? */ +ov_check: + reg_r(dev, 0x0010, &retbyte); /* ?? */ + reg_r(dev, 0x0010, &retbyte); + + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0x06, 0x0010); /* OmniVision */ + reg_w(dev, 0xa1, 0x008b); + reg_w(dev, 0x08, 0x008d); + msleep(500); + reg_w(dev, 0x01, 0x0012); + i2c_write(dev, 0x12, 0x80, 0x00); /* sensor reset */ + retbyte = i2c_read(dev, 0x0a); + checkword = retbyte << 8; + retbyte = i2c_read(dev, 0x0b); + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); + switch (checkword) { + case 0x7631: /* OV7630C */ + reg_w(dev, 0x06, 0x0010); + break; + case 0x7620: /* OV7620 */ + case 0x7648: /* OV7648 */ + break; + default: + return -1; /* not OmniVision */ + } + return checkword; +} + +struct sensor_by_chipset_revision { + __u16 revision; + __u8 internal_sensor_id; +}; +static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { + {0xc001, 0x13}, /* MI0360 */ + {0xe001, 0x13}, + {0x8001, 0x13}, + {0x8000, 0x14}, /* CS2102K */ + {0x8400, 0x15}, /* TAS5130K */ + {0, 0} +}; + +static int vga_3wr_probe(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int i; + __u8 retbyte; + __u16 checkword; + +/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ + reg_w(dev, 0x02, 0x0010); + reg_r(dev, 0x0010, &retbyte); + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x00, 0x0010); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0x91, 0x008b); + reg_w(dev, 0x03, 0x0012); + reg_w(dev, 0x01, 0x0012); + reg_w(dev, 0x05, 0x0012); + retbyte = i2c_read(dev, 0x14); + if (retbyte != 0) + return 0x11; /* HV7131R */ + retbyte = i2c_read(dev, 0x15); + if (retbyte != 0) + return 0x11; /* HV7131R */ + retbyte = i2c_read(dev, 0x16); + if (retbyte != 0) + return 0x11; /* HV7131R */ + + reg_w(dev, 0x02, 0x0010); + reg_r(dev, 0x000b, &retbyte); + checkword = retbyte << 8; + reg_r(dev, 0x000a, &retbyte); + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); + reg_r(dev, 0x0010, &retbyte); + /* this is tested only once anyway */ + i = 0; + while (chipset_revision_sensor[i].revision) { + if (chipset_revision_sensor[i].revision == checkword) { + sd->chip_revision = checkword; + send_unknown(dev, SENSOR_PB0330); + return chipset_revision_sensor[i].internal_sensor_id; + } + i++; + } + + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0xdd, 0x008b); + reg_w(dev, 0x0a, 0x0010); + reg_w(dev, 0x03, 0x0012); + reg_w(dev, 0x01, 0x0012); + retbyte = i2c_read(dev, 0x00); + if (retbyte != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); + return 0x0a; /* ?? */ + } + + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0x98, 0x008b); + reg_w(dev, 0x01, 0x0010); + reg_w(dev, 0x03, 0x0012); + msleep(2); + reg_w(dev, 0x01, 0x0012); + retbyte = i2c_read(dev, 0x00); + if (retbyte != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); + send_unknown(dev, SENSOR_GC0305); + return retbyte; /* 0x29 = gc0305 - should continue? */ + } + + reg_w(dev, 0x01, 0x0000); /* check OmniVision */ + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0xa1, 0x008b); + reg_w(dev, 0x08, 0x008d); + reg_w(dev, 0x06, 0x0010); + reg_w(dev, 0x01, 0x0012); + reg_w(dev, 0x05, 0x0012); + if (i2c_read(dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ + && i2c_read(dev, 0x1d) == 0xa2) { + send_unknown(dev, SENSOR_OV7620); + return 0x06; /* OmniVision confirm ? */ + } + + reg_w(dev, 0x01, 0x00); + reg_w(dev, 0x00, 0x02); + reg_w(dev, 0x01, 0x10); + reg_w(dev, 0x01, 0x01); + reg_w(dev, 0xee, 0x8b); + reg_w(dev, 0x03, 0x12); +/* msleep(150); */ + reg_w(dev, 0x01, 0x12); + reg_w(dev, 0x05, 0x12); + retbyte = i2c_read(dev, 0x00); /* ID 0 */ + checkword = retbyte << 8; + retbyte = i2c_read(dev, 0x01); /* ID 1 */ + checkword |= retbyte; + PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); + if (checkword == 0x2030) { + retbyte = i2c_read(dev, 0x02); /* revision number */ + PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); + send_unknown(dev, SENSOR_PO2030); + return checkword; + } + + reg_w(dev, 0x01, 0x00); + reg_w(dev, 0x0a, 0x10); + reg_w(dev, 0xd3, 0x8b); + reg_w(dev, 0x01, 0x01); + reg_w(dev, 0x03, 0x12); + reg_w(dev, 0x01, 0x12); + reg_w(dev, 0x05, 0x01); + reg_w(dev, 0xd3, 0x8b); + retbyte = i2c_read(dev, 0x01); + if (retbyte != 0) { + PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); + return 0x0a; /* ?? */ + } + return -1; +} + +static int zcxx_probeSensor(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int sensor, sensor2; + + switch (sd->sensor) { + case SENSOR_MC501CB: + case SENSOR_TAS5130C_VF0250: + return -1; /* don't probe */ + } + sensor = vga_2wr_probe(dev); + if (sensor >= 0) { + if (sensor < 0x7600) + return sensor; + /* next probe is needed for OmniVision ? */ + } + sensor2 = vga_3wr_probe(gspca_dev); + if (sensor2 >= 0) { + if (sensor >= 0) + return sensor; + return sensor2; + } + return sif_probe(dev); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + int sensor; + __u8 bsensor; + int vga = 1; /* 1: vga, 0: sif */ + static unsigned char gamma[SENSOR_MAX] = { + 5, /* SENSOR_CS2102 0 */ + 5, /* SENSOR_CS2102K 1 */ + 4, /* SENSOR_GC0305 2 */ + 4, /* SENSOR_HDCS2020 3 */ + 4, /* SENSOR_HDCS2020b 4 */ + 4, /* SENSOR_HV7131B 5 */ + 4, /* SENSOR_HV7131C 6 */ + 4, /* SENSOR_ICM105A 7 */ + 4, /* SENSOR_MC501CB 8 */ + 3, /* SENSOR_OV7620 9 */ + 4, /* SENSOR_OV7630C 10 */ + 4, /* SENSOR_free 11 */ + 4, /* SENSOR_PAS106 12 */ + 4, /* SENSOR_PB0330 13 */ + 4, /* SENSOR_PO2030 14 */ + 4, /* SENSOR_TAS5130CK 15 */ + 4, /* SENSOR_TAS5130CXX 16 */ + 3, /* SENSOR_TAS5130C_VF0250 17 */ + }; + + /* define some sensors from the vendor/product */ + switch (id->idVendor) { + case 0x041e: /* Creative */ + switch (id->idProduct) { + case 0x4051: /* zc301 chips */ + case 0x4053: + sd->sensor = SENSOR_TAS5130C_VF0250; + break; + } + break; + case 0x046d: /* Logitech Labtec */ + switch (id->idProduct) { + case 0x08dd: + sd->sensor = SENSOR_MC501CB; + break; + } + break; + case 0x0ac8: /* Vimicro z-star */ + switch (id->idProduct) { + case 0x305b: + sd->sensor = SENSOR_TAS5130C_VF0250; + break; + } + break; + } + sensor = zcxx_probeSensor(gspca_dev); + if (sensor >= 0) + PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); + if ((unsigned) force_sensor < SENSOR_MAX) { + sd->sensor = force_sensor; + PDEBUG(D_PROBE, "sensor forced to %d", force_sensor); + } else { + switch (sensor) { + case -1: + switch (sd->sensor) { + case SENSOR_MC501CB: + PDEBUG(D_PROBE, "Sensor MC501CB"); + break; + case SENSOR_TAS5130C_VF0250: + PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); + break; + default: + PDEBUG(D_PROBE, + "Sensor UNKNOW_0 force Tas5130"); + sd->sensor = SENSOR_TAS5130CXX; + } + break; + case 0: + PDEBUG(D_PROBE, "Find Sensor HV7131B"); + sd->sensor = SENSOR_HV7131B; + break; + case 0x04: + PDEBUG(D_PROBE, "Find Sensor CS2102"); + sd->sensor = SENSOR_CS2102; + break; + case 0x08: + PDEBUG(D_PROBE, "Find Sensor HDCS2020(b)"); + sd->sensor = SENSOR_HDCS2020b; + break; + case 0x0a: + PDEBUG(D_PROBE, + "Find Sensor PB0330. Chip revision %x", + sd->chip_revision); + sd->sensor = SENSOR_PB0330; + break; + case 0x0c: + PDEBUG(D_PROBE, "Find Sensor ICM105A"); + sd->sensor = SENSOR_ICM105A; + break; + case 0x0e: + PDEBUG(D_PROBE, "Find Sensor PAS202BCB"); + sd->sensor = SENSOR_HDCS2020; + break; + case 0x0f: + PDEBUG(D_PROBE, "Find Sensor PAS106"); + sd->sensor = SENSOR_PAS106; + vga = 0; /* SIF */ + break; + case 0x10: + case 0x12: + PDEBUG(D_PROBE, "Find Sensor TAS5130"); + sd->sensor = SENSOR_TAS5130CXX; + break; + case 0x11: + PDEBUG(D_PROBE, "Find Sensor HV7131R(c)"); + sd->sensor = SENSOR_HV7131C; + break; + case 0x13: + PDEBUG(D_PROBE, + "Find Sensor MI0360. Chip revision %x", + sd->chip_revision); + sd->sensor = SENSOR_PB0330; + break; + case 0x14: + PDEBUG(D_PROBE, + "Find Sensor CS2102K?. Chip revision %x", + sd->chip_revision); + sd->sensor = SENSOR_CS2102K; + break; + case 0x15: + PDEBUG(D_PROBE, + "Find Sensor TAS5130CK?. Chip revision %x", + sd->chip_revision); + sd->sensor = SENSOR_TAS5130CK; + break; + case 0x29: + PDEBUG(D_PROBE, "Find Sensor GC0305"); + sd->sensor = SENSOR_GC0305; + break; + case 0x2030: + PDEBUG(D_PROBE, "Find Sensor PO2030"); + sd->sensor = SENSOR_PO2030; + break; + case 0x7620: + PDEBUG(D_PROBE, "Find Sensor OV7620"); + sd->sensor = SENSOR_OV7620; + break; + case 0x7648: + PDEBUG(D_PROBE, "Find Sensor OV7648"); + sd->sensor = SENSOR_OV7620; /* same sensor (?) */ + break; + default: + PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor); + return -EINVAL; + } + } + if (sensor < 0x20) { + if (sensor == -1 || sensor == 0x10 || sensor == 0x12) + reg_w(gspca_dev->dev, 0x02, 0x0010); + else + reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010); + reg_r(gspca_dev->dev, 0x0010, &bsensor); + } + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; +/*fixme:test*/ + gspca_dev->nbalt--; + if (vga) { + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + } else { + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + } + sd->qindex = 1; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->gamma = gamma[(int) sd->sensor]; + + /* switch the led off */ +/*fixme: other sensors? */ + if (sensor == 0x06 || sensor == 0x11) + reg_w(gspca_dev->dev, 0x01, 0x0000); + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + reg_w(gspca_dev->dev, 0x01, 0x0000); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct usb_action *zc3_init; + int mode; + __u8 retbyte; + static struct usb_action *init_tb[SENSOR_MAX][2] = { + {cs2102_InitialScale, cs2102_Initial}, /* 0 */ + {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ + {gc0305_Initial, gc0305_InitialScale}, /* 2 */ + {hdcs2020xx_InitialScale, hdcs2020xx_Initial}, /* 3 */ + {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */ + {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */ + {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */ + {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */ + {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ + {OV7620_mode0, OV7620_mode1}, /* 9 */ + {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ + {0, 0}, /* 11 */ + {pas106b_InitialScale, pas106b_Initial}, /* 12 */ + {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ +/* or {pb03303x_InitialScale, pb03303x_Initial}, */ + {PO2030_mode0, PO2030_mode1}, /* 14 */ + {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ + {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ + {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, + /* 17 */ + }; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + zc3_init = init_tb[(int) sd->sensor][mode]; + switch (sd->sensor) { + case SENSOR_HV7131B: + case SENSOR_HV7131C: + zcxx_probeSensor(gspca_dev); + break; + case SENSOR_PAS106: + usb_exchange(dev, pas106b_Initial_com); + break; + case SENSOR_PB0330: + if (mode) { + if (sd->chip_revision == 0xc001 + || sd->chip_revision == 0xe001 + || sd->chip_revision == 0x8001) + zc3_init = pb03303x_Initial; + } else { + if (sd->chip_revision == 0xc001 + || sd->chip_revision == 0xe001 + || sd->chip_revision == 0x8001) + zc3_init = pb03303x_InitialScale; + } + break; + } + usb_exchange(dev, zc3_init); + + switch (sd->sensor) { + case SENSOR_GC0305: + case SENSOR_OV7620: + case SENSOR_PO2030: + msleep(100); /* ?? */ + reg_r(dev, 0x0002, &retbyte); /* --> 0x40 */ + reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ + reg_w(dev, 0x15, 0x01ae); + reg_w(dev, 0x0d, 0x003a); + reg_w(dev, 0x02, 0x003b); + reg_w(dev, 0x00, 0x0038); + break; + } + + setmatrix(gspca_dev); + setbrightness(gspca_dev); + switch (sd->sensor) { + case SENSOR_OV7620: + reg_r(dev, 0x0008, &retbyte); + reg_w(dev, 0x00, 0x0008); + break; + case SENSOR_GC0305: + reg_r(dev, 0x0008, &retbyte); + /* fall thru */ + case SENSOR_PO2030: + reg_w(dev, 0x03, 0x0008); + break; + } + setsharpness(gspca_dev); + + /* set the gamma tables when not set */ + switch (sd->sensor) { + case SENSOR_CS2102: /* gamma set in xxx_Initial */ + case SENSOR_CS2102K: + case SENSOR_HDCS2020: + case SENSOR_HDCS2020b: + case SENSOR_PB0330: /* pb with chip_revision - see above */ + case SENSOR_OV7630C: + case SENSOR_TAS5130CK: + break; + default: + setcontrast(gspca_dev); + break; + } + setmatrix(gspca_dev); /* one more time? */ + switch (sd->sensor) { + case SENSOR_OV7620: + reg_r(dev, 0x0180, &retbyte); /* from win */ + reg_w(dev, 0x00, 0x0180); + break; + default: + setquality(gspca_dev); + break; + } + setlightfreq(gspca_dev); + + switch (sd->sensor) { + case SENSOR_GC0305: + case SENSOR_OV7620: + reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ + reg_w(dev, 0x15, 0x01ae); + sd->autogain = 0; + break; + case SENSOR_PO2030: + reg_w(dev, 0x40, 0x0117); /* (from win traces) */ + reg_r(dev, 0x0180, &retbyte); + break; + } + + setautogain(gspca_dev); + switch (sd->sensor) { + case SENSOR_GC0305: +/* setlightfreq(gspca_dev); ?? (end: 80 -> [18d]) */ + reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ + reg_w(dev, 0x15, 0x01ae); + reg_w(dev, 0x40, 0x0180); + reg_w(dev, 0x40, 0x0117); + reg_r(dev, 0x0180, &retbyte); + sd->autogain = 1; + setautogain(gspca_dev); + break; + case SENSOR_OV7620: + i2c_read(dev, 0x13); /*fixme: returns 0xa3 */ + i2c_write(dev, 0x13, 0xa3, 0x00); /*fixme: same to send? */ + reg_w(dev, 0x40, 0x0117); /* (from win traces) */ + reg_r(dev, 0x0180, &retbyte); + setautogain(gspca_dev); + msleep(500); + break; + case SENSOR_PO2030: + msleep(500); + reg_r(dev, 0x0008, &retbyte); + reg_r(dev, 0x0007, &retbyte); + reg_w(dev, 0x00, 0x0007); /* (from win traces) */ + reg_w(dev, 0x02, 0x0008); + break; + } +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + send_unknown(gspca_dev->dev, sd->sensor); +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, + unsigned char *data, + int len) +{ + + if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + /* put the JPEG header in the new frame */ + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x21); + /* remove the webcam's header: + * ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp + * - 'ss ss' is the frame sequence number (BE) + * - 'ww ww' and 'hh hh' are the window dimensions (BE) + * - 'pp pp' is the packet sequence number (BE) + */ + data += 18; + len -= 18; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (gspca_dev->streaming) + setautogain(gspca_dev); + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->gamma; + return 0; +} + +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, + {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, + {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, + {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")}, + {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")}, +/*0x041e, 0x4022*/ + {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")}, + {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")}, + {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")}, + {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")}, + {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")}, + {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")}, + {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")}, + {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")}, + {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")}, + {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")}, + {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")}, + {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")}, + {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")}, + {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")}, + {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")}, + {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")}, + {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")}, + {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")}, + {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, + {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")}, + {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")}, + {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")}, + {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")}, + {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")}, + {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")}, + {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")}, + {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")}, + {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")}, + {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")}, + {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")}, + {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")}, + {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")}, + {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")}, + {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")}, + {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")}, + {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")}, + {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")}, +/*0x0ac8, 0x0301*/ + {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")}, + {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")}, + {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")}, + {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")}, + {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")}, + {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")}, +/*0x10fd, 0x804e*/ + {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")}, + {} /* end of entry */ +}; +#undef DVNAME +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +/* USB driver */ +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} + +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); + +module_param(lightfreq, int, 0644); +MODULE_PARM_DESC(lightfreq, + "Light frequency banding filter: 50, 60 Hz or" + " 0 to NoFliker (default=50)"); +module_param(force_sensor, int, 0644); +MODULE_PARM_DESC(force_sensor, + "Force sensor. Only for experts!!!"); -- cgit v1.2.3 From 6a7eba24e4f0ff725d33159f6265e3a79d53a833 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 30 Jun 2008 15:50:11 -0300 Subject: V4L/DVB (8157): gspca: all subdrivers - remaning subdrivers added - remove the decoding helper and some specific frame decodings Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 306 ++--- drivers/media/video/Makefile | 1 + drivers/media/video/gspca/Kconfig | 2 +- drivers/media/video/gspca/Makefile | 26 +- drivers/media/video/gspca/conex.c | 1059 +++++++++++++++++ drivers/media/video/gspca/etoms.c | 1062 +++++++++++++++++ drivers/media/video/gspca/gspca.c | 579 ++------- drivers/media/video/gspca/gspca.h | 39 +- drivers/media/video/gspca/mars.c | 455 +++++++ drivers/media/video/gspca/ov519.c | 2174 ++++++++++++++++++++++++++++++++++ drivers/media/video/gspca/pac207.c | 10 +- drivers/media/video/gspca/pac7311.c | 754 ++++++++++++ drivers/media/video/gspca/sonixb.c | 879 ++++++++++++++ drivers/media/video/gspca/sonixj.c | 1629 +++++++++++++++++++++++++ drivers/media/video/gspca/spca500.c | 1195 +++++++++++++++++++ drivers/media/video/gspca/spca501.c | 2219 +++++++++++++++++++++++++++++++++++ drivers/media/video/gspca/spca505.c | 933 +++++++++++++++ drivers/media/video/gspca/spca506.c | 830 +++++++++++++ drivers/media/video/gspca/spca508.c | 1774 ++++++++++++++++++++++++++++ drivers/media/video/gspca/spca561.c | 1025 ++++++++++++++++ drivers/media/video/gspca/stk014.c | 170 ++- drivers/media/video/gspca/sunplus.c | 1638 ++++++++++++++++++++++++++ drivers/media/video/gspca/t613.c | 1013 ++++++++++++++++ drivers/media/video/gspca/tv8532.c | 709 +++++++++++ drivers/media/video/gspca/vc032x.c | 1816 ++++++++++++++++++++++++++++ drivers/media/video/gspca/zc3xx.c | 649 +++++----- include/linux/videodev2.h | 2 + 27 files changed, 21964 insertions(+), 984 deletions(-) create mode 100644 drivers/media/video/gspca/conex.c create mode 100644 drivers/media/video/gspca/etoms.c create mode 100644 drivers/media/video/gspca/mars.c create mode 100644 drivers/media/video/gspca/ov519.c create mode 100644 drivers/media/video/gspca/pac7311.c create mode 100644 drivers/media/video/gspca/sonixb.c create mode 100644 drivers/media/video/gspca/sonixj.c create mode 100644 drivers/media/video/gspca/spca500.c create mode 100644 drivers/media/video/gspca/spca501.c create mode 100644 drivers/media/video/gspca/spca505.c create mode 100644 drivers/media/video/gspca/spca506.c create mode 100644 drivers/media/video/gspca/spca508.c create mode 100644 drivers/media/video/gspca/spca561.c create mode 100644 drivers/media/video/gspca/sunplus.c create mode 100644 drivers/media/video/gspca/t613.c create mode 100644 drivers/media/video/gspca/tv8532.c create mode 100644 drivers/media/video/gspca/vc032x.c (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 9c404b56dbb3..37996e59d516 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -1,4 +1,4 @@ -Here the list of the known working cameras with gspca. +List of the webcams know by gspca. The modules are: gspca_main main driver @@ -6,106 +6,73 @@ The modules are: xxxx vend:prod ---- -conex 0572:0041 Creative Notebook cx11646 -etoms 102c:6151 Qcam Sangha CIF -etoms 102c:6251 Qcam xxxxxx VGA -mars 093a:050f Mars-Semi Pc-Camera +spca501 0000:0000 MystFromOri Unknow Camera +spca501 040a:0002 Kodak DVC-325 +spca500 040a:0300 Kodak EZ200 +zc3xx 041e:041e Creative WebCam Live! +spca500 041e:400a Creative PC-CAM 300 +sunplus 041e:400b Creative PC-CAM 600 +sunplus 041e:4012 PC-Cam350 +sunplus 041e:4013 Creative Pccam750 +zc3xx 041e:4017 Creative Webcam Mobile PD1090 +spca508 041e:4018 Creative Webcam Vista (PD1100) +spca561 041e:401a Creative Webcam Vista (PD1100) +zc3xx 041e:401c Creative NX +spca505 041e:401d Creative Webcam NX ULTRA +zc3xx 041e:401e Creative Nx Pro +zc3xx 041e:401f Creative Webcam Notebook PD1171 +pac207 041e:4028 Creative Webcam Vista Plus +zc3xx 041e:4029 Creative WebCam Vista Pro +zc3xx 041e:4034 Creative Instant P0620 +zc3xx 041e:4035 Creative Instant P0620D +zc3xx 041e:4036 Creative Live ! +zc3xx 041e:403a Creative Nx Pro 2 +spca561 041e:403b Creative Webcam Vista (VF0010) +zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) ov519 041e:4052 Creative Live! VISTA IM +zc3xx 041e:4053 Creative Live!Cam Video IM ov519 041e:405f Creative Live! VISTA VF0330 ov519 041e:4060 Creative Live! VISTA VF0350 ov519 041e:4061 Creative Live! VISTA VF0400 ov519 041e:4064 Creative Live! VISTA VF0420 ov519 041e:4068 Creative Live! VISTA VF0470 -ov519 045e:028c Micro$oft xbox cam -ov519 054c:0154 Sonny toy4 -ov519 054c:0155 Sonny toy5 -ov519 05a9:0519 OmniVision -ov519 05a9:4519 OmniVision -ov519 05a9:8519 OmniVision -ov519 05a9:0530 OmniVision -pac207 041e:4028 Creative Webcam Vista Plus -pac207 093a:2460 PAC207 Qtec Webcam 100 -pac207 093a:2463 Philips spc200nc pac207 -pac207 093a:2464 Labtec Webcam 1200 -pac207 093a:2468 PAC207 -pac207 093a:2470 Genius GF112 -pac207 093a:2471 PAC207 Genius VideoCam ge111 -pac207 093a:2472 PAC207 Genius VideoCam ge110 -pac7311 093a:2600 PAC7311 Typhoon -pac7311 093a:2601 PAC7311 Phillips SPC610NC -pac7311 093a:2603 PAC7312 -pac7311 093a:2608 PAC7311 Trust WB-3300p -pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 -pac7311 093a:260f PAC7311 SnakeCam -sonixb 0c45:6001 Genius VideoCAM NB -sonixb 0c45:6005 Sweex Tas5110 -sonixb 0c45:6007 Sonix sn9c101 + Tas5110D -sonixb 0c45:6009 spcaCam@120 -sonixb 0c45:600d spcaCam@120 -sonixb 0c45:6011 MAX Webcam (Microdia - OV6650 - SN9C101G) -sonixb 0c45:6019 Generic Sonix OV7630 -sonixb 0c45:6024 Generic Sonix Tas5130c -sonixb 0c45:6025 Xcam Shanga -sonixb 0c45:6028 Sonix Btc Pc380 -sonixb 0c45:6029 spcaCam@150 -sonixb 0c45:602c Generic Sonix OV7630 -sonixb 0c45:602d LIC-200 LG -sonixb 0c45:602e Genius VideoCam Messenger +spca561 0458:7004 Genius VideoCAM Express V2 +sunplus 0458:7006 Genius Dsc 1.3 Smart +zc3xx 0458:7007 Genius VideoCam V2 +zc3xx 0458:700c Genius VideoCam V3 +zc3xx 0458:700f Genius VideoCam Web V2 sonixj 0458:7025 Genius Eye 311Q sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 -sonixj 0471:0327 Philips SPC 600 NC -sonixj 0471:0328 Philips SPC 700 NC -sonixj 0471:0330 Philips SPC 710NC -sonixj 0c45:6040 Speed NVC 350K -sonixj 0c45:607c Sonix sn9c102p Hv7131R -sonixj 0c45:60c0 Sangha Sn535 -sonixj 0c45:60ec SN9C105+MO4000 -sonixj 0c45:60fb Surfer NoName -sonixj 0c45:60fc LG-LIC300 -sonixj 0c45:612a Avant Camera -sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix -sonixj 0c45:6130 Sonix Pccam -sonixj 0c45:6138 Sn9c120 Mo4000 -sonixj 0c45:613b Surfer SN-206 -sonixj 0c45:613c Sonix Pccam168 -spca500 040a:0300 Kodak EZ200 -spca500 041e:400a Creative PC-CAM 300 +ov519 045e:028c Micro$oft xbox cam +spca508 0461:0815 Micro Innovation IC200 +zc3xx 0461:0a00 MicroInnovation WebCam320 spca500 046d:0890 Logitech QuickCam traveler +vc032x 046d:0892 Logitech Orbicam +vc032x 046d:0896 Logitech Orbicam +zc3xx 046d:08a0 Logitech QC IM +zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound +zc3xx 046d:08a2 Labtec Webcam Pro +zc3xx 046d:08a3 Logitech QC Chat +zc3xx 046d:08a6 Logitech QCim +zc3xx 046d:08a7 Logitech QuickCam Image +zc3xx 046d:08a9 Logitech Notebook Deluxe +zc3xx 046d:08aa Labtec Webcam Notebook +zc3xx 046d:08ac Logitech QuickCam Cool +zc3xx 046d:08ad Logitech QCCommunicate STX +zc3xx 046d:08ae Logitech QuickCam for Notebooks +zc3xx 046d:08af Logitech QuickCam Cool +zc3xx 046d:08b9 Logitech QC IM ??? +zc3xx 046d:08d7 Logitech QCam STX +zc3xx 046d:08d9 Logitech QuickCam IM/Connect +zc3xx 046d:08d8 Logitech Notebook Deluxe +zc3xx 046d:08da Logitech QuickCam Messenger +zc3xx 046d:08dd Logitech QuickCam for Notebooks spca500 046d:0900 Logitech Inc. ClickSmart 310 spca500 046d:0901 Logitech Inc. ClickSmart 510 -spca500 04a5:300c Benq DC1016 -spca500 04fc:7333 PalmPixDC85 -spca500 055f:c200 Mustek Gsmart 300 -spca500 055f:c220 Gsmart Mini -spca500 06bd:0404 Agfa CL20 -spca500 06be:0800 Optimedia -spca500 084d:0003 D-Link DSC-350 -spca500 08ca:0103 Aiptek PocketDV -spca500 2899:012c Toptro Industrial -spca500 8086:0630 Intel Pocket PC Camera -spca501 040a:0002 Kodak DVC-325 -spca501 0497:c001 Smile International -spca501 0506:00df 3Com HomeConnect Lite -spca501 0733:0401 Intel Create and Share -spca501 0733:0402 ViewQuest M318B -spca501 1776:501c Arowana 300K CMOS Camera -spca501 0000:0000 MystFromOri Unknow Camera -spca505 041e:401d Creative Webcam NX ULTRA -spca505 0733:0430 Intel PC Camera Pro -spca506 06e1:a190 ADS Instant VCD -spca506 0734:043b 3DeMon USB Capture aka -spca506 99fa:8988 Grandtec V.cap -spca506 99fa:8988 Grandtec V.cap -spca508 041e:4018 Creative Webcam Vista (PD1100) -spca508 0461:0815 Micro Innovation IC200 -spca508 0733:0110 ViewQuest VQ110 -spca508 0af9:0010 Hama USB Sightcam 100 -spca508 0af9:0011 Hama USB Sightcam 100 -spca508 8086:0110 Intel Easy PC Camera -spca561 041e:401a Creative Webcam Vista (PD1100) -spca561 041e:403b Creative Webcam Vista (VF0010) -spca561 0458:7004 Genius VideoCAM Express V2 +sunplus 046d:0905 Logitech ClickSmart 820 +tv8532 046d:0920 QC Express +tv8532 046d:0921 Labtec Webcam spca561 046d:0928 Logitech QC Express Etch2 spca561 046d:0929 Labtec Webcam Elch2 spca561 046d:092a Logitech QC for Notebook @@ -114,33 +81,42 @@ spca561 046d:092c Logitech QC chat Elch2 spca561 046d:092d Logitech QC Elch2 spca561 046d:092e Logitech QC Elch2 spca561 046d:092f Logitech QC Elch2 -spca561 04fc:0561 Flexcam 100 -spca561 060b:a001 Maxell Compact Pc PM3 -spca561 10fd:7e50 FlyCam Usb 100 -spca561 abcd:cdee Petcam -stk014 05e1:0893 Syntek DV4000 -sunplus 041e:400b Creative PC-CAM 600 -sunplus 041e:4012 PC-Cam350 -sunplus 041e:4013 Creative Pccam750 -sunplus 0458:7006 Genius Dsc 1.3 Smart -sunplus 046d:0905 Logitech ClickSmart 820 sunplus 046d:0960 Logitech ClickSmart 420 sunplus 0471:0322 Philips DMVC1300K +zc3xx 0471:0325 Philips SPC 200 NC +zc3xx 0471:0326 Philips SPC 300 NC +sonixj 0471:0327 Philips SPC 600 NC +sonixj 0471:0328 Philips SPC 700 NC +zc3xx 0471:032d Philips spc210nc +zc3xx 0471:032e Philips spc315nc +sonixj 0471:0330 Philips SPC 710NC +spca501 0497:c001 Smile International sunplus 04a5:3003 Benq DC 1300 sunplus 04a5:3008 Benq DC 1500 sunplus 04a5:300a Benq DC3410 +spca500 04a5:300c Benq DC1016 sunplus 04f1:1001 JVC GC A50 +spca561 04fc:0561 Flexcam 100 sunplus 04fc:500c Sunplus CA500C sunplus 04fc:504a Aiptek Mini PenCam 1.3 sunplus 04fc:504b Maxell MaxPocket LE 1.3 sunplus 04fc:5330 Digitrex 2110 sunplus 04fc:5360 Sunplus Generic +spca500 04fc:7333 PalmPixDC85 sunplus 04fc:ffff Pure DigitalDakota +spca501 0506:00df 3Com HomeConnect Lite sunplus 052b:1513 Megapix V4 +tv8532 0545:808b Veo Stingray +tv8532 0545:8333 Veo Stingray sunplus 0546:3155 Polaroid PDC3070 sunplus 0546:3191 Polaroid Ion 80 sunplus 0546:3273 Polaroid PDC2030 +ov519 054c:0154 Sonny toy4 +ov519 054c:0155 Sonny toy5 +zc3xx 055f:c005 Mustek Wcam300A +spca500 055f:c200 Mustek Gsmart 300 sunplus 055f:c211 Kowa Bs888e Microcamera +spca500 055f:c220 Gsmart Mini sunplus 055f:c230 Mustek Digicam 330K sunplus 055f:c232 Mustek MDC3500 sunplus 055f:c360 Mustek DV4000 Mpeg4 @@ -152,14 +128,34 @@ sunplus 055f:c530 Mustek Gsmart LCD 3 sunplus 055f:c540 Gsmart D30 sunplus 055f:c630 Mustek MDC4000 sunplus 055f:c650 Mustek MDC5500Z +zc3xx 055f:d003 Mustek WCam300A +zc3xx 055f:d004 Mustek WCam300 AN +conex 0572:0041 Creative Notebook cx11646 +ov519 05a9:0519 OmniVision +ov519 05a9:0530 OmniVision +ov519 05a9:4519 OmniVision +ov519 05a9:8519 OmniVision sunplus 05da:1018 Digital Dream Enigma 1.3 +stk014 05e1:0893 Syntek DV4000 +spca561 060b:a001 Maxell Compact Pc PM3 +zc3xx 0698:2003 CTX M730V built in +spca500 06bd:0404 Agfa CL20 +spca500 06be:0800 Optimedia sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom +spca506 06e1:a190 ADS Instant VCD +spca508 0733:0110 ViewQuest VQ110 +spca501 0733:0401 Intel Create and Share +spca501 0733:0402 ViewQuest M318B +spca505 0733:0430 Intel PC Camera Pro sunplus 0733:1311 Digital Dream Epsilon 1.3 sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam sunplus 0733:2211 Jenoptik jdc 21 LCD sunplus 0733:2221 Mercury Digital Pro 3.1p sunplus 0733:3261 Concord 3045 spca536a sunplus 0733:3281 Cyberpix S550V +spca506 0734:043b 3DeMon USB Capture aka +spca500 084d:0003 D-Link DSC-350 +spca500 08ca:0103 Aiptek PocketDV sunplus 08ca:0104 Aiptek PocketDVII 1.3 sunplus 08ca:0106 Aiptek Pocket DV3100+ sunplus 08ca:2008 Aiptek Mini PenCam 2 M @@ -173,66 +169,72 @@ sunplus 08ca:2028 Aiptek PocketCam4M sunplus 08ca:2040 Aiptek PocketDV4100M sunplus 08ca:2042 Aiptek PocketDV5100 sunplus 08ca:2060 Aiptek PocketDV5300 -sunplus 0d64:0303 Sunplus FashionCam DXG -tv8532 046d:0920 QC Express -tv8532 046d:0921 Labtec Webcam -tv8532 0545:808b Veo Stingray -tv8532 0545:8333 Veo Stingray tv8532 0923:010f ICM532 cams -vc032x 046d:0892 Logitech Orbicam -vc032x 046d:0896 Logitech Orbicam +mars 093a:050f Mars-Semi Pc-Camera +pac207 093a:2460 PAC207 Qtec Webcam 100 +pac207 093a:2463 Philips spc200nc pac207 +pac207 093a:2464 Labtec Webcam 1200 +pac207 093a:2468 PAC207 +pac207 093a:2470 Genius GF112 +pac207 093a:2471 PAC207 Genius VideoCam ge111 +pac207 093a:2472 PAC207 Genius VideoCam ge110 +pac7311 093a:2600 PAC7311 Typhoon +pac7311 093a:2601 PAC7311 Phillips SPC610NC +pac7311 093a:2603 PAC7312 +pac7311 093a:2608 PAC7311 Trust WB-3300p +pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350 +pac7311 093a:260f PAC7311 SnakeCam +pac7311 093a:2621 PAC731x +zc3xx 0ac8:0302 Z-star Vimicro zc0302 vc032x 0ac8:0321 Vimicro generic vc0321 vc032x 0ac8:0323 Vimicro Vc0323 vc032x 0ac8:0328 A4Tech PK-130MG -vc032x 0ac8:c001 Sony embedded vimicro -vc032x 0ac8:c002 Sony embedded vimicro -vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC -zc3xx 041e:041e Creative WebCam Live! -zc3xx 041e:4017 Creative Webcam Mobile PD1090 -zc3xx 041e:401c Creative NX -zc3xx 041e:401e Creative Nx Pro -zc3xx 041e:401f Creative Webcam Notebook PD1171 -zc3xx 041e:4029 Creative WebCam Vista Pro -zc3xx 041e:4034 Creative Instant P0620 -zc3xx 041e:4035 Creative Instant P0620D -zc3xx 041e:4036 Creative Live ! -zc3xx 041e:403a Creative Nx Pro 2 -zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) -zc3xx 041e:4053 Creative Live!Cam Video IM -zc3xx 0458:7007 Genius VideoCam V2 -zc3xx 0458:700c Genius VideoCam V3 -zc3xx 0458:700f Genius VideoCam Web V2 -zc3xx 0461:0a00 MicroInnovation WebCam320 -zc3xx 046d:08a0 Logitech QC IM -zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound -zc3xx 046d:08a2 Labtec Webcam Pro -zc3xx 046d:08a3 Logitech QC Chat -zc3xx 046d:08a6 Logitech QCim -zc3xx 046d:08a7 Logitech QuickCam Image -zc3xx 046d:08a9 Logitech Notebook Deluxe -zc3xx 046d:08aa Labtec Webcam Notebook -zc3xx 046d:08ac Logitech QuickCam Cool -zc3xx 046d:08ad Logitech QCCommunicate STX -zc3xx 046d:08ae Logitech QuickCam for Notebooks -zc3xx 046d:08af Logitech QuickCam Cool -zc3xx 046d:08b9 Logitech QC IM ??? -zc3xx 046d:08d7 Logitech QCam STX -zc3xx 046d:08d9 Logitech QuickCam IM/Connect -zc3xx 046d:08d8 Logitech Notebook Deluxe -zc3xx 046d:08da Logitech QuickCam Messenger -zc3xx 046d:08dd Logitech QuickCam for Notebooks -zc3xx 0471:0325 Philips SPC 200 NC -zc3xx 0471:0326 Philips SPC 300 NC -zc3xx 0471:032d Philips spc210nc -zc3xx 0471:032e Philips spc315nc -zc3xx 055f:c005 Mustek Wcam300A -zc3xx 055f:d003 Mustek WCam300A -zc3xx 055f:d004 Mustek WCam300 AN -zc3xx 0698:2003 CTX M730V built in -zc3xx 0ac8:0302 Z-star Vimicro zc0302 zc3xx 0ac8:301b Z-Star zc301b zc3xx 0ac8:303b Vimicro 0x303b zc3xx 0ac8:305b Z-star Vimicro zc0305b zc3xx 0ac8:307b Ldlc VC302+Ov7620 +vc032x 0ac8:c001 Sony embedded vimicro +vc032x 0ac8:c002 Sony embedded vimicro +spca508 0af9:0010 Hama USB Sightcam 100 +spca508 0af9:0011 Hama USB Sightcam 100 +sonixb 0c45:6001 Genius VideoCAM NB +sonixb 0c45:6005 Sweex Tas5110 +sonixb 0c45:6007 Sonix sn9c101 + Tas5110D +sonixb 0c45:6009 spcaCam@120 +sonixb 0c45:600d spcaCam@120 +sonixb 0c45:6011 MAX Webcam (Microdia - OV6650 - SN9C101G) +sonixb 0c45:6019 Generic Sonix OV7630 +sonixb 0c45:6024 Generic Sonix Tas5130c +sonixb 0c45:6025 Xcam Shanga +sonixb 0c45:6028 Sonix Btc Pc380 +sonixb 0c45:6029 spcaCam@150 +sonixb 0c45:602c Generic Sonix OV7630 +sonixb 0c45:602d LIC-200 LG +sonixb 0c45:602e Genius VideoCam Messenger +sonixj 0c45:6040 Speed NVC 350K +sonixj 0c45:607c Sonix sn9c102p Hv7131R +sonixj 0c45:60c0 Sangha Sn535 +sonixj 0c45:60ec SN9C105+MO4000 +sonixj 0c45:60fb Surfer NoName +sonixj 0c45:60fc LG-LIC300 +sonixj 0c45:612a Avant Camera +sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix +sonixj 0c45:6130 Sonix Pccam +sonixj 0c45:6138 Sn9c120 Mo4000 +sonixj 0c45:613b Surfer SN-206 +sonixj 0c45:613c Sonix Pccam168 +sunplus 0d64:0303 Sunplus FashionCam DXG +etoms 102c:6151 Qcam Sangha CIF +etoms 102c:6251 Qcam xxxxxx VGA zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128 +spca561 10fd:7e50 FlyCam Usb 100 zc3xx 10fd:8050 Typhoon Webshot II USB 300k +spca501 1776:501c Arowana 300K CMOS Camera +t613 17a1:0128 T613/TAS5130A +vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC +pac207 2001:f115 D-Link DSB-C120 +spca500 2899:012c Toptro Industrial +spca508 8086:0110 Intel Easy PC Camera +spca500 8086:0630 Intel Pocket PC Camera +spca506 99fa:8988 Grandtec V.cap +spca561 abcd:cdee Petcam diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 2ec920dc32e0..d5f6eea7d2fd 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -117,6 +117,7 @@ obj-$(CONFIG_USB_SN9C102) += sn9c102/ obj-$(CONFIG_USB_ET61X251) += et61x251/ obj-$(CONFIG_USB_PWC) += pwc/ obj-$(CONFIG_USB_ZC0301) += zc0301/ +obj-$(CONFIG_USB_GSPCA) += gspca/ obj-$(CONFIG_USB_IBMCAM) += usbvideo/ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig index a04e413e1258..42b90742b40b 100644 --- a/drivers/media/video/gspca/Kconfig +++ b/drivers/media/video/gspca/Kconfig @@ -2,7 +2,7 @@ config USB_GSPCA tristate "USB GSPCA driver" depends on VIDEO_V4L2 ---help--- - Say Y here if you want support for various USB cameras. + Say Y here if you want support for various USB webcams. See for more info. diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile index d959f7771526..e68a8965297a 100644 --- a/drivers/media/video/gspca/Makefile +++ b/drivers/media/video/gspca/Makefile @@ -1,7 +1,29 @@ -obj-$(CONFIG_GSPCA) += gspca_main.o \ - gspca_pac207.o gspca_stk014.o gspca_zc3xx.o +obj-$(CONFIG_USB_GSPCA) += gspca_main.o \ + gspca_conex.o gspca_etoms.o gspca_mars.o \ + gspca_ov519.o gspca_pac207.o gspca_pac7311.o \ + gspca_sonixb.o gspca_sonixj.o gspca_spca500.o gspca_spca501.o \ + gspca_spca505.o gspca_spca506.o gspca_spca508.o gspca_spca561.o \ + gspca_sunplus.o gspca_stk014.o gspca_t613.o gspca_tv8532.o \ + gspca_vc032x.o gspca_zc3xx.o gspca_main-objs := gspca.o +gspca_conex-objs := conex.o +gspca_etoms-objs := etoms.o +gspca_mars-objs := mars.o +gspca_ov519-objs := ov519.o gspca_pac207-objs := pac207.o +gspca_pac7311-objs := pac7311.o +gspca_sonixb-objs := sonixb.o +gspca_sonixj-objs := sonixj.o +gspca_spca500-objs := spca500.o +gspca_spca501-objs := spca501.o +gspca_spca505-objs := spca505.o +gspca_spca506-objs := spca506.o +gspca_spca508-objs := spca508.o +gspca_spca561-objs := spca561.o gspca_stk014-objs := stk014.o +gspca_sunplus-objs := sunplus.o +gspca_t613-objs := t613.o +gspca_tv8532-objs := tv8532.o +gspca_vc032x-objs := vc032x.o gspca_zc3xx-objs := zc3xx.o diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c new file mode 100644 index 000000000000..b0294c9274e3 --- /dev/null +++ b/drivers/media/video/gspca/conex.c @@ -0,0 +1,1059 @@ +/* + * Connexant Cx11646 library + * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "conex" + +#include "gspca.h" +#define CONEX_CAM 1 /* special JPEG header */ +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + + unsigned char qindex; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 0xd4, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0x0a, + .maximum = 0x1f, + .step = 1, + .default_value = 0x0c, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 7, + .step = 1, + .default_value = 3, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 176, 144, 3}, + {V4L2_PIX_FMT_JPEG, 320, 240, 2}, + {V4L2_PIX_FMT_JPEG, 352, 288, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +static void reg_r(struct usb_device *dev, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, + index, buffer, length, + 500); + PDEBUG(D_USBI, "reg read i:%02x -> %02x", index, *buffer); +} + +static void reg_w(struct usb_device *dev, + __u16 index, + const __u8 *buffer, __u16 length) +{ + PDEBUG(D_USBO, "reg write i:%02x = %02x", index, *buffer); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, + index, (__u8 *) buffer, length, + 500); +} + +static const __u8 cx_sensor_init[][4] = { + {0x88, 0x11, 0x01, 0x01}, + {0x88, 0x12, 0x70, 0x01}, + {0x88, 0x0f, 0x00, 0x01}, + {0x88, 0x05, 0x01, 0x01}, + {} +}; + +static const __u8 cx11646_fw1[][3] = { + {0x00, 0x02, 0x00}, + {0x01, 0x43, 0x00}, + {0x02, 0xA7, 0x00}, + {0x03, 0x8B, 0x01}, + {0x04, 0xE9, 0x02}, + {0x05, 0x08, 0x04}, + {0x06, 0x08, 0x05}, + {0x07, 0x07, 0x06}, + {0x08, 0xE7, 0x06}, + {0x09, 0xC6, 0x07}, + {0x0A, 0x86, 0x08}, + {0x0B, 0x46, 0x09}, + {0x0C, 0x05, 0x0A}, + {0x0D, 0xA5, 0x0A}, + {0x0E, 0x45, 0x0B}, + {0x0F, 0xE5, 0x0B}, + {0x10, 0x85, 0x0C}, + {0x11, 0x25, 0x0D}, + {0x12, 0xC4, 0x0D}, + {0x13, 0x45, 0x0E}, + {0x14, 0xE4, 0x0E}, + {0x15, 0x64, 0x0F}, + {0x16, 0xE4, 0x0F}, + {0x17, 0x64, 0x10}, + {0x18, 0xE4, 0x10}, + {0x19, 0x64, 0x11}, + {0x1A, 0xE4, 0x11}, + {0x1B, 0x64, 0x12}, + {0x1C, 0xE3, 0x12}, + {0x1D, 0x44, 0x13}, + {0x1E, 0xC3, 0x13}, + {0x1F, 0x24, 0x14}, + {0x20, 0xA3, 0x14}, + {0x21, 0x04, 0x15}, + {0x22, 0x83, 0x15}, + {0x23, 0xE3, 0x15}, + {0x24, 0x43, 0x16}, + {0x25, 0xA4, 0x16}, + {0x26, 0x23, 0x17}, + {0x27, 0x83, 0x17}, + {0x28, 0xE3, 0x17}, + {0x29, 0x43, 0x18}, + {0x2A, 0xA3, 0x18}, + {0x2B, 0x03, 0x19}, + {0x2C, 0x63, 0x19}, + {0x2D, 0xC3, 0x19}, + {0x2E, 0x22, 0x1A}, + {0x2F, 0x63, 0x1A}, + {0x30, 0xC3, 0x1A}, + {0x31, 0x23, 0x1B}, + {0x32, 0x83, 0x1B}, + {0x33, 0xE2, 0x1B}, + {0x34, 0x23, 0x1C}, + {0x35, 0x83, 0x1C}, + {0x36, 0xE2, 0x1C}, + {0x37, 0x23, 0x1D}, + {0x38, 0x83, 0x1D}, + {0x39, 0xE2, 0x1D}, + {0x3A, 0x23, 0x1E}, + {0x3B, 0x82, 0x1E}, + {0x3C, 0xC3, 0x1E}, + {0x3D, 0x22, 0x1F}, + {0x3E, 0x63, 0x1F}, + {0x3F, 0xC1, 0x1F}, + {} +}; +static void cx11646_fw(struct gspca_dev*gspca_dev) +{ + __u8 val; + int i = 0; + + val = 0x02; + reg_w(gspca_dev->dev, 0x006a, &val, 1); + while (cx11646_fw1[i][1]) { + reg_w(gspca_dev->dev, 0x006b, cx11646_fw1[i], 3); + i++; + } + val = 0x00; + reg_w(gspca_dev->dev, 0x006a, &val, 1); +} + +static __u8 cxsensor[] = { + 0x88, 0x12, 0x70, 0x01, + 0x88, 0x0d, 0x02, 0x01, + 0x88, 0x0f, 0x00, 0x01, + 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */ + 0x88, 0x02, 0x10, 0x01, + 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */ + 0x88, 0x0B, 0x00, 0x01, + 0x88, 0x0A, 0x0A, 0x01, + 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */ + 0x88, 0x05, 0x01, 0x01, + 0xA1, 0x18, 0x00, 0x01, + 0x00 +}; + +static __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; +static __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; +static __u8 reg10[] = { 0xb1, 0xb1 }; +static __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ +static __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; + /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */ +static __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; + /* 320{0x04,0x0c,0x05,0x0f}; //320 */ +static __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ +static __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; + +static void cx_sensor(struct gspca_dev*gspca_dev) +{ + __u8 val = 0; + int i = 0; + __u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int length = 0; + __u8 *ptsensor = cxsensor; + + reg_w(gspca_dev->dev, 0x0020, reg20, 8); + reg_w(gspca_dev->dev, 0x0028, reg28, 8); + reg_w(gspca_dev->dev, 0x0010, reg10, 8); + val = 0x03; + reg_w(gspca_dev->dev, 0x0092, &val, 1); + + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 0: + reg_w(gspca_dev->dev, 0x0071, reg71a, 4); + break; + case 1: + reg_w(gspca_dev->dev, 0x0071, reg71b, 4); + break; + default: +/* case 2: */ + reg_w(gspca_dev->dev, 0x0071, reg71c, 4); + break; + case 3: + reg_w(gspca_dev->dev, 0x0071, reg71d, 4); + break; + } + reg_w(gspca_dev->dev, 0x007b, reg7b, 6); + val = 0x00; + reg_w(gspca_dev->dev, 0x00f8, &val, 1); + reg_w(gspca_dev->dev, 0x0010, reg10, 8); + val = 0x41; + reg_w(gspca_dev->dev, 0x0098, &val, 1); + for (i = 0; i < 11; i++) { + if (i == 3 || i == 5 || i == 8) + length = 8; + else + length = 4; + reg_w(gspca_dev->dev, 0x00e5, ptsensor, length); + if (length == 4) + reg_r(gspca_dev->dev, 0x00e8, &val, 1); + else + reg_r(gspca_dev->dev, 0x00e8, bufread, length); + ptsensor += length; + } + reg_r(gspca_dev->dev, 0x00e7, bufread, 8); +} + +static __u8 cx_inits_176[] = { + 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */ + 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03, + 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30, + 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF, + 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02, + 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static __u8 cx_inits_320[] = { + 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01, + 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01, + 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81, + 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, + 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02, + 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static __u8 cx_inits_352[] = { + 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03, + 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b, + 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25, + 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00, + 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, + 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02, + 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static __u8 cx_inits_640[] = { + 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01, + 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01, + 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81, + 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff, + 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02, + 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static int cx11646_initsize(struct gspca_dev *gspca_dev) +{ + __u8 *cxinit; + __u8 val; + static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; + static const __u8 reg17[] = + { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; + + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 0: + cxinit = cx_inits_640; + break; + case 1: + cxinit = cx_inits_352; + break; + default: +/* case 2: */ + cxinit = cx_inits_320; + break; + case 3: + cxinit = cx_inits_176; + break; + } + val = 0x01; + reg_w(gspca_dev->dev, 0x009a, &val, 1); + val = 0x10; + reg_w(gspca_dev->dev, 0x0010, &val, 1); + reg_w(gspca_dev->dev, 0x0012, reg12, 5); + reg_w(gspca_dev->dev, 0x0017, reg17, 8); + val = 0x00; + reg_w(gspca_dev->dev, 0x00c0, &val, 1); + val = 0x04; + reg_w(gspca_dev->dev, 0x00c1, &val, 1); + val = 0x04; + reg_w(gspca_dev->dev, 0x00c2, &val, 1); + + reg_w(gspca_dev->dev, 0x0061, cxinit, 8); + cxinit += 8; + reg_w(gspca_dev->dev, 0x00ca, cxinit, 8); + cxinit += 8; + reg_w(gspca_dev->dev, 0x00d2, cxinit, 8); + cxinit += 8; + reg_w(gspca_dev->dev, 0x00da, cxinit, 6); + cxinit += 8; + reg_w(gspca_dev->dev, 0x0041, cxinit, 8); + cxinit += 8; + reg_w(gspca_dev->dev, 0x0049, cxinit, 8); + cxinit += 8; + reg_w(gspca_dev->dev, 0x0051, cxinit, 2); + + reg_r(gspca_dev->dev, 0x0010, &val, 1); + return val; +} + +static __u8 cx_jpeg_init[][8] = { + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */ + {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11}, + {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22}, + {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26}, + {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a}, + {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73}, + {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D}, + {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0}, + {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01}, + {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12}, + {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35}, + {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31}, + {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43}, + {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A}, + {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73}, + {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95}, + {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83}, + {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}, + {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A}, + {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05}, + {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00}, + {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05}, + {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01}, + {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21}, + {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22}, + {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23}, + {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24}, + {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17}, + {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29}, + {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A}, + {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A}, + {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A}, + {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A}, + {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A}, + {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A}, + {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99}, + {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8}, + {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7}, + {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6}, + {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5}, + {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3}, + {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1}, + {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9}, + {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04}, + {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01}, + {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04}, + {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07}, + {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14}, + {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33}, + {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16}, + {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19}, + {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36}, + {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46}, + {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56}, + {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66}, + {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76}, + {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85}, + {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94}, + {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3}, + {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2}, + {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA}, + {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9}, + {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8}, + {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7}, + {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6}, + {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F}, + {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22}, + {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11}, + {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00}, + {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08}, + {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00}, + {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA}, + {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02}, + {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */ +}; + + +static __u8 cxjpeg_640[][8] = { + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */ + {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d}, + {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a}, + {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d}, + {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38}, + {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57}, + {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F}, + {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79}, + {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01}, + {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E}, + {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28}, + {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25}, + {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33}, + {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44}, + {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57}, + {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71}, + {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63}, + {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00}, + {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, + {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, + {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, + {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF}, + {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80}, + {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, + {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, + {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, + {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ +}; +static __u8 cxjpeg_352[][8] = { + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, + {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a}, + {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14}, + {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17}, + {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, + {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, + {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, + {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, + {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, + {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, + {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, + {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, + {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, + {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, + {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, + {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, + {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, + {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00}, + {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, + {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, + {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, + {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF}, + {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60}, + {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, + {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, + {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, + {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; +static __u8 cxjpeg_320[][8] = { + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05}, + {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04}, + {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08}, + {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09}, + {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11}, + {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A}, + {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D}, + {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24}, + {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01}, + {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04}, + {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C}, + {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B}, + {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F}, + {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14}, + {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A}, + {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22}, + {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E}, + {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00}, + {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, + {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, + {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, + {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF}, + {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40}, + {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, + {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, + {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, + {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ +}; +static __u8 cxjpeg_176[][8] = { + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, + {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A}, + {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14}, + {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17}, + {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C}, + {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44}, + {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A}, + {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F}, + {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01}, + {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B}, + {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F}, + {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D}, + {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28}, + {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35}, + {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44}, + {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58}, + {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D}, + {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00}, + {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00}, + {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22}, + {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55}, + {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF}, + {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0}, + {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02}, + {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00}, + {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, + {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; +static __u8 cxjpeg_qtable[][8] = { /* 640 take with the zcx30x part */ + {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08}, + {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07}, + {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a}, + {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f}, + {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c}, + {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c}, + {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30}, + {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d}, + {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01}, + {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a}, + {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32}, + {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */ +}; + + +static void cx11646_jpegInit(struct gspca_dev*gspca_dev) +{ + __u8 val; + int i; + int length; + + val = 0x01; + reg_w(gspca_dev->dev, 0x00c0, &val, 1); + val = 0x00; + reg_w(gspca_dev->dev, 0x00c3, &val, 1); + val = 0x00; + reg_w(gspca_dev->dev, 0x00c0, &val, 1); + reg_r(gspca_dev->dev, 0x0001, &val, 1); + length = 8; + for (i = 0; i < 79; i++) { + if (i == 78) + length = 6; + reg_w(gspca_dev->dev, 0x0008, cx_jpeg_init[i], length); + } + reg_r(gspca_dev->dev, 0x0002, &val, 1); + val = 0x14; + reg_w(gspca_dev->dev, 0x0055, &val, 1); +} + +static __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; +static __u8 regE5_8[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; +static __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; +static __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; +static __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; +static __u8 reg51[] = { 0x77, 0x03 }; +static __u8 reg70 = 0x03; + +static void cx11646_jpeg(struct gspca_dev*gspca_dev) +{ + __u8 val; + int i; + int length = 8; + __u8 Reg55 = 0x14; + __u8 bufread[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + int retry = 50; + + val = 0x01; + reg_w(gspca_dev->dev, 0x00c0, &val, 1); + val = 0x00; + reg_w(gspca_dev->dev, 0x00c3, &val, 1); + val = 0x00; + reg_w(gspca_dev->dev, 0x00c0, &val, 1); + reg_r(gspca_dev->dev, 0x0001, &val, 1); + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 0: + for (i = 0; i < 27; i++) { + if (i == 26) + length = 2; + reg_w(gspca_dev->dev, 0x0008, + cxjpeg_640[i], length); + } + Reg55 = 0x28; + break; + case 1: + for (i = 0; i < 27; i++) { + if (i == 26) + length = 2; + reg_w(gspca_dev->dev, 0x0008, + cxjpeg_352[i], length); + } + Reg55 = 0x16; + break; + default: +/* case 2: */ + for (i = 0; i < 27; i++) { + if (i == 26) + length = 2; + reg_w(gspca_dev->dev, 0x0008, + cxjpeg_320[i], length); + } + Reg55 = 0x14; + break; + case 3: + for (i = 0; i < 27; i++) { + if (i == 26) + length = 2; + reg_w(gspca_dev->dev, 0x0008, + cxjpeg_176[i], length); + } + Reg55 = 0x0B; + break; + } + + reg_r(gspca_dev->dev, 0x0002, &val, 1); + val = Reg55; + reg_w(gspca_dev->dev, 0x0055, &val, 1); + reg_r(gspca_dev->dev, 0x0002, &val, 1); + reg_w(gspca_dev->dev, 0x0010, reg10, 2); + val = 0x02; + reg_w(gspca_dev->dev, 0x0054, &val, 1); + val = 0x01; + reg_w(gspca_dev->dev, 0x0054, &val, 1); + val = 0x94; + reg_w(gspca_dev->dev, 0x0000, &val, 1); + val = 0xc0; + reg_w(gspca_dev->dev, 0x0053, &val, 1); + val = 0xe1; + reg_w(gspca_dev->dev, 0x00fc, &val, 1); + val = 0x00; + reg_w(gspca_dev->dev, 0x0000, &val, 1); + /* wait for completion */ + while (retry--) { + reg_r(gspca_dev->dev, 0x0002, &val, 1); + /* 0x07 until 0x00 */ + if (val == 0x00) + break; + val = 0x00; + reg_w(gspca_dev->dev, 0x0053, &val, 1); + } + if (retry == 0) + PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); + /* send the qtable now */ + reg_r(gspca_dev->dev, 0x0001, &val, 1); /* -> 0x18 */ + length = 8; + for (i = 0; i < 18; i++) { + if (i == 17) + length = 2; + reg_w(gspca_dev->dev, 0x0008, + cxjpeg_qtable[i], length); + + } + reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */ + reg_r(gspca_dev->dev, 0x0053, &val, 1); /* 0x00 */ + val = 0x02; + reg_w(gspca_dev->dev, 0x0054, &val, 1); + val = 0x01; + reg_w(gspca_dev->dev, 0x0054, &val, 1); + val = 0x94; + reg_w(gspca_dev->dev, 0x0000, &val, 1); + val = 0xc0; + reg_w(gspca_dev->dev, 0x0053, &val, 1); + + reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ + reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ + reg_r(gspca_dev->dev, 0x001f, &val, 1); /* 0x38 */ + reg_w(gspca_dev->dev, 0x0012, reg12, 5); + reg_w(gspca_dev->dev, 0x00e5, regE5_8, 8); + reg_r(gspca_dev->dev, 0x00e8, bufread, 8); + reg_w(gspca_dev->dev, 0x00e5, regE5a, 4); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + val = 0x01; + reg_w(gspca_dev->dev, 0x009a, &val, 1); + reg_w(gspca_dev->dev, 0x00e5, regE5b, 4); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + + reg_w(gspca_dev->dev, 0x0051, reg51, 2); + reg_w(gspca_dev->dev, 0x0010, reg10, 2); + reg_w(gspca_dev->dev, 0x0070, ®70, 1); +} + +static void cx11646_init1(struct gspca_dev *gspca_dev) +{ + __u8 val; + int i = 0; + + val = 0; + reg_w(gspca_dev->dev, 0x0010, &val, 1); + reg_w(gspca_dev->dev, 0x0053, &val, 1); + reg_w(gspca_dev->dev, 0x0052, &val, 1); + val = 0x2f; + reg_w(gspca_dev->dev, 0x009b, &val, 1); + val = 0x10; + reg_w(gspca_dev->dev, 0x009c, &val, 1); + reg_r(gspca_dev->dev, 0x0098, &val, 1); + val = 0x40; + reg_w(gspca_dev->dev, 0x0098, &val, 1); + reg_r(gspca_dev->dev, 0x0099, &val, 1); + val = 0x07; + reg_w(gspca_dev->dev, 0x0099, &val, 1); + val = 0x40; + reg_w(gspca_dev->dev, 0x0039, &val, 1); + val = 0xff; + reg_w(gspca_dev->dev, 0x003c, &val, 1); + val = 0x1f; + reg_w(gspca_dev->dev, 0x003f, &val, 1); + val = 0x40; + reg_w(gspca_dev->dev, 0x003d, &val, 1); +/* val= 0x60; */ +/* reg_w(gspca_dev->dev,0x00,0x00,0x003d,&val,1); */ + reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */ + + while (cx_sensor_init[i][0]) { + reg_w(gspca_dev->dev, 0x00e5, cx_sensor_init[i], 1); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* -> 0x00 */ + if (i == 1) { + val = 1; + reg_w(gspca_dev->dev, 0x00ed, &val, 1); + reg_r(gspca_dev->dev, 0x00ed, &val, 1); /* -> 0x01 */ + } + i++; + } + val = 0x00; + reg_w(gspca_dev->dev, 0x00c3, &val, 1); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + + sd->qindex = 0; /* set the quantization table */ + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + cx11646_init1(gspca_dev); + cx11646_initsize(gspca_dev); + cx11646_fw(gspca_dev); + cx_sensor(gspca_dev); + cx11646_jpegInit(gspca_dev); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + cx11646_initsize(gspca_dev); + cx11646_fw(gspca_dev); + cx_sensor(gspca_dev); + cx11646_jpeg(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + int retry = 50; + __u8 val; + + val = 0; + reg_w(gspca_dev->dev, 0x0000, &val, 1); + reg_r(gspca_dev->dev, 0x0002, &val, 1); + val = 0; + reg_w(gspca_dev->dev, 0x0053, &val, 1); + + while (retry--) { +/* reg_r (gspca_dev->dev,0x00,0x00,0x0002,&val,1);*/ + reg_r(gspca_dev->dev, 0x0053, &val, 1); + if (val == 0) + break; + } + val = 0; + reg_w(gspca_dev->dev, 0x0000, &val, 1); + reg_r(gspca_dev->dev, 0x0002, &val, 1); + + val = 0; + reg_w(gspca_dev->dev, 0x0010, &val, 1); + reg_r(gspca_dev->dev, 0x0033, &val, 1); + val = 0xe0; + reg_w(gspca_dev->dev, 0x00fc, &val, 1); +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + if (data[0] == 0xff && data[1] == 0xd8) { + + /* start of frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + + /* put the JPEG header in the new frame */ + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x22); + data += 2; + len -= 2; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static void setbrightness(struct gspca_dev*gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; + __u8 reg51c[] = { 0x77, 0x03 }; + __u8 bright; + __u8 colors; + __u8 val; + __u8 bufread[8]; + + bright = sd->brightness; + colors = sd->colors; + regE5cbx[2] = bright; + reg51c[1] = colors; + reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8); + reg_r(gspca_dev->dev, 0x00e8, bufread, 8); + reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + + reg_w(gspca_dev->dev, 0x0051, reg51c, 2); + reg_w(gspca_dev->dev, 0x0010, reg10, 2); + reg_w(gspca_dev->dev, 0x0070, ®70, 1); +} + +static void setcontrast(struct gspca_dev*gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ + /* __u8 regE5bcx[]={0x88,0x0b,0x12,0x01}; // LSB */ + __u8 reg51c[] = { 0x77, 0x03 }; + __u8 val; + + reg51c[1] = sd->colors; + regE5acx[2] = sd->contrast; + reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4); + reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + reg_w(gspca_dev->dev, 0x0051, reg51c, 2); + reg_w(gspca_dev->dev, 0x0010, reg10, 2); + reg_w(gspca_dev->dev, 0x0070, ®70, 1); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) { + setbrightness(gspca_dev); + setcontrast(gspca_dev); + } + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c new file mode 100644 index 000000000000..c479f638413e --- /dev/null +++ b/drivers/media/video/gspca/etoms.c @@ -0,0 +1,1062 @@ +/* + * Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004) + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "etoms" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("Etoms USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + + char sensor; +#define SENSOR_PAS106 0 +#define SENSOR_TAS5130CXX 1 + signed char ag_cnt; +#define AG_CNT_START 13 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 1, + .maximum = 127, + .step = 1, + .default_value = 63, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 15, + .step = 1, + .default_value = 7, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_AUTOGAIN 3 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_SBGGR8, 320, 240, 1}, +/* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */ +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, + {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, +}; + +#define ETOMS_ALT_SIZE_1000 12 + +#define ET_GPIO_DIR_CTRL 0x04 /* Control IO bit[0..5] (0 in 1 out) */ +#define ET_GPIO_OUT 0x05 /* Only IO data */ +#define ET_GPIO_IN 0x06 /* Read Only IO data */ +#define ET_RESET_ALL 0x03 +#define ET_ClCK 0x01 +#define ET_CTRL 0x02 /* enable i2c OutClck Powerdown mode */ + +#define ET_COMP 0x12 /* Compression register */ +#define ET_MAXQt 0x13 +#define ET_MINQt 0x14 +#define ET_COMP_VAL0 0x02 +#define ET_COMP_VAL1 0x03 + +#define ET_REG1d 0x1d +#define ET_REG1e 0x1e +#define ET_REG1f 0x1f +#define ET_REG20 0x20 +#define ET_REG21 0x21 +#define ET_REG22 0x22 +#define ET_REG23 0x23 +#define ET_REG24 0x24 +#define ET_REG25 0x25 +/* base registers for luma calculation */ +#define ET_LUMA_CENTER 0x39 + +#define ET_G_RED 0x4d +#define ET_G_GREEN1 0x4e +#define ET_G_BLUE 0x4f +#define ET_G_GREEN2 0x50 +#define ET_G_GR_H 0x51 +#define ET_G_GB_H 0x52 + +#define ET_O_RED 0x34 +#define ET_O_GREEN1 0x35 +#define ET_O_BLUE 0x36 +#define ET_O_GREEN2 0x37 + +#define ET_SYNCHRO 0x68 +#define ET_STARTX 0x69 +#define ET_STARTY 0x6a +#define ET_WIDTH_LOW 0x6b +#define ET_HEIGTH_LOW 0x6c +#define ET_W_H_HEIGTH 0x6d + +#define ET_REG6e 0x6e /* OBW */ +#define ET_REG6f 0x6f /* OBW */ +#define ET_REG70 0x70 /* OBW_AWB */ +#define ET_REG71 0x71 /* OBW_AWB */ +#define ET_REG72 0x72 /* OBW_AWB */ +#define ET_REG73 0x73 /* Clkdelay ns */ +#define ET_REG74 0x74 /* test pattern */ +#define ET_REG75 0x75 /* test pattern */ + +#define ET_I2C_CLK 0x8c +#define ET_PXL_CLK 0x60 + +#define ET_I2C_BASE 0x89 +#define ET_I2C_COUNT 0x8a +#define ET_I2C_PREFETCH 0x8b +#define ET_I2C_REG 0x88 +#define ET_I2C_DATA7 0x87 +#define ET_I2C_DATA6 0x86 +#define ET_I2C_DATA5 0x85 +#define ET_I2C_DATA4 0x84 +#define ET_I2C_DATA3 0x83 +#define ET_I2C_DATA2 0x82 +#define ET_I2C_DATA1 0x81 +#define ET_I2C_DATA0 0x80 + +#define PAS106_REG2 0x02 /* pxlClk = systemClk/(reg2) */ +#define PAS106_REG3 0x03 /* line/frame H [11..4] */ +#define PAS106_REG4 0x04 /* line/frame L [3..0] */ +#define PAS106_REG5 0x05 /* exposure time line offset(default 5) */ +#define PAS106_REG6 0x06 /* exposure time pixel offset(default 6) */ +#define PAS106_REG7 0x07 /* signbit Dac (default 0) */ +#define PAS106_REG9 0x09 +#define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ +#define PAS106_REG13 0x13 /* end i2c write */ + +static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; + +static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; + +static __u8 I2c3[] = { 0x12, 0x05 }; + +static __u8 I2c4[] = { 0x41, 0x08 }; + +static void Et_RegRead(struct usb_device *dev, + __u16 index, __u8 *buffer, int len) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0, index, buffer, len, 500); +} + +static void Et_RegWrite(struct usb_device *dev, + __u16 index, __u8 *buffer, __u16 len) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0, index, buffer, len, 500); +} + +static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 * buffer, + __u16 length, __u8 mode) +{ +/* buffer should be [D0..D7] */ + int i, j; + __u8 base = 0x40; /* sensor base for the pas106 */ + __u8 ptchcount = 0; + + ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); +/* set the base address */ + Et_RegWrite(dev, ET_I2C_BASE, &base, 1); +/* set count and prefetch */ + Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); +/* set the register base */ + Et_RegWrite(dev, ET_I2C_REG, ®, 1); + j = length - 1; + for (i = 0; i < length; i++) { + Et_RegWrite(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); + j--; + } + return 0; +} + +static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 * buffer, + __u16 length, __u8 mode) +{ +/* buffer should be [D0..D7] */ + int i, j; + __u8 base = 0x40; /* sensor base for the pas106 */ + __u8 ptchcount; + __u8 prefetch = 0x02; + + ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); +/* set the base address */ + Et_RegWrite(dev, ET_I2C_BASE, &base, 1); +/* set count and prefetch */ + Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); +/* set the register base */ + Et_RegWrite(dev, ET_I2C_REG, ®, 1); + Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); + prefetch = 0x00; + Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); + j = length - 1; + for (i = 0; i < length; i++) { + Et_RegRead(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); + j--; + } + return 0; +} + +static int Et_WaitStatus(struct usb_device *dev) +{ + __u8 bytereceived; + int retry = 10; + + while (retry--) { + Et_RegRead(dev, ET_ClCK, &bytereceived, 1); + if (bytereceived != 0) + return 1; + } + return 0; +} + +static int Et_videoOff(struct usb_device *dev) +{ + int err; + __u8 stopvideo = 0; + + Et_RegWrite(dev, ET_GPIO_OUT, &stopvideo, 1); + err = Et_WaitStatus(dev); + if (!err) + PDEBUG(D_ERR, "timeout Et_waitStatus VideoON"); + return err; +} + +static int Et_videoOn(struct usb_device *dev) +{ + int err; + __u8 startvideo = 0x10; /* set Bit5 */ + + Et_RegWrite(dev, ET_GPIO_OUT, &startvideo, 1); + err = Et_WaitStatus(dev); + if (!err) + PDEBUG(D_ERR, "timeout Et_waitStatus VideoOFF"); + return err; +} + +static void Et_init2(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 value = 0x00; + __u8 received = 0x00; + __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; + + PDEBUG(D_STREAM, "Open Init2 ET"); + value = 0x2f; + Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); + value = 0x10; + Et_RegWrite(dev, ET_GPIO_OUT, &value, 1); + Et_RegRead(dev, ET_GPIO_IN, &received, 1); + value = 0x14; /* 0x14 // 0x16 enabled pattern */ + Et_RegWrite(dev, ET_ClCK, &value, 1); + value = 0x1b; + Et_RegWrite(dev, ET_CTRL, &value, 1); + + /* compression et subsampling */ + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + value = ET_COMP_VAL1; /* 320 */ + else + value = ET_COMP_VAL0; /* 640 */ + Et_RegWrite(dev, ET_COMP, &value, 1); + value = 0x1f; + Et_RegWrite(dev, ET_MAXQt, &value, 1); + value = 0x04; + Et_RegWrite(dev, ET_MINQt, &value, 1); + /* undocumented registers */ + value = 0xff; + Et_RegWrite(dev, ET_REG1d, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG1e, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG1f, &value, 1); + value = 0x35; + Et_RegWrite(dev, ET_REG20, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_REG21, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_REG22, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG23, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG24, &value, 1); + value = 0x0f; + Et_RegWrite(dev, ET_REG25, &value, 1); + /* colors setting */ + value = 0x11; + Et_RegWrite(dev, 0x30, &value, 1); /* 0x30 */ + value = 0x40; + Et_RegWrite(dev, 0x31, &value, 1); + value = 0x00; + Et_RegWrite(dev, 0x32, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_O_RED, &value, 1); /* 0x34 */ + value = 0x00; + Et_RegWrite(dev, ET_O_GREEN1, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_O_BLUE, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_O_GREEN2, &value, 1); + /*************/ + value = 0x80; + Et_RegWrite(dev, ET_G_RED, &value, 1); /* 0x4d */ + value = 0x80; + Et_RegWrite(dev, ET_G_GREEN1, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_G_BLUE, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_G_GREEN2, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_G_GR_H, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_G_GB_H, &value, 1); /* 0x52 */ + /* Window control registers */ + + value = 0x80; /* use cmc_out */ + Et_RegWrite(dev, 0x61, &value, 1); + + value = 0x02; + Et_RegWrite(dev, 0x62, &value, 1); + value = 0x03; + Et_RegWrite(dev, 0x63, &value, 1); + value = 0x14; + Et_RegWrite(dev, 0x64, &value, 1); + value = 0x0e; + Et_RegWrite(dev, 0x65, &value, 1); + value = 0x02; + Et_RegWrite(dev, 0x66, &value, 1); + value = 0x02; + Et_RegWrite(dev, 0x67, &value, 1); + + /**************************************/ + value = 0x8f; + Et_RegWrite(dev, ET_SYNCHRO, &value, 1); /* 0x68 */ + value = 0x69; /* 0x6a //0x69 */ + Et_RegWrite(dev, ET_STARTX, &value, 1); + value = 0x0d; /* 0x0d //0x0c */ + Et_RegWrite(dev, ET_STARTY, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); + value = 0xe0; + Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); + value = 0x60; + Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */ + value = 0x86; + Et_RegWrite(dev, ET_REG6e, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_REG6f, &value, 1); + value = 0x26; + Et_RegWrite(dev, ET_REG70, &value, 1); + value = 0x7a; + Et_RegWrite(dev, ET_REG71, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_REG72, &value, 1); + /* Clock Pattern registers ***************** */ + value = 0x00; + Et_RegWrite(dev, ET_REG73, &value, 1); + value = 0x18; /* 0x28 */ + Et_RegWrite(dev, ET_REG74, &value, 1); + value = 0x0f; /* 0x01 */ + Et_RegWrite(dev, ET_REG75, &value, 1); + /**********************************************/ + value = 0x20; + Et_RegWrite(dev, 0x8a, &value, 1); + value = 0x0f; + Et_RegWrite(dev, 0x8d, &value, 1); + value = 0x08; + Et_RegWrite(dev, 0x8e, &value, 1); + /**************************************/ + value = 0x08; + Et_RegWrite(dev, 0x03, &value, 1); + value = 0x03; + Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + value = 0xff; + Et_RegWrite(dev, 0x81, &value, 1); + value = 0x00; + Et_RegWrite(dev, 0x80, &value, 1); + value = 0xff; + Et_RegWrite(dev, 0x81, &value, 1); + value = 0x20; + Et_RegWrite(dev, 0x80, &value, 1); + value = 0x01; + Et_RegWrite(dev, 0x03, &value, 1); + value = 0x00; + Et_RegWrite(dev, 0x03, &value, 1); + value = 0x08; + Et_RegWrite(dev, 0x03, &value, 1); + /********************************************/ + + /* Et_RegRead(dev,0x0,ET_I2C_BASE,&received,1); + always 0x40 as the pas106 ??? */ + /* set the sensor */ + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + value = 0x04; /* 320 */ + Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + /* now set by fifo the FormatLine setting */ + Et_RegWrite(dev, 0x62, FormLine, 6); + } else { /* 640 */ + /* setting PixelClock + 0x03 mean 24/(3+1) = 6 Mhz + 0x05 -> 24/(5+1) = 4 Mhz + 0x0b -> 24/(11+1) = 2 Mhz + 0x17 -> 24/(23+1) = 1 Mhz + */ + value = 0x1e; /* 0x17 */ + Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + /* now set by fifo the FormatLine setting */ + Et_RegWrite(dev, 0x62, FormLine, 6); + } + + /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ + value = 0x47; /* 0x47; */ + Et_RegWrite(dev, 0x81, &value, 1); + value = 0x40; /* 0x40; */ + Et_RegWrite(dev, 0x80, &value, 1); + /* Pedro change */ + /* Brightness change Brith+ decrease value */ + /* Brigth- increase value */ + /* original value = 0x70; */ + value = 0x30; /* 0x20; */ + Et_RegWrite(dev, 0x81, &value, 1); /* set brightness */ + value = 0x20; /* 0x20; */ + Et_RegWrite(dev, 0x80, &value, 1); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + static __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; + __u8 i2cflags = 0x01; + /* __u8 green = 0; */ + __u8 colors = sd->colors; + + I2cc[3] = colors; /* red */ + I2cc[0] = 15 - colors; /* blue */ + /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ + /* I2cc[1] = I2cc[2] = green; */ + if (sd->sensor == SENSOR_PAS106) { + Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); + Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof(I2cc), 1); + } +/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", + I2cc[3], I2cc[0], green); */ +} + +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + /* __u8 valblue = 0; */ + __u8 valred; + + if (sd->sensor == SENSOR_PAS106) { + /* Et_i2cread(gspca_dev->dev,PAS106_REG9,&valblue,1,1); */ + Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1); + sd->colors = valred & 0x0f; + } +} + +static void Et_init1(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 value = 0x00; + __u8 received = 0x00; +/* __u8 I2c0 [] ={0x0a,0x12,0x05,0x22,0xac,0x00,0x01,0x00}; */ + __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; + /* try 1/120 0x6d 0xcd 0x40 */ +/* __u8 I2c0 [] ={0x0a,0x12,0x05,0xfe,0xfe,0xc0,0x01,0x00}; + * 1/60000 hmm ?? */ + + PDEBUG(D_STREAM, "Open Init1 ET"); + value = 7; + Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); + Et_RegRead(dev, ET_GPIO_IN, &received, 1); + value = 1; + Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + value = 0; + Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + value = 0x10; + Et_RegWrite(dev, ET_ClCK, &value, 1); + value = 0x19; + Et_RegWrite(dev, ET_CTRL, &value, 1); + /* compression et subsampling */ + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + value = ET_COMP_VAL1; + else + value = ET_COMP_VAL0; + + PDEBUG(D_STREAM, "Open mode %d Compression %d", + gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode, + value); + Et_RegWrite(dev, ET_COMP, &value, 1); + value = 0x1d; + Et_RegWrite(dev, ET_MAXQt, &value, 1); + value = 0x02; + Et_RegWrite(dev, ET_MINQt, &value, 1); + /* undocumented registers */ + value = 0xff; + Et_RegWrite(dev, ET_REG1d, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG1e, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG1f, &value, 1); + value = 0x35; + Et_RegWrite(dev, ET_REG20, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_REG21, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_REG22, &value, 1); + value = 0xf7; + Et_RegWrite(dev, ET_REG23, &value, 1); + value = 0xff; + Et_RegWrite(dev, ET_REG24, &value, 1); + value = 0x07; + Et_RegWrite(dev, ET_REG25, &value, 1); + /* colors setting */ + value = 0x80; + Et_RegWrite(dev, ET_G_RED, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_G_GREEN1, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_G_BLUE, &value, 1); + value = 0x80; + Et_RegWrite(dev, ET_G_GREEN2, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_G_GR_H, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_G_GB_H, &value, 1); + /* Window control registers */ + value = 0xf0; + Et_RegWrite(dev, ET_SYNCHRO, &value, 1); + value = 0x56; /* 0x56 */ + Et_RegWrite(dev, ET_STARTX, &value, 1); + value = 0x05; /* 0x04 */ + Et_RegWrite(dev, ET_STARTY, &value, 1); + value = 0x60; + Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); + value = 0x20; + Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); + value = 0x50; + Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); + value = 0x86; + Et_RegWrite(dev, ET_REG6e, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_REG6f, &value, 1); + value = 0x86; + Et_RegWrite(dev, ET_REG70, &value, 1); + value = 0x14; + Et_RegWrite(dev, ET_REG71, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_REG72, &value, 1); + /* Clock Pattern registers */ + value = 0x00; + Et_RegWrite(dev, ET_REG73, &value, 1); + value = 0x00; + Et_RegWrite(dev, ET_REG74, &value, 1); + value = 0x0a; + Et_RegWrite(dev, ET_REG75, &value, 1); + value = 0x04; + Et_RegWrite(dev, ET_I2C_CLK, &value, 1); + value = 0x01; + Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + /* set the sensor */ + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + I2c0[0] = 0x06; + Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); + Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); + value = 0x06; + Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); + Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); + /* value = 0x1f; */ + value = 0x04; + Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); + } else { + I2c0[0] = 0x0a; + + Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); + Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); + value = 0x0a; + + Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); + Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); + value = 0x04; + /* value = 0x10; */ + Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); + /* bit 2 enable bit 1:2 select 0 1 2 3 + value = 0x07; * curve 0 * + Et_i2cwrite(dev,PAS106_REG0f,&value,1,1); + */ + } + +/* value = 0x01; */ +/* value = 0x22; */ +/* Et_i2cwrite(dev, PAS106_REG5, &value, 1, 1); */ + /* magnetude and sign bit for DAC */ + Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1); + /* now set by fifo the whole colors setting */ + Et_RegWrite(dev, ET_G_RED, GainRGBG, 6); + getcolors(gspca_dev); + setcolors(gspca_dev); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; +/* switch (vendor) { */ +/* case 0x102c: * Etoms */ + switch (product) { + case 0x6151: + sd->sensor = SENSOR_PAS106; /* Etoms61x151 */ + break; + case 0x6251: + sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */ + break; +/* } */ +/* break; */ + } + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 1; + if (sd->sensor == SENSOR_PAS106) { + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + } else { + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + } + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int err; + __u8 value; + + PDEBUG(D_STREAM, "Initialize ET1"); + if (sd->sensor == SENSOR_PAS106) + Et_init1(gspca_dev); + else + Et_init2(gspca_dev); + value = 0x08; + Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + err = Et_videoOff(dev); + PDEBUG(D_STREAM, "Et_Init_VideoOff %d", err); + return 0; +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int err; + __u8 value; + + if (sd->sensor == SENSOR_PAS106) + Et_init1(gspca_dev); + else + Et_init2(gspca_dev); + + value = 0x08; + Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + err = Et_videoOn(dev); + PDEBUG(D_STREAM, "Et_VideoOn %d", err); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + int err; + + err = Et_videoOff(gspca_dev->dev); + PDEBUG(D_STREAM, "Et_VideoOff %d", err); + +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + __u8 brightness = sd->brightness; + + for (i = 0; i < 4; i++) + Et_RegWrite(gspca_dev->dev, (ET_O_RED + i), &brightness, 1); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int brightness = 0; + __u8 value = 0; + + for (i = 0; i < 4; i++) { + Et_RegRead(gspca_dev->dev, (ET_O_RED + i), &value, 1); + brightness += value; + } + sd->brightness = brightness >> 3; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; + __u8 contrast = sd->contrast; + + memset(RGBG, contrast, sizeof RGBG - 2); + Et_RegWrite(gspca_dev->dev, ET_G_RED, RGBG, 6); +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + int contrast = 0; + __u8 value = 0; + + for (i = 0; i < 4; i++) { + Et_RegRead(gspca_dev->dev, (ET_G_RED + i), &value, 1); + contrast += value; + } + sd->contrast = contrast >> 2; +} + +static __u8 Et_getgainG(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value = 0; + + if (sd->sensor == SENSOR_PAS106) { + Et_i2cread(gspca_dev->dev, PAS106_REG0e, &value, 1, 1); + PDEBUG(D_CONF, "Etoms gain G %d", value); + return value; + } + return 0x1f; +} + +static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 i2cflags = 0x01; + + if (sd->sensor == SENSOR_PAS106) { + Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); + Et_i2cwrite(dev, PAS106_REG0e, &gain, 1, 1); + } +} + +#define BLIMIT(bright) \ + (__u8)((bright > 0x1f)?0x1f:((bright < 4)?3:bright)) +#define LIMIT(color) \ + (unsigned char)((color > 0xff)?0xff:((color < 0)?0:color)) + +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 GRBG[] = { 0, 0, 0, 0 }; + __u8 luma = 0; + __u8 luma_mean = 128; + __u8 luma_delta = 20; + __u8 spring = 4; + int Gbright = 0; + __u8 r, g, b; + + Gbright = Et_getgainG(gspca_dev); + Et_RegRead(dev, ET_LUMA_CENTER, GRBG, 4); + g = (GRBG[0] + GRBG[3]) >> 1; + r = GRBG[1]; + b = GRBG[2]; + r = ((r << 8) - (r << 4) - (r << 3)) >> 10; + b = ((b << 7) >> 10); + g = ((g << 9) + (g << 7) + (g << 5)) >> 10; + luma = LIMIT(r + g + b); + PDEBUG(D_FRAM, "Etoms luma G %d", luma); + if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { + Gbright += (luma_mean - luma) >> spring; + Gbright = BLIMIT(Gbright); + PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright); + Et_setgainG(gspca_dev, (__u8) Gbright); + } +} + +#undef BLIMIT +#undef LIMIT + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd; + int seqframe; + + seqframe = data[0] & 0x3f; + len = (int) (((data[0] & 0xc0) << 2) | data[1]); + if (seqframe == 0x3f) { + PDEBUG(D_FRAM, + "header packet found datalength %d !!", len); + PDEBUG(D_FRAM, "G %d R %d G %d B %d", + data[2], data[3], data[4], data[5]); + data += 30; + /* don't change datalength as the chips provided it */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + sd = (struct sd *) gspca_dev; + if (sd->ag_cnt >= 0) { + if (--sd->ag_cnt < 0) { + sd->ag_cnt = AG_CNT_START; + setautogain(gspca_dev); + } + } + return; + } + if (len) { + data += 8; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + } else { /* Drop Packet */ + gspca_dev->last_packet_type = DISCARD_PACKET; + } +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcolors(gspca_dev); + *val = sd->colors; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (val) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, + {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} + +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 423ebbdc4b4f..5583c53e4863 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -35,24 +35,24 @@ #include "gspca.h" -/* option */ -#define GSPCA_HLP 0 +#undef CONFIG_VIDEO_V4L1_COMPAT /* global values */ #define DEF_NURBS 2 /* default number of URBs (mmap) */ +#define USR_NURBS 5 /* default number of URBs (userptr) */ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) -static const char version[] = "0.2.15"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; static int video_nr = -1; static int comp_fac = 30; /* Buffer size ratio when compressed in % */ -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG int gspca_debug = D_ERR | D_PROBE; EXPORT_SYMBOL(gspca_debug); @@ -81,224 +81,7 @@ static void PDEBUG_MODE(char *txt, __u32 pixfmt, int w, int h) #define GSPCA_MEMORY_NO 0 /* V4L2_MEMORY_xxx starts from 1 */ #define GSPCA_MEMORY_READ 7 -#ifndef GSPCA_HLP #define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE) -#else -#define GSPCA_BUF_FLAG_DECODE 0x1000 /* internal buffer flag */ -#define BUF_ALL_FLAGS (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE \ - | GSPCA_BUF_FLAG_DECODE) - -static int autostart = 4; -module_param(autostart, int, 0644); -MODULE_PARM_DESC(autostart, - "Automatically start the helper process"); - -/* try to start the helper process */ -static void start_hlp(void) -{ - int ret; - static char *argv[] = {"gspca_hlp", NULL}; - static char *env[] = {NULL}; - - if (autostart <= 0) { - if (autostart < 0) - PDEBUG(D_ERR|D_PROBE, "Too many helper restart"); - return; - } - autostart--; - if (autostart == 0) - autostart = -1; - ret = call_usermodehelper("/sbin/gspca_hlp", argv, env, - UMH_WAIT_EXEC); - if (ret != 0) - PDEBUG(D_ERR|D_PROBE, - "/sbin/gspca_hlp start failed %d", ret); -} - -/* /dev/gspca_hlp stuff */ -#include -#include "gspca_hlp.h" - -/* !! possible decodings defined in decoder.c */ -static __u32 bayer_to_tb[] = { - V4L2_PIX_FMT_SBGGR8, - V4L2_PIX_FMT_YUYV, - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_RGB24, - V4L2_PIX_FMT_BGR24, - V4L2_PIX_FMT_RGB565, -}; -static __u32 jpeg_to_tb[] = { - V4L2_PIX_FMT_JPEG, - V4L2_PIX_FMT_YUYV, - V4L2_PIX_FMT_YUV420, - V4L2_PIX_FMT_RGB24, - V4L2_PIX_FMT_BGR24, - V4L2_PIX_FMT_RGB565, -}; - -/* /dev/gspca_hlp device */ -struct hlp_dev { - struct gspca_dev *gspca_dev; /* associated device */ - struct gspca_frame *frame; /* frame being decoded */ - __u32 pixfmt; /* webcam pixel format */ - atomic_t nevent; /* nb of frames ready to decode */ - wait_queue_head_t wq; /* wait queue */ - char fr_d; /* next frame to decode */ -} *hlp; - -static int hlp_open(struct inode *inode, struct file *file) -{ - struct hlp_dev *hlp_dev; - - PDEBUG(D_CONF, "hlp open"); - if (hlp != 0) - return -EBUSY; - hlp_dev = kzalloc(sizeof *hlp_dev, GFP_KERNEL); - if (hlp_dev == NULL) { - err("couldn't kzalloc hlp struct"); - return -EIO; - } - init_waitqueue_head(&hlp_dev->wq); - file->private_data = hlp_dev; - hlp = hlp_dev; - return 0; -} - -static int hlp_close(struct inode *inode, struct file *file) -{ - struct gspca_dev *gspca_dev; - int mode; - - PDEBUG(D_CONF, "hlp close"); - file->private_data = NULL; - - /* stop decoding */ - gspca_dev = hlp->gspca_dev; - if (gspca_dev != 0) { - mode = gspca_dev->curr_mode; - gspca_dev->pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; - } - - /* destroy the helper structure */ - kfree(hlp); - hlp = 0; - - /* try to restart the helper process */ - start_hlp(); - return 0; -} - -static ssize_t hlp_read(struct file *file, char __user *buf, - size_t cnt, loff_t *ppos) -{ - struct hlp_dev *hlp_dev = file->private_data; - struct gspca_dev *gspca_dev; - struct gspca_frame *frame; - struct gspca_hlp_read_hd head; - int i, j, len, ret; - - PDEBUG(D_FRAM, "hlp read (%d)", cnt); - - /* check / wait till a frame is ready */ - for (;;) { - gspca_dev = hlp_dev->gspca_dev; - if (gspca_dev != 0 && gspca_dev->streaming) { - i = hlp_dev->fr_d; /* frame to decode */ - j = gspca_dev->fr_queue[i]; - frame = &gspca_dev->frame[j]; - if (frame->v4l2_buf.flags & GSPCA_BUF_FLAG_DECODE) - break; - } - ret = wait_event_interruptible(hlp_dev->wq, - atomic_read(&hlp_dev->nevent) > 0); - if (ret < 0) { /* helper process is killed */ - autostart = 0; /* don't restart it */ - return ret; - } - } - atomic_dec(&hlp_dev->nevent); - hlp_dev->fr_d = (i + 1) % gspca_dev->nframes; - PDEBUG(D_FRAM, "hlp read q:%d i:%d d:%d o:%d", - gspca_dev->fr_q, - gspca_dev->fr_i, - hlp_dev->fr_d, - gspca_dev->fr_o); - - hlp_dev->frame = frame; /* memorize the current frame */ - len = frame->v4l2_buf.bytesused; - if (cnt < sizeof head - sizeof head.data + len) -/*fixme: special errno?*/ - return -EINVAL; - head.pixfmt_out = gspca_dev->pixfmt; - head.pixfmt_in = hlp_dev->pixfmt; - head.width = gspca_dev->width; - head.height = gspca_dev->height; - copy_to_user(buf, &head, sizeof head); - copy_to_user(buf + sizeof head - sizeof head.data, - frame->data, len); - return sizeof head - sizeof head.data + len; -} - -static ssize_t hlp_write(struct file *file, - const char __user *buf, - size_t cnt, loff_t *ppos) -{ - struct hlp_dev *hlp_dev = file->private_data; - struct gspca_dev *gspca_dev; - struct gspca_frame *frame; - - PDEBUG(D_FRAM, "hlp write (%d)", cnt); - gspca_dev = hlp_dev->gspca_dev; - if (gspca_dev == 0) - return cnt; - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; - if (!gspca_dev->streaming) - goto out; - frame = hlp_dev->frame; - hlp_dev->frame = 0; - if (frame == 0) - goto out; - if (cnt > frame->v4l2_buf.length) { - PDEBUG(D_ERR|D_FRAM, "bad frame size %d - %d", - cnt, frame->v4l2_buf.length); - cnt = -EINVAL; - goto out; - } - copy_from_user(frame->data, buf, cnt); - frame->v4l2_buf.bytesused = cnt; - frame->v4l2_buf.flags &= ~(V4L2_BUF_FLAG_QUEUED - | GSPCA_BUF_FLAG_DECODE); - frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; - mutex_unlock(&gspca_dev->queue_lock); - atomic_inc(&gspca_dev->nevent); - wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ - PDEBUG(D_FRAM, "hlp write q:%d i:%d d:%d o:%d", - gspca_dev->fr_q, - gspca_dev->fr_i, - hlp_dev->fr_d, - gspca_dev->fr_o); - return cnt; -out: - mutex_unlock(&gspca_dev->queue_lock); - return cnt; -} - -static struct file_operations hlp_fops = { - .owner = THIS_MODULE, - .open = hlp_open, - .release = hlp_close, - .read = hlp_read, - .write = hlp_write, - .llseek = no_llseek -}; -static struct miscdevice hlp_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "gspca_hlp", - .fops = &hlp_fops, -}; -#endif /* * VMA operations. @@ -331,10 +114,14 @@ static void fill_frame(struct gspca_dev *gspca_dev, struct urb *urb) { struct gspca_frame *frame; - unsigned char *data; /* address of data in the iso message */ + __u8 *data; /* address of data in the iso message */ int i, j, len, st; cam_pkt_op pkt_scan; + if (urb->status != 0) { + PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status); + return; /* disconnection ? */ + } pkt_scan = gspca_dev->sd_desc->pkt_scan; for (i = 0; i < urb->number_of_packets; i++) { @@ -350,20 +137,21 @@ static void fill_frame(struct gspca_dev *gspca_dev, /* check the packet status and length */ len = urb->iso_frame_desc[i].actual_length; + if (len == 0) + continue; st = urb->iso_frame_desc[i].status; if (st) { - PDEBUG(D_ERR, "ISOC data error: [%d] len=%d, status=%d", + PDEBUG(D_ERR, + "ISOC data error: [%d] len=%d, status=%d", i, len, st); gspca_dev->last_packet_type = DISCARD_PACKET; continue; } - if (len == 0) - continue; /* let the packet be analyzed by the subdriver */ PDEBUG(D_PACK, "packet [%d] o:%d l:%d", i, urb->iso_frame_desc[i].offset, len); - data = (unsigned char *) urb->transfer_buffer + data = (__u8 *) urb->transfer_buffer + urb->iso_frame_desc[i].offset; pkt_scan(gspca_dev, frame, data, len); } @@ -390,7 +178,8 @@ static void fill_frame(struct gspca_dev *gspca_dev, * buffers are in user space (userptr). The frame detection * and copy is done by the application. */ -static void isoc_irq_mmap(struct urb *urb) +static void isoc_irq_mmap(struct urb *urb +) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; @@ -400,7 +189,8 @@ static void isoc_irq_mmap(struct urb *urb) fill_frame(gspca_dev, urb); } -static void isoc_irq_user(struct urb *urb) +static void isoc_irq_user(struct urb *urb +) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; int i; @@ -459,7 +249,7 @@ static void isoc_transfer(struct gspca_dev *gspca_dev) struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, struct gspca_frame *frame, - unsigned char *data, + __u8 *data, int len) { int i, j; @@ -503,23 +293,10 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, /* if last packet, wake the application and advance in the queue */ if (packet_type == LAST_PACKET) { frame->v4l2_buf.bytesused = frame->data_end - frame->data; -#ifndef GSPCA_HLP frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; atomic_inc(&gspca_dev->nevent); wake_up_interruptible(&gspca_dev->wq); /* event = new frame */ -#else /*GSPCA_HLP*/ - if (hlp != 0 && hlp->gspca_dev == gspca_dev) { - frame->v4l2_buf.flags |= GSPCA_BUF_FLAG_DECODE; - atomic_inc(&hlp->nevent); - wake_up_interruptible(&hlp->wq); - } else { - frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED; - frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE; - atomic_inc(&gspca_dev->nevent); - wake_up_interruptible(&gspca_dev->wq); /* new frame */ - } -#endif /*GSPCA_HLP*/ i = (gspca_dev->fr_i + 1) % gspca_dev->nframes; gspca_dev->fr_i = i; PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d", @@ -581,13 +358,13 @@ static void rvfree(void *mem, unsigned long size) static __u32 get_v4l2_depth(__u32 pixfmt) { switch (pixfmt) { - case V4L2_PIX_FMT_BGR32: +/* case V4L2_PIX_FMT_BGR32: case V4L2_PIX_FMT_RGB32: - return 32; + return 32; */ case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ case V4L2_PIX_FMT_BGR24: return 24; - case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ +/* case V4L2_PIX_FMT_RGB565: * 'RGBP' */ case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ return 16; @@ -596,6 +373,9 @@ static __u32 get_v4l2_depth(__u32 pixfmt) case V4L2_PIX_FMT_MJPEG: case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ + case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ + case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ + case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed BGGR bayer */ return 8; } PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", @@ -603,7 +383,7 @@ static __u32 get_v4l2_depth(__u32 pixfmt) (pixfmt >> 8) & 0xff, (pixfmt >> 16) & 0xff, pixfmt >> 24); - return -EINVAL; + return 24; } static int gspca_get_buff_size(struct gspca_dev *gspca_dev) @@ -632,7 +412,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, count = GSPCA_MAX_FRAMES; /* if compressed (JPEG), reduce the buffer size */ if (gspca_is_compressed(gspca_dev->pixfmt)) - frsz = (frsz * comp_fac) / 100 + 600; /* plus JPEG header */ + frsz = (frsz * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ frsz = PAGE_ALIGN(frsz); PDEBUG(D_STREAM, "new fr_sz: %d", frsz); gspca_dev->frsz = frsz; @@ -660,17 +440,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev, } } gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; -#ifdef GSPCA_HLP - { - struct hlp_dev *hlp_dev; - - hlp_dev = hlp; - if (hlp != 0 && hlp_dev->gspca_dev == gspca_dev) { - hlp_dev->fr_d = 0; - atomic_set(&hlp_dev->nevent, 0); - } - } -#endif /*GSPCA_HLP*/ gspca_dev->last_packet_type = DISCARD_PACKET; gspca_dev->sequence = 0; atomic_set(&gspca_dev->nevent, 0); @@ -752,13 +521,14 @@ struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) int i, ret; intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface); + ep = NULL; i = gspca_dev->alt; /* previous alt setting */ while (--i > 0) { /* alt 0 is unusable */ ep = alt_isoc(&intf->altsetting[i], gspca_dev->cam.epaddr); if (ep) break; } - if (i <= 0) { + if (ep == NULL) { err("no ISOC endpoint found"); return NULL; } @@ -796,11 +566,14 @@ static int create_urbs(struct gspca_dev *gspca_dev, "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); /*fixme:change for userptr*/ /*fixme:don't submit all URBs when userptr*/ - gspca_dev->nurbs = nurbs = DEF_NURBS; - if (gspca_dev->memory == V4L2_MEMORY_MMAP) + if (gspca_dev->memory == V4L2_MEMORY_MMAP) { usb_complete = isoc_irq_mmap; - else + nurbs = DEF_NURBS; + } else { usb_complete = isoc_irq_user; + nurbs = USR_NURBS; + } + gspca_dev->nurbs = nurbs; for (n = 0; n < nurbs; n++) { urb = usb_alloc_urb(npkt, GFP_KERNEL); if (!urb) { @@ -904,16 +677,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) { gspca_dev->streaming = 0; atomic_set(&gspca_dev->nevent, 0); -#ifdef GSPCA_HLP - { - struct hlp_dev *hlp_dev; - - hlp_dev = hlp; - if (hlp_dev != 0 - && hlp_dev->gspca_dev == gspca_dev) - atomic_set(&hlp_dev->nevent, 0); - } -#endif if (gspca_dev->present) { gspca_dev->sd_desc->stopN(gspca_dev); destroy_urbs(gspca_dev); @@ -979,15 +742,11 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fmtdesc) { struct gspca_dev *gspca_dev = priv; - int i; -#ifndef GSPCA_HLP - int j, index; + int i, j, index; __u32 fmt_tb[8]; -#endif PDEBUG(D_CONF, "enum fmt cap"); -#ifndef GSPCA_HLP /* give an index to each format */ index = 0; j = 0; @@ -1013,36 +772,6 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, fmtdesc->pixelformat = fmt_tb[index]; if (gspca_is_compressed(fmt_tb[index])) fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; -#else /*GSPCA_HLP*/ - /* !! code tied to the decoding functions in decoder.c */ - i = gspca_dev->cam.nmodes - 1; - if (fmtdesc->index == 0) { /* (assume one format per subdriver) */ - fmtdesc->pixelformat = gspca_dev->cam.cam_mode[i].pixfmt; - if (gspca_is_compressed(fmtdesc->pixelformat)) - fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED; - } else { - if (hlp == 0 - || (hlp->gspca_dev != 0 - && hlp->gspca_dev != gspca_dev)) - return -EINVAL; - switch (gspca_dev->cam.cam_mode[i].pixfmt) { - case V4L2_PIX_FMT_JPEG: - if (fmtdesc->index >= sizeof jpeg_to_tb - / sizeof jpeg_to_tb[0]) - return -EINVAL; - fmtdesc->pixelformat = jpeg_to_tb[fmtdesc->index]; - break; - case V4L2_PIX_FMT_SBGGR8: - if (fmtdesc->index >= sizeof bayer_to_tb - / sizeof bayer_to_tb[0]) - return -EINVAL; - fmtdesc->pixelformat = bayer_to_tb[fmtdesc->index]; - break; - default: - return -EINVAL; - } - } -#endif /*GSPCA_HLP*/ fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; fmtdesc->description[0] = fmtdesc->pixelformat & 0xff; fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff; @@ -1057,25 +786,12 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, { struct gspca_dev *gspca_dev = priv; -#ifdef GSPCA_HLP - int i; - - /* if the pixel format is not the one of the device and - * if the helper is inactive or busy, restore */ - i = gspca_dev->curr_mode; - if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[i].pixfmt) { - struct hlp_dev *hlp_dev; - - hlp_dev = hlp; - if (hlp_dev == 0 || hlp_dev->gspca_dev != gspca_dev) - gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; - } -#endif /*GSPCA_HLP*/ - + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; fmt->fmt.pix.width = gspca_dev->width; fmt->fmt.pix.height = gspca_dev->height; fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) { PDEBUG_MODE("get fmt cap", fmt->fmt.pix.pixelformat, @@ -1099,13 +815,15 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, { int w, h, mode, mode2, frsz; + if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; w = fmt->fmt.pix.width; h = fmt->fmt.pix.height; /* (luvcview problem) */ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); #endif @@ -1121,44 +839,11 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, if (mode2 >= 0) { mode = mode2; } else { - __u32 pixfmt; - - pixfmt = gspca_dev->cam.cam_mode[mode].pixfmt; -#ifndef GSPCA_HLP /* no chance, return this mode */ - fmt->fmt.pix.pixelformat = pixfmt; -#else /*GSPCA_HLP*/ - if (hlp != 0 - && (hlp->gspca_dev == 0 - || hlp->gspca_dev == gspca_dev) -/* decoding works for JPEG and Bayer only */ - && (pixfmt == V4L2_PIX_FMT_JPEG - || pixfmt == V4L2_PIX_FMT_SBGGR8)) { - switch (fmt->fmt.pix.pixelformat) { - case V4L2_PIX_FMT_YUYV: /* 'YUYV' */ - case V4L2_PIX_FMT_BGR24: /* 'BGR3' */ - case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ - case V4L2_PIX_FMT_YUV420: /* 'YU12' */ - case V4L2_PIX_FMT_RGB565: /* 'RGBP' */ - break; - default: { - /* return any of the supported fmt's */ - __u8 u; - - u = get_jiffies_64(); - u %= sizeof bayer_to_tb - / sizeof bayer_to_tb[0] - 1; - fmt->fmt.pix.pixelformat = - bayer_to_tb[u + 1]; - break; - } - } - } else { - fmt->fmt.pix.pixelformat = pixfmt; - } -#endif /*GSPCA_HLP*/ -#ifdef GSPCA_DEBUG + fmt->fmt.pix.pixelformat = + gspca_dev->cam.cam_mode[mode].pixfmt; +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) { PDEBUG_MODE("new format", fmt->fmt.pix.pixelformat, @@ -1198,7 +883,17 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int ret; -#ifdef GSPCA_DEBUG +#ifdef CONFIG_VIDEO_V4L1_COMPAT + /* if v4l1 got JPEG */ + if (fmt->fmt.pix.pixelformat == 0 + && gspca_dev->streaming) { + fmt->fmt.pix.width = gspca_dev->width; + fmt->fmt.pix.height = gspca_dev->height; + fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; + return 0; + } +#endif +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) { PDEBUG_MODE("set fmt cap", fmt->fmt.pix.pixelformat, @@ -1218,14 +913,8 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, goto out; } -#ifndef GSPCA_HLP if (ret == gspca_dev->curr_mode) goto out; /* same mode */ -#else /*GSPCA_HLP*/ - if (ret == gspca_dev->curr_mode - && gspca_dev->pixfmt == fmt->fmt.pix.pixelformat) - goto out; /* same mode */ -#endif /*GSPCA_HLP*/ if (gspca_dev->streaming) { ret = -EBUSY; @@ -1236,26 +925,6 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, gspca_dev->pixfmt = fmt->fmt.pix.pixelformat; gspca_dev->curr_mode = ret; -#ifdef GSPCA_HLP - /* if frame decoding is required */ - if (gspca_dev->pixfmt != gspca_dev->cam.cam_mode[ret].pixfmt) { - struct hlp_dev *hlp_dev; - - hlp_dev = hlp; - if (hlp_dev == 0 - || (hlp_dev->gspca_dev != 0 - && hlp_dev->gspca_dev != gspca_dev)) { /* helper busy */ - fmt->fmt.pix.pixelformat = - gspca_dev->pixfmt = - gspca_dev->cam.cam_mode[ret].pixfmt; - } else { /* helper active */ - hlp_dev->gspca_dev = gspca_dev; - hlp_dev->pixfmt = gspca_dev->cam.cam_mode[ret].pixfmt; - hlp_dev->fr_d = gspca_dev->fr_i; - } - } else if (hlp != 0 && hlp->gspca_dev == gspca_dev) - hlp->gspca_dev = 0; -#endif /*GSPCA_HLP*/ ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); @@ -1294,7 +963,7 @@ static int dev_open(struct inode *inode, struct file *file) } gspca_dev->users++; file->private_data = gspca_dev; -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG /* activate the v4l2 debug */ if (gspca_debug & D_V4L2) gspca_dev->vdev.debug |= 3; @@ -1329,22 +998,6 @@ static int dev_close(struct inode *inode, struct file *file) frame_free(gspca_dev); gspca_dev->capt_file = 0; gspca_dev->memory = GSPCA_MEMORY_NO; -#ifdef GSPCA_HLP - { - struct hlp_dev *hlp_dev; - int mode; - - hlp_dev = hlp; - if (hlp_dev != 0 - && hlp_dev->gspca_dev == gspca_dev) { - hlp_dev->gspca_dev = 0; - hlp_dev->frame = 0; - mode = gspca_dev->curr_mode; - gspca_dev->pixfmt = - gspca_dev->cam.cam_mode[mode].pixfmt; - } - } -#endif /*GSPCA_HLP*/ } file->private_data = NULL; mutex_unlock(&gspca_dev->queue_lock); @@ -1370,23 +1023,38 @@ static int vidioc_querycap(struct file *file, void *priv, return 0; } +/* the use of V4L2_CTRL_FLAG_NEXT_CTRL asks for the controls to be sorted */ static int vidioc_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *q_ctrl) { struct gspca_dev *gspca_dev = priv; int i; - - PDEBUG(D_CONF, "queryctrl"); + u32 id; + + id = q_ctrl->id; + if (id & V4L2_CTRL_FLAG_NEXT_CTRL) { + id &= V4L2_CTRL_ID_MASK; + id++; + for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { + if (id >= gspca_dev->sd_desc->ctrls[i].qctrl.id) { + memcpy(q_ctrl, + &gspca_dev->sd_desc->ctrls[i].qctrl, + sizeof *q_ctrl); + return 0; + } + } + return -EINVAL; + } for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { - if (q_ctrl->id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { + if (id == gspca_dev->sd_desc->ctrls[i].qctrl.id) { memcpy(q_ctrl, &gspca_dev->sd_desc->ctrls[i].qctrl, sizeof *q_ctrl); return 0; } } - if (q_ctrl->id >= V4L2_CID_BASE - && q_ctrl->id <= V4L2_CID_LASTP1) { + if (id >= V4L2_CID_BASE + && id <= V4L2_CID_LASTP1) { q_ctrl->flags |= V4L2_CTRL_FLAG_DISABLED; return 0; } @@ -1489,13 +1157,8 @@ static int vidioc_reqbufs(struct file *file, void *priv, return -EINVAL; switch (rb->memory) { case V4L2_MEMORY_MMAP: - break; case V4L2_MEMORY_USERPTR: -#ifdef GSPCA_HLP - if (hlp == 0 || hlp->gspca_dev != gspca_dev) - break; -#endif - return -EINVAL; + break; default: return -EINVAL; } @@ -1578,7 +1241,7 @@ static int vidioc_streamon(struct file *file, void *priv, if (ret < 0) goto out; } -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_STREAM) { PDEBUG_MODE("stream on OK", gspca_dev->pixfmt, @@ -1657,7 +1320,7 @@ static int vidioc_g_parm(struct file *filp, void *priv, { struct gspca_dev *gspca_dev = priv; - memset(parm, 0, sizeof parm); + memset(parm, 0, sizeof *parm); parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; parm->parm.capture.readbuffers = gspca_dev->nbufread; return 0; @@ -1677,6 +1340,12 @@ static int vidioc_s_parm(struct file *filp, void *priv, return 0; } +static int vidioc_s_std(struct file *filp, void *priv, + v4l2_std_id *parm) +{ + return 0; +} + #ifdef CONFIG_VIDEO_V4L1_COMPAT static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) @@ -1686,29 +1355,32 @@ static int vidiocgmbuf(struct file *file, void *priv, PDEBUG(D_STREAM, "cgmbuf"); if (gspca_dev->nframes == 0) { - struct v4l2_requestbuffers rb; int ret; - __u32 pixfmt; - short width, height; - - /* as the final format is not yet defined, allocate - buffers with the max size */ - pixfmt = gspca_dev->pixfmt; - width = gspca_dev->width; - height = gspca_dev->height; - gspca_dev->pixfmt = V4L2_PIX_FMT_BGR32; - gspca_dev->width = 640; - gspca_dev->height = 480; - memset(&rb, 0, sizeof rb); - rb.count = 4; - rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - rb.memory = V4L2_MEMORY_MMAP; - ret = vidioc_reqbufs(file, priv, &rb); - gspca_dev->pixfmt = pixfmt; - gspca_dev->width = width; - gspca_dev->height = height; - if (ret != 0) - return ret; + + { + struct v4l2_format fmt; + + memset(&fmt, 0, sizeof fmt); + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + i = gspca_dev->cam.nmodes - 1; /* highest mode */ + fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; + fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; + ret = vidioc_s_fmt_cap(file, priv, &fmt); + if (ret != 0) + return ret; + } + { + struct v4l2_requestbuffers rb; + + memset(&rb, 0, sizeof rb); + rb.count = 4; + rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + rb.memory = V4L2_MEMORY_MMAP; + ret = vidioc_reqbufs(file, priv, &rb); + if (ret != 0) + return ret; + } } mbuf->frames = gspca_dev->nframes; mbuf->size = gspca_dev->frsz * gspca_dev->nframes; @@ -1951,7 +1623,7 @@ static int vidioc_qbuf(struct file *file, void *priv, if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { frame->data = frame->data_end = - (unsigned char *) v4l2_buf->m.userptr; + (__u8 *) v4l2_buf->m.userptr; frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; frame->v4l2_buf.length = v4l2_buf->length; } @@ -2154,6 +1826,9 @@ static struct file_operations dev_fops = { .read = dev_read, .mmap = dev_mmap, .ioctl = video_ioctl2, +#ifdef CONFIG_COMPAT + .compat_ioctl = v4l_compat_ioctl32, +#endif .llseek = no_llseek, .poll = dev_poll, }; @@ -2186,6 +1861,7 @@ static struct video_device gspca_template = { .vidioc_s_jpegcomp = vidioc_s_jpegcomp, .vidioc_g_parm = vidioc_g_parm, .vidioc_s_parm = vidioc_s_parm, + .vidioc_s_std = vidioc_s_std, #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif @@ -2207,12 +1883,8 @@ int gspca_dev_probe(struct usb_interface *intf, struct gspca_dev *gspca_dev; struct usb_device *dev = interface_to_usbdev(intf); int ret; - __u16 vendor; - __u16 product; - vendor = id->idVendor; - product = id->idProduct; - PDEBUG(D_PROBE, "probing %04x:%04x", vendor, product); + PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct); /* we don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) @@ -2309,35 +1981,24 @@ EXPORT_SYMBOL(gspca_disconnect); /* -- module insert / remove -- */ static int __init gspca_init(void) { -#ifdef GSPCA_HLP - int ret; - - /* create /dev/gspca_hlp */ - ret = misc_register(&hlp_device); - if (ret < 0) - err("misc_register err %d", ret); - start_hlp(); /* try to start the helper process */ -#endif info("main v%s registered", version); return 0; } static void __exit gspca_exit(void) { -#ifdef GSPCA_HLP - misc_deregister(&hlp_device); -#endif info("main deregistered"); } module_init(gspca_init); module_exit(gspca_exit); +#ifdef VIDEO_ADV_DEBUG module_param_named(debug, gspca_debug, int, 0644); MODULE_PARM_DESC(debug, "Debug (bit) 0x01:error 0x02:probe 0x04:config" " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" " 0x0100: v4l2"); - +#endif module_param(comp_fac, int, 0644); MODULE_PARM_DESC(comp_fac, "Buffer size ratio when compressed in percent"); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index e69d8472a284..1581fa808b6f 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -9,7 +9,26 @@ #include #include -#ifdef GSPCA_DEBUG +/* values in 2.6.27 */ +#ifndef V4L2_PIX_FMT_SPCA501 +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') +#endif +#ifndef V4L2_PIX_FMT_SPCA561 +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') +#endif + +/* values in 2.6.26 */ +#ifndef V4L2_CID_POWER_LINE_FREQUENCY +#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) +#endif +#ifndef V4L2_CID_WHITE_BALANCE_TEMPERATURE +#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE + 26) +#endif +#ifndef V4L2_CID_SHARPNESS +#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) +#endif + +#ifdef VIDEO_ADV_DEBUG /* GSPCA our debug messages */ extern int gspca_debug; #define PDEBUG(level, fmt, args...) \ @@ -47,7 +66,7 @@ extern int gspca_debug; #define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */ /* ISOC transfers */ -#define MAX_NURBS 32 /* max number of URBs (read & userptr) */ +#define MAX_NURBS 16 /* max number of URBs */ #define ISO_MAX_PKT 32 /* max number of packets in an ISOC transfer */ #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ @@ -79,7 +98,7 @@ typedef int (*cam_qmnu_op) (struct gspca_dev *, struct v4l2_querymenu *); typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, struct gspca_frame *frame, - unsigned char *data, + __u8 *data, int len); struct ctrl { @@ -116,8 +135,8 @@ struct sd_desc { #define LAST_PACKET 3 struct gspca_frame { - unsigned char *data; /* frame buffer */ - unsigned char *data_end; /* end of frame while filling */ + __u8 *data; /* frame buffer */ + __u8 *data_end; /* end of frame while filling */ int vma_use_count; struct v4l2_buffer v4l2_buf; }; @@ -135,7 +154,7 @@ struct gspca_dev { __u8 *frbuf; /* buffer for nframes */ struct gspca_frame frame[GSPCA_MAX_FRAMES]; - unsigned int frsz; /* frame size */ + __u32 frsz; /* frame size */ char nframes; /* number of frames */ char fr_i; /* frame being filled */ char fr_q; /* next frame to queue */ @@ -145,10 +164,10 @@ struct gspca_dev { __u8 iface; /* USB interface number */ __u8 alt; /* USB alternate setting */ - unsigned char curr_mode; /* current camera mode */ + __u8 curr_mode; /* current camera mode */ __u32 pixfmt; /* current mode parameters */ - short width; - short height; + __u16 width; + __u16 height; atomic_t nevent; /* number of frames done */ wait_queue_head_t wq; /* wait queue */ @@ -176,6 +195,6 @@ void gspca_disconnect(struct usb_interface *intf); struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, struct gspca_frame *frame, - unsigned char *data, + __u8 *data, int len); #endif /* GSPCAV2_H */ diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c new file mode 100644 index 000000000000..48b861d68299 --- /dev/null +++ b/drivers/media/video/gspca/mars.c @@ -0,0 +1,455 @@ +/* + * Mars-Semi MR97311A library + * Copyright (C) 2005 + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "mars" + +#include "gspca.h" +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + char qindex; +}; + +/* V4L2 controls supported by the driver */ +static struct ctrl sd_ctrls[] = { +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 2}, + {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +}; + +/* MI Register table //elvis */ +enum { + REG_HW_MI_0, + REG_HW_MI_1, + REG_HW_MI_2, + REG_HW_MI_3, + REG_HW_MI_4, + REG_HW_MI_5, + REG_HW_MI_6, + REG_HW_MI_7, + REG_HW_MI_9 = 0x09, + REG_HW_MI_B = 0x0B, + REG_HW_MI_C, + REG_HW_MI_D, + REG_HW_MI_1E = 0x1E, + REG_HW_MI_20 = 0x20, + REG_HW_MI_2B = 0x2B, + REG_HW_MI_2C, + REG_HW_MI_2D, + REG_HW_MI_2E, + REG_HW_MI_35 = 0x35, + REG_HW_MI_5F = 0x5f, + REG_HW_MI_60, + REG_HW_MI_61, + REG_HW_MI_62, + REG_HW_MI_63, + REG_HW_MI_64, + REG_HW_MI_F1 = 0xf1, + ATTR_TOTAL_MI_REG = 242 +}; + +static int pcam_reg_write(struct usb_device *dev, + __u16 index, unsigned char *value, int length) +{ + int rc; + + rc = usb_control_msg(dev, + usb_sndbulkpipe(dev, 4), + 0x12, +/* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ + 0xc8, + 0, /* value */ + index, value, length, 500); + PDEBUG(D_USBO, "reg write: 0x%02X , result = 0x%x", index, rc); + + if (rc < 0) + PDEBUG(D_ERR, "reg write: error %d", rc); + return rc; +} + +static void MISensor_BulkWrite(struct usb_device *dev, unsigned short *pch, + char Address) +{ + int result; + unsigned char data[6]; + + data[0] = 0x1f; + data[1] = 0; + data[2] = Address; + data[3] = *pch >> 8; /* high byte */ + data[4] = *pch; /* low byte */ + data[5] = 0; + + result = usb_control_msg(dev, + usb_sndbulkpipe(dev, 4), + 0x12, +/* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ + 0xc8, + 0, /* value */ + Address, /* index */ + data, 5, 500); + PDEBUG(D_USBO, "bulk write 0x%02x = 0x%04x", Address, *pch); + + if (result < 0) + PDEBUG(D_ERR, "reg write: error %d", result); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->qindex = 1; /* set the quantization table */ + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int err_code; + __u8 data[12]; + __u16 MI_buf[242]; + int h_size, v_size; + int intpipe; + /* struct usb_device *dev = pcam->dev; */ + memset(data, 0, sizeof data); + memset(MI_buf, 0, sizeof MI_buf); + + PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); + if (usb_set_interface(dev, gspca_dev->iface, 8) < 0) { + PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); + return; + } + + data[0] = 0x01; /* address */ + data[1] = 0x01; + + err_code = pcam_reg_write(dev, data[0], data, 0x02); + if (err_code < 0) + return; + + /* + Initialize the MR97113 chip register + */ + data[0] = 0x00; /* address */ + data[1] = 0x0c | 0x01; /* reg 0 */ + data[2] = 0x01; /* reg 1 */ + h_size = gspca_dev->width; + v_size = gspca_dev->height; + data[3] = h_size / 8; /* h_size , reg 2 */ + data[4] = v_size / 8; /* v_size , reg 3 */ + data[5] = 0x30; /* reg 4, MI, PAS5101 : + * 0x30 for 24mhz , 0x28 for 12mhz */ + data[6] = 4; /* reg 5, H start */ + data[7] = 0xc0; /* reg 6, gamma 1.5 */ + data[8] = 3; /* reg 7, V start */ +/* if(h_size == 320 ) */ +/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ +/* else */ + data[9] = 0x52; /* reg 8, 24MHz, no scale down */ + data[10] = 0x5d; /* reg 9, I2C device address + * [for PAS5101 (0x40)] [for MI (0x5d)] */ + + err_code = pcam_reg_write(dev, data[0], data, 0x0b); + if (err_code < 0) + return; + + data[0] = 0x23; /* address */ + data[1] = 0x09; /* reg 35, append frame header */ + + err_code = pcam_reg_write(dev, data[0], data, 0x02); + if (err_code < 0) { + PDEBUG(D_ERR, "Register write failed"); + return; + } + + data[0] = 0x3C; /* address */ +/* if (pcam->width == 1280) */ +/* data[1] = 200; * reg 60, pc-cam frame size + * (unit: 4KB) 800KB */ +/* else */ + data[1] = 50; /* 50 reg 60, pc-cam frame size + * (unit: 4KB) 200KB */ + err_code = pcam_reg_write(dev, data[0], data, 0x02); + if (err_code < 0) + return; + + if (0) { /* fixed dark-gain */ + data[1] = 0; /* reg 94, Y Gain (1.75) */ + data[2] = 0; /* reg 95, UV Gain (1.75) */ + data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ + data[4] = 0; /* reg 97, set fixed dark level */ + data[5] = 0; /* reg 98, don't care */ + } else { /* auto dark-gain */ + data[1] = 0; /* reg 94, Y Gain (auto) */ + data[2] = 0; /* reg 95, UV Gain (1.75) */ + data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ + switch (gspca_dev->width) { +/* case 1280: */ +/* data[4] = 154; + * reg 97, %3 shadow point (unit: 256 pixel) */ +/* data[5] = 51; + * reg 98, %1 highlight point + * (uint: 256 pixel) */ +/* break; */ + default: +/* case 640: */ + data[4] = 36; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 12; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + case 320: + data[4] = 9; /* reg 97, %3 shadow point + * (unit: 256 pixel) */ + data[5] = 3; /* reg 98, %1 highlight point + * (uint: 256 pixel) */ + break; + } + } + /* auto dark-gain */ + data[0] = 0x5e; /* address */ + + err_code = pcam_reg_write(dev, data[0], data, 0x06); + if (err_code < 0) + return; + + data[0] = 0x67; + data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ + err_code = pcam_reg_write(dev, data[0], data, 0x02); + if (err_code < 0) + return; + + /* + * initialize the value of MI sensor... + */ + MI_buf[REG_HW_MI_1] = 0x000a; + MI_buf[REG_HW_MI_2] = 0x000c; + MI_buf[REG_HW_MI_3] = 0x0405; + MI_buf[REG_HW_MI_4] = 0x0507; + /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */ + MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */ + MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */ + /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */ + MI_buf[REG_HW_MI_7] = 0x0002; + /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */ + /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */ + MI_buf[REG_HW_MI_9] = 0x0374; + MI_buf[REG_HW_MI_B] = 0x0000; + MI_buf[REG_HW_MI_C] = 0x0000; + MI_buf[REG_HW_MI_D] = 0x0000; + MI_buf[REG_HW_MI_1E] = 0x8000; +/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */ + MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */ + MI_buf[REG_HW_MI_2B] = 0x0008; +/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */ + MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */ + MI_buf[REG_HW_MI_2D] = 0x0008; + MI_buf[REG_HW_MI_2E] = 0x0008; + MI_buf[REG_HW_MI_35] = 0x0051; + MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */ + MI_buf[REG_HW_MI_60] = 0x0000; + MI_buf[REG_HW_MI_61] = 0x0000; + MI_buf[REG_HW_MI_62] = 0x0498; + MI_buf[REG_HW_MI_63] = 0x0000; + MI_buf[REG_HW_MI_64] = 0x0000; + MI_buf[REG_HW_MI_F1] = 0x0001; + /* changing while setting up the different value of dx/dy */ + + if (gspca_dev->width != 1280) { + MI_buf[0x01] = 0x010a; + MI_buf[0x02] = 0x014c; + MI_buf[0x03] = 0x01e5; + MI_buf[0x04] = 0x0287; + } + MI_buf[0x20] = 0x1104; + + MISensor_BulkWrite(dev, MI_buf + 1, 1); + MISensor_BulkWrite(dev, MI_buf + 2, 2); + MISensor_BulkWrite(dev, MI_buf + 3, 3); + MISensor_BulkWrite(dev, MI_buf + 4, 4); + MISensor_BulkWrite(dev, MI_buf + 5, 5); + MISensor_BulkWrite(dev, MI_buf + 6, 6); + MISensor_BulkWrite(dev, MI_buf + 7, 7); + MISensor_BulkWrite(dev, MI_buf + 9, 9); + MISensor_BulkWrite(dev, MI_buf + 0x0b, 0x0b); + MISensor_BulkWrite(dev, MI_buf + 0x0c, 0x0c); + MISensor_BulkWrite(dev, MI_buf + 0x0d, 0x0d); + MISensor_BulkWrite(dev, MI_buf + 0x1e, 0x1e); + MISensor_BulkWrite(dev, MI_buf + 0x20, 0x20); + MISensor_BulkWrite(dev, MI_buf + 0x2b, 0x2b); + MISensor_BulkWrite(dev, MI_buf + 0x2c, 0x2c); + MISensor_BulkWrite(dev, MI_buf + 0x2d, 0x2d); + MISensor_BulkWrite(dev, MI_buf + 0x2e, 0x2e); + MISensor_BulkWrite(dev, MI_buf + 0x35, 0x35); + MISensor_BulkWrite(dev, MI_buf + 0x5f, 0x5f); + MISensor_BulkWrite(dev, MI_buf + 0x60, 0x60); + MISensor_BulkWrite(dev, MI_buf + 0x61, 0x61); + MISensor_BulkWrite(dev, MI_buf + 0x62, 0x62); + MISensor_BulkWrite(dev, MI_buf + 0x63, 0x63); + MISensor_BulkWrite(dev, MI_buf + 0x64, 0x64); + MISensor_BulkWrite(dev, MI_buf + 0xf1, 0xf1); + + intpipe = usb_sndintpipe(dev, 0); + err_code = usb_clear_halt(dev, intpipe); + + data[0] = 0x00; + data[1] = 0x4d; /* ISOC transfering enable... */ + pcam_reg_write(dev, data[0], data, 0x02); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + int result; + __u8 data[2]; + + data[0] = 1; + data[1] = 0; + result = pcam_reg_write(gspca_dev->dev, data[0], data, 2); + if (result < 0) + PDEBUG(D_ERR, "Camera Stop failed"); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + int p; + + if (len < 6) { +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + for (p = 0; p < len - 6; p++) { + if (data[0 + p] == 0xff + && data[1 + p] == 0xff + && data[2 + p] == 0x00 + && data[3 + p] == 0xff + && data[4 + p] == 0x96) { + if (data[5 + p] == 0x64 + || data[5 + p] == 0x65 + || data[5 + p] == 0x66 + || data[5 + p] == 0x67) { + PDEBUG(D_PACK, "sof offset: %d leng: %d", + p, len); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, + frame, data, 0); + + /* put the JPEG header */ + jpeg_put_header(gspca_dev, frame, + sd->qindex, 0x21); + data += 16; + len -= 16; + break; + } + } + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c new file mode 100644 index 000000000000..7d6237f18ba0 --- /dev/null +++ b/drivers/media/video/gspca/ov519.c @@ -0,0 +1,2174 @@ +/** + * OV519 driver + * + * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) + * + * (This module is adapted from the ov51x-jpeg package) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#define MODULE_NAME "ov519" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Jean-Francois Moine "); +MODULE_DESCRIPTION("OV519 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* global parameters */ +static int frame_rate; + +/* Number of times to retry a failed I2C transaction. Increase this if you + * are getting "Failed to read sensor ID..." */ +static int i2c_detect_tries = 10; + +/* ov519 device descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + /* Determined by sensor type */ + short maxwidth; + short maxheight; + + unsigned char primary_i2c_slave; /* I2C write id of sensor */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + + char compress; /* Should the next frame be compressed? */ + char compress_inited; /* Are compression params uploaded? */ + char stopped; /* Streaming is temporarily paused */ + + char frame_rate; /* current Framerate (OV519 only) */ + char clockdiv; /* clockdiv override for OV519 only */ + + char sensor; /* Type of image sensor chip (SEN_*) */ +#define SEN_UNKNOWN 0 +#define SEN_OV6620 1 +#define SEN_OV6630 2 +#define SEN_OV7610 3 +#define SEN_OV7620 4 +#define SEN_OV7630 5 +#define SEN_OV7640 6 +#define SEN_OV7670 7 +#define SEN_OV76BE 8 +#define SEN_OV8610 9 + +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240}, + {V4L2_PIX_FMT_JPEG, 640, 480}, +}; +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_JPEG, 176, 144}, + {V4L2_PIX_FMT_JPEG, 352, 288}, +}; + +/* OV519 Camera interface register numbers */ +#define OV519_CAM_H_SIZE 0x10 +#define OV519_CAM_V_SIZE 0x11 +#define OV519_CAM_X_OFFSETL 0x12 +#define OV519_CAM_X_OFFSETH 0x13 +#define OV519_CAM_Y_OFFSETL 0x14 +#define OV519_CAM_Y_OFFSETH 0x15 +#define OV519_CAM_DIVIDER 0x16 +#define OV519_CAM_DFR 0x20 +#define OV519_CAM_FORMAT 0x25 + +/* OV519 System Controller register numbers */ +#define OV519_SYS_RESET1 0x51 +#define OV519_SYS_EN_CLK1 0x54 + +#define OV519_GPIO_DATA_OUT0 0x71 +#define OV519_GPIO_IO_CTRL0 0x72 + +#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ + +/* I2C registers */ +#define R51x_I2C_W_SID 0x41 +#define R51x_I2C_SADDR_3 0x42 +#define R51x_I2C_SADDR_2 0x43 +#define R51x_I2C_R_SID 0x44 +#define R51x_I2C_DATA 0x45 +#define R518_I2C_CTL 0x47 /* OV518(+) only */ + +/* I2C ADDRESSES */ +#define OV7xx0_SID 0x42 +#define OV8xx0_SID 0xa0 +#define OV6xx0_SID 0xc0 + +/* OV7610 registers */ +#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ +#define OV7610_REG_SAT 0x03 /* saturation */ +#define OV8610_REG_HUE 0x04 /* 04 reserved */ +#define OV7610_REG_CNT 0x05 /* Y contrast */ +#define OV7610_REG_BRT 0x06 /* Y brightness */ +#define OV7610_REG_COM_C 0x14 /* misc common regs */ +#define OV7610_REG_ID_HIGH 0x1c /* manufacturer ID MSB */ +#define OV7610_REG_ID_LOW 0x1d /* manufacturer ID LSB */ +#define OV7610_REG_COM_I 0x29 /* misc settings */ + +/* OV7670 registers */ +#define OV7670_REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */ +#define OV7670_REG_BLUE 0x01 /* blue gain */ +#define OV7670_REG_RED 0x02 /* red gain */ +#define OV7670_REG_VREF 0x03 /* Pieces of GAIN, VSTART, VSTOP */ +#define OV7670_REG_COM1 0x04 /* Control 1 */ +#define OV7670_REG_AECHH 0x07 /* AEC MS 5 bits */ +#define OV7670_REG_COM3 0x0c /* Control 3 */ +#define OV7670_REG_COM4 0x0d /* Control 4 */ +#define OV7670_REG_COM5 0x0e /* All "reserved" */ +#define OV7670_REG_COM6 0x0f /* Control 6 */ +#define OV7670_REG_AECH 0x10 /* More bits of AEC value */ +#define OV7670_REG_CLKRC 0x11 /* Clock control */ +#define OV7670_REG_COM7 0x12 /* Control 7 */ +#define OV7670_COM7_FMT_VGA 0x00 +#define OV7670_COM7_YUV 0x00 /* YUV */ +#define OV7670_COM7_FMT_QVGA 0x10 /* QVGA format */ +#define OV7670_COM7_FMT_MASK 0x38 +#define OV7670_COM7_RESET 0x80 /* Register reset */ +#define OV7670_REG_COM8 0x13 /* Control 8 */ +#define OV7670_COM8_AEC 0x01 /* Auto exposure enable */ +#define OV7670_COM8_AWB 0x02 /* White balance enable */ +#define OV7670_COM8_AGC 0x04 /* Auto gain enable */ +#define OV7670_COM8_BFILT 0x20 /* Band filter enable */ +#define OV7670_COM8_AECSTEP 0x40 /* Unlimited AEC step size */ +#define OV7670_COM8_FASTAEC 0x80 /* Enable fast AGC/AEC */ +#define OV7670_REG_COM9 0x14 /* Control 9 - gain ceiling */ +#define OV7670_REG_COM10 0x15 /* Control 10 */ +#define OV7670_REG_HSTART 0x17 /* Horiz start high bits */ +#define OV7670_REG_HSTOP 0x18 /* Horiz stop high bits */ +#define OV7670_REG_VSTART 0x19 /* Vert start high bits */ +#define OV7670_REG_VSTOP 0x1a /* Vert stop high bits */ +#define OV7670_REG_MVFP 0x1e /* Mirror / vflip */ +#define OV7670_MVFP_MIRROR 0x20 /* Mirror image */ +#define OV7670_REG_AEW 0x24 /* AGC upper limit */ +#define OV7670_REG_AEB 0x25 /* AGC lower limit */ +#define OV7670_REG_VPT 0x26 /* AGC/AEC fast mode op region */ +#define OV7670_REG_HREF 0x32 /* HREF pieces */ +#define OV7670_REG_TSLB 0x3a /* lots of stuff */ +#define OV7670_REG_COM11 0x3b /* Control 11 */ +#define OV7670_COM11_EXP 0x02 +#define OV7670_COM11_HZAUTO 0x10 /* Auto detect 50/60 Hz */ +#define OV7670_REG_COM12 0x3c /* Control 12 */ +#define OV7670_REG_COM13 0x3d /* Control 13 */ +#define OV7670_COM13_GAMMA 0x80 /* Gamma enable */ +#define OV7670_COM13_UVSAT 0x40 /* UV saturation auto adjustment */ +#define OV7670_REG_COM14 0x3e /* Control 14 */ +#define OV7670_REG_EDGE 0x3f /* Edge enhancement factor */ +#define OV7670_REG_COM15 0x40 /* Control 15 */ +#define OV7670_COM15_R00FF 0xc0 /* 00 to FF */ +#define OV7670_REG_COM16 0x41 /* Control 16 */ +#define OV7670_COM16_AWBGAIN 0x08 /* AWB gain enable */ +#define OV7670_REG_BRIGHT 0x55 /* Brightness */ +#define OV7670_REG_CONTRAS 0x56 /* Contrast control */ +#define OV7670_REG_GFIX 0x69 /* Fix gain control */ +#define OV7670_REG_RGB444 0x8c /* RGB 444 control */ +#define OV7670_REG_HAECC1 0x9f /* Hist AEC/AGC control 1 */ +#define OV7670_REG_HAECC2 0xa0 /* Hist AEC/AGC control 2 */ +#define OV7670_REG_BD50MAX 0xa5 /* 50hz banding step limit */ +#define OV7670_REG_HAECC3 0xa6 /* Hist AEC/AGC control 3 */ +#define OV7670_REG_HAECC4 0xa7 /* Hist AEC/AGC control 4 */ +#define OV7670_REG_HAECC5 0xa8 /* Hist AEC/AGC control 5 */ +#define OV7670_REG_HAECC6 0xa9 /* Hist AEC/AGC control 6 */ +#define OV7670_REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ +#define OV7670_REG_BD60MAX 0xab /* 60hz banding step limit */ + +struct ovsensor_window { + short x; + short y; + short width; + short height; +/* int format; */ + short quarter; /* Scale width and height down 2x */ + short clockdiv; /* Clock divisor setting */ +}; + +static unsigned char ov7670_abs_to_sm(unsigned char v) +{ + if (v > 127) + return v & 0x7f; + return (128 - v) | 0x80; +} + +/* Write a OV519 register */ +static int reg_w(struct sd *sd, __u16 index, __u8 value) +{ + int ret; + __u8 buf[4]; + + buf[0] = value; + ret = usb_control_msg(sd->gspca_dev.dev, + usb_sndctrlpipe(sd->gspca_dev.dev, 0), + 1, /* REQ_IO (ov518/519) */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, + &buf[0], 1, 500); + if (ret < 0) + PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); + return ret; +} + +/* Read from a OV519 register */ +/* returns: negative is error, pos or zero is data */ +static int reg_r(struct sd *sd, __u16 index) +{ + int ret; + __u8 buf[4]; + + ret = usb_control_msg(sd->gspca_dev.dev, + usb_rcvctrlpipe(sd->gspca_dev.dev, 0), + 1, /* REQ_IO */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, &buf[0], 1, 500); + + if (ret >= 0) + ret = buf[0]; + else + PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); + return ret; +} + +/* Read 8 values from a OV519 register */ +static int reg_r8(struct sd *sd, + __u16 index) +{ + int ret; + __u8 buf[8]; + + ret = usb_control_msg(sd->gspca_dev.dev, + usb_rcvctrlpipe(sd->gspca_dev.dev, 0), + 1, /* REQ_IO */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, index, &buf[0], 8, 500); + + if (ret >= 0) + ret = buf[0]; + else + PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); + return ret; +} + +/* + * Writes bits at positions specified by mask to an OV51x reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int reg_w_mask(struct sd *sd, + __u16 index, + __u8 value, + __u8 mask) +{ + int ret; + __u8 oldval; + + if (mask != 0xff) { + value &= mask; /* Enforce mask on value */ + ret = reg_r(sd, index); + if (ret < 0) + return ret; + + oldval = ret & ~mask; /* Clear the masked bits */ + value |= oldval; /* Set the desired bits */ + } + return reg_w(sd, index, value); +} + +/* + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_w(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int i2c_w(struct sd *sd, + __u8 reg, + __u8 value) +{ + int rc; + + PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg); + + /* Select camera register */ + rc = reg_w(sd, R51x_I2C_SADDR_3, reg); + if (rc < 0) + return rc; + + /* Write "value" to I2C data port of OV511 */ + rc = reg_w(sd, R51x_I2C_DATA, value); + if (rc < 0) + return rc; + + /* Initiate 3-byte write cycle */ + rc = reg_w(sd, R518_I2C_CTL, 0x01); + + /* wait for write complete */ + msleep(4); + if (rc < 0) + return rc; + return reg_r8(sd, R518_I2C_CTL); +} + +/* + * returns: negative is error, pos or zero is data + * + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_r(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int i2c_r(struct sd *sd, __u8 reg) +{ + int rc, value; + + /* Select camera register */ + rc = reg_w(sd, R51x_I2C_SADDR_2, reg); + if (rc < 0) + return rc; + + /* Initiate 2-byte write cycle */ + rc = reg_w(sd, R518_I2C_CTL, 0x03); + if (rc < 0) + return rc; + + /* Initiate 2-byte read cycle */ + rc = reg_w(sd, R518_I2C_CTL, 0x05); + if (rc < 0) + return rc; + value = reg_r(sd, R51x_I2C_DATA); + PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value); + return value; +} + +/* Writes bits at positions specified by mask to an I2C reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int i2c_w_mask(struct sd *sd, + __u8 reg, + __u8 value, + __u8 mask) +{ + int rc; + __u8 oldval; + + value &= mask; /* Enforce mask on value */ + rc = i2c_r(sd, reg); + if (rc < 0) + return rc; + oldval = rc & ~mask; /* Clear the masked bits */ + value |= oldval; /* Set the desired bits */ + return i2c_w(sd, reg, value); +} + +/* Temporarily stops OV511 from functioning. Must do this before changing + * registers while the camera is streaming */ +static inline int ov51x_stop(struct sd *sd) +{ + PDEBUG(D_STREAM, "stopping"); + sd->stopped = 1; + return reg_w(sd, OV519_SYS_RESET1, 0x0f); +} + +/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not + * actually stopped (for performance). */ +static inline int ov51x_restart(struct sd *sd) +{ + PDEBUG(D_STREAM, "restarting"); + if (!sd->stopped) + return 0; + sd->stopped = 0; + + /* Reinitialize the stream */ + return reg_w(sd, OV519_SYS_RESET1, 0x00); +} + +/* This does an initial reset of an OmniVision sensor and ensures that I2C + * is synchronized. Returns <0 on failure. + */ +static int init_ov_sensor(struct sd *sd) +{ + int i, success; + + /* Reset the sensor */ + if (i2c_w(sd, 0x12, 0x80) < 0) + return -EIO; + + /* Wait for it to initialize */ + msleep(150); + + for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { + if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f && + i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) { + success = 1; + continue; + } + + /* Reset the sensor */ + if (i2c_w(sd, 0x12, 0x80) < 0) + return -EIO; + /* Wait for it to initialize */ + msleep(150); + /* Dummy read to sync I2C */ + if (i2c_r(sd, 0x00) < 0) + return -EIO; + } + if (!success) + return -EIO; + PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i); + return 0; +} + +/* Switch on standard JPEG compression. Returns 0 for success. */ +static int ov519_init_compression(struct sd *sd) +{ + if (!sd->compress_inited) { + if (reg_w_mask(sd, OV519_SYS_EN_CLK1, 1 << 2, 1 << 2) < 0) { + PDEBUG(D_ERR, "Error switching to compressed mode"); + return -EIO; + } + sd->compress_inited = 1; + } + return 0; +} + +/* Set the read and write slave IDs. The "slave" argument is the write slave, + * and the read slave will be set to (slave + 1). + * This should not be called from outside the i2c I/O functions. + * Sets I2C read and write slave IDs. Returns <0 for error + */ +static int ov51x_set_slave_ids(struct sd *sd, + __u8 slave) +{ + int rc; + + rc = reg_w(sd, R51x_I2C_W_SID, slave); + if (rc < 0) + return rc; + return reg_w(sd, R51x_I2C_R_SID, slave + 1); +} + +struct ov_regvals { + __u8 reg; + __u8 val; +}; +struct ov_i2c_regvals { + __u8 reg; + __u8 val; +}; + +static int write_regvals(struct sd *sd, + struct ov_regvals *regvals, + int n) +{ + int rc; + + while (--n >= 0) { + rc = reg_w(sd, regvals->reg, regvals->val); + if (rc < 0) + return rc; + regvals++; + } + return 0; +} + +static int write_i2c_regvals(struct sd *sd, + struct ov_i2c_regvals *regvals, + int n) +{ + int rc; + + while (--n >= 0) { + rc = i2c_w(sd, regvals->reg, regvals->val); + if (rc < 0) + return rc; + regvals++; + } + return 0; +} + +/**************************************************************************** + * + * OV511 and sensor configuration + * + ***************************************************************************/ + +/* This initializes the OV8110, OV8610 sensor. The OV8110 uses + * the same register settings as the OV8610, since they are very similar. + */ +static int ov8xx0_configure(struct sd *sd) +{ + int rc; + static struct ov_i2c_regvals norm_8610[] = { + { 0x12, 0x80 }, + { 0x00, 0x00 }, + { 0x01, 0x80 }, + { 0x02, 0x80 }, + { 0x03, 0xc0 }, + { 0x04, 0x30 }, + { 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */ + { 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */ + { 0x0a, 0x86 }, + { 0x0b, 0xb0 }, + { 0x0c, 0x20 }, + { 0x0d, 0x20 }, + { 0x11, 0x01 }, + { 0x12, 0x25 }, + { 0x13, 0x01 }, + { 0x14, 0x04 }, + { 0x15, 0x01 }, /* Lin and Win think different about UV order */ + { 0x16, 0x03 }, + { 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */ + { 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */ + { 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */ + { 0x1a, 0xf5 }, + { 0x1b, 0x00 }, + { 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */ + { 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */ + { 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */ + { 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */ + { 0x26, 0xa2 }, + { 0x27, 0xea }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x80 }, + { 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */ + { 0x2c, 0xac }, + { 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */ + { 0x2e, 0x80 }, + { 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */ + { 0x4c, 0x00 }, + { 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */ + { 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */ + { 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */ + { 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */ + { 0x63, 0xff }, + { 0x64, 0x53 }, /* new windrv 090403 says 0x57, + * maybe thats wrong */ + { 0x65, 0x00 }, + { 0x66, 0x55 }, + { 0x67, 0xb0 }, + { 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */ + { 0x69, 0x02 }, + { 0x6a, 0x22 }, + { 0x6b, 0x00 }, + { 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but + deleting bit7 colors the first images red */ + { 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */ + { 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */ + { 0x6f, 0x01 }, + { 0x70, 0x8b }, + { 0x71, 0x00 }, + { 0x72, 0x14 }, + { 0x73, 0x54 }, + { 0x74, 0x00 },/* 0x60? - was 0x00, new from windrv 090403 */ + { 0x75, 0x0e }, + { 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */ + { 0x77, 0xff }, + { 0x78, 0x80 }, + { 0x79, 0x80 }, + { 0x7a, 0x80 }, + { 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */ + { 0x7c, 0x00 }, + { 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */ + { 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */ + { 0x7f, 0xfb }, + { 0x80, 0x28 }, + { 0x81, 0x00 }, + { 0x82, 0x23 }, + { 0x83, 0x0b }, + { 0x84, 0x00 }, + { 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */ + { 0x86, 0xc9 }, + { 0x87, 0x00 }, + { 0x88, 0x00 }, + { 0x89, 0x01 }, + { 0x12, 0x20 }, + { 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */ + }; + + PDEBUG(D_PROBE, "starting ov8xx0 configuration"); + + if (init_ov_sensor(sd) < 0) + PDEBUG(D_ERR|D_PROBE, "Failed to read sensor ID"); + else + PDEBUG(D_PROBE, "OV86x0 initialized"); + + /* Detect sensor (sub)type */ + rc = i2c_r(sd, OV7610_REG_COM_I); + if (rc < 0) { + PDEBUG(D_ERR, "Error detecting sensor type"); + return -1; + } + if ((rc & 3) == 1) { + PDEBUG(D_PROBE, "Sensor is an OV8610"); + sd->sensor = SEN_OV8610; + } else { + PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); + return -1; + } + PDEBUG(D_PROBE, "Writing 8610 registers"); + if (write_i2c_regvals(sd, + norm_8610, + sizeof norm_8610 / sizeof norm_8610[0])) + return -1; + + /* Set sensor-specific vars */ + sd->maxwidth = 640; + sd->maxheight = 480; + return 0; +} + +/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses + * the same register settings as the OV7610, since they are very similar. + */ +static int ov7xx0_configure(struct sd *sd) +{ + int rc, high, low; + + /* Lawrence Glaister reports: + * + * Register 0x0f in the 7610 has the following effects: + * + * 0x85 (AEC method 1): Best overall, good contrast range + * 0x45 (AEC method 2): Very overexposed + * 0xa5 (spec sheet default): Ok, but the black level is + * shifted resulting in loss of contrast + * 0x05 (old driver setting): very overexposed, too much + * contrast + */ + static struct ov_i2c_regvals norm_7610[] = { + { 0x10, 0xff }, + { 0x16, 0x06 }, + { 0x28, 0x24 }, + { 0x2b, 0xac }, + { 0x12, 0x00 }, + { 0x38, 0x81 }, + { 0x28, 0x24 }, /* 0c */ + { 0x0f, 0x85 }, /* lg's setting */ + { 0x15, 0x01 }, + { 0x20, 0x1c }, + { 0x23, 0x2a }, + { 0x24, 0x10 }, + { 0x25, 0x8a }, + { 0x26, 0xa2 }, + { 0x27, 0xc2 }, + { 0x2a, 0x04 }, + { 0x2c, 0xfe }, + { 0x2d, 0x93 }, + { 0x30, 0x71 }, + { 0x31, 0x60 }, + { 0x32, 0x26 }, + { 0x33, 0x20 }, + { 0x34, 0x48 }, + { 0x12, 0x24 }, + { 0x11, 0x01 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + }; + + static struct ov_i2c_regvals norm_7620[] = { + { 0x00, 0x00 }, /* gain */ + { 0x01, 0x80 }, /* blue gain */ + { 0x02, 0x80 }, /* red gain */ + { 0x03, 0xc0 }, /* OV7670_REG_VREF */ + { 0x06, 0x60 }, + { 0x07, 0x00 }, + { 0x0c, 0x24 }, + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0x11, 0x01 }, + { 0x12, 0x24 }, + { 0x13, 0x01 }, + { 0x14, 0x84 }, + { 0x15, 0x01 }, + { 0x16, 0x03 }, + { 0x17, 0x2f }, + { 0x18, 0xcf }, + { 0x19, 0x06 }, + { 0x1a, 0xf5 }, + { 0x1b, 0x00 }, + { 0x20, 0x18 }, + { 0x21, 0x80 }, + { 0x22, 0x80 }, + { 0x23, 0x00 }, + { 0x26, 0xa2 }, + { 0x27, 0xea }, + { 0x28, 0x20 }, + { 0x29, 0x00 }, + { 0x2a, 0x10 }, + { 0x2b, 0x00 }, + { 0x2c, 0x88 }, + { 0x2d, 0x91 }, + { 0x2e, 0x80 }, + { 0x2f, 0x44 }, + { 0x60, 0x27 }, + { 0x61, 0x02 }, + { 0x62, 0x5f }, + { 0x63, 0xd5 }, + { 0x64, 0x57 }, + { 0x65, 0x83 }, + { 0x66, 0x55 }, + { 0x67, 0x92 }, + { 0x68, 0xcf }, + { 0x69, 0x76 }, + { 0x6a, 0x22 }, + { 0x6b, 0x00 }, + { 0x6c, 0x02 }, + { 0x6d, 0x44 }, + { 0x6e, 0x80 }, + { 0x6f, 0x1d }, + { 0x70, 0x8b }, + { 0x71, 0x00 }, + { 0x72, 0x14 }, + { 0x73, 0x54 }, + { 0x74, 0x00 }, + { 0x75, 0x8e }, + { 0x76, 0x00 }, + { 0x77, 0xff }, + { 0x78, 0x80 }, + { 0x79, 0x80 }, + { 0x7a, 0x80 }, + { 0x7b, 0xe2 }, + { 0x7c, 0x00 }, + }; + + /* 7640 and 7648. The defaults should be OK for most registers. */ + static struct ov_i2c_regvals norm_7640[] = { + { 0x12, 0x80 }, + { 0x12, 0x14 }, + }; + + /* 7670. Defaults taken from OmniVision provided data, + * as provided by Jonathan Corbet of OLPC */ + static struct ov_i2c_regvals norm_7670[] = { + { OV7670_REG_COM7, OV7670_COM7_RESET }, + { OV7670_REG_TSLB, 0x04 }, /* OV */ + { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ + { OV7670_REG_CLKRC, 0x1 }, + /* + * Set the hardware window. These values from OV don't entirely + * make sense - hstop is less than hstart. But they work... + */ + { OV7670_REG_HSTART, 0x13 }, { OV7670_REG_HSTOP, 0x01 }, + { OV7670_REG_HREF, 0xb6 }, { OV7670_REG_VSTART, 0x02 }, + { OV7670_REG_VSTOP, 0x7a }, { OV7670_REG_VREF, 0x0a }, + + { OV7670_REG_COM3, 0 }, { OV7670_REG_COM14, 0 }, + /* Mystery scaling numbers */ + { 0x70, 0x3a }, { 0x71, 0x35 }, + { 0x72, 0x11 }, { 0x73, 0xf0 }, + { 0xa2, 0x02 }, +/* jfm */ +/* { OV7670_REG_COM10, 0x0 }, */ + + /* Gamma curve values */ + { 0x7a, 0x20 }, +/* jfm:win 7b=1c */ + { 0x7b, 0x10 }, +/* jfm:win 7c=28 */ + { 0x7c, 0x1e }, +/* jfm:win 7d=3c */ + { 0x7d, 0x35 }, + { 0x7e, 0x5a }, { 0x7f, 0x69 }, + { 0x80, 0x76 }, { 0x81, 0x80 }, + { 0x82, 0x88 }, { 0x83, 0x8f }, + { 0x84, 0x96 }, { 0x85, 0xa3 }, + { 0x86, 0xaf }, { 0x87, 0xc4 }, + { 0x88, 0xd7 }, { 0x89, 0xe8 }, + + /* AGC and AEC parameters. Note we start by disabling those features, + then turn them only after tweaking the values. */ + { OV7670_REG_COM8, OV7670_COM8_FASTAEC + | OV7670_COM8_AECSTEP + | OV7670_COM8_BFILT }, + { OV7670_REG_GAIN, 0 }, { OV7670_REG_AECH, 0 }, + { OV7670_REG_COM4, 0x40 }, /* magic reserved bit */ +/* jfm:win 14=38 */ + { OV7670_REG_COM9, 0x18 }, /* 4x gain + magic rsvd bit */ + { OV7670_REG_BD50MAX, 0x05 }, { OV7670_REG_BD60MAX, 0x07 }, + { OV7670_REG_AEW, 0x95 }, { OV7670_REG_AEB, 0x33 }, + { OV7670_REG_VPT, 0xe3 }, { OV7670_REG_HAECC1, 0x78 }, + { OV7670_REG_HAECC2, 0x68 }, +/* jfm:win a1=0b */ + { 0xa1, 0x03 }, /* magic */ + { OV7670_REG_HAECC3, 0xd8 }, { OV7670_REG_HAECC4, 0xd8 }, + { OV7670_REG_HAECC5, 0xf0 }, { OV7670_REG_HAECC6, 0x90 }, + { OV7670_REG_HAECC7, 0x94 }, + { OV7670_REG_COM8, OV7670_COM8_FASTAEC + | OV7670_COM8_AECSTEP + | OV7670_COM8_BFILT + | OV7670_COM8_AGC + | OV7670_COM8_AEC }, + + /* Almost all of these are magic "reserved" values. */ + { OV7670_REG_COM5, 0x61 }, { OV7670_REG_COM6, 0x4b }, + { 0x16, 0x02 }, +/* jfm */ +/* { OV7670_REG_MVFP, 0x07|OV7670_MVFP_MIRROR }, */ + { OV7670_REG_MVFP, 0x07 }, + { 0x21, 0x02 }, { 0x22, 0x91 }, + { 0x29, 0x07 }, { 0x33, 0x0b }, + { 0x35, 0x0b }, { 0x37, 0x1d }, + { 0x38, 0x71 }, { 0x39, 0x2a }, + { OV7670_REG_COM12, 0x78 }, { 0x4d, 0x40 }, + { 0x4e, 0x20 }, { OV7670_REG_GFIX, 0 }, + { 0x6b, 0x4a }, { 0x74, 0x10 }, + { 0x8d, 0x4f }, { 0x8e, 0 }, + { 0x8f, 0 }, { 0x90, 0 }, + { 0x91, 0 }, { 0x96, 0 }, + { 0x9a, 0 }, { 0xb0, 0x84 }, + { 0xb1, 0x0c }, { 0xb2, 0x0e }, + { 0xb3, 0x82 }, { 0xb8, 0x0a }, + + /* More reserved magic, some of which tweaks white balance */ + { 0x43, 0x0a }, { 0x44, 0xf0 }, + { 0x45, 0x34 }, { 0x46, 0x58 }, + { 0x47, 0x28 }, { 0x48, 0x3a }, + { 0x59, 0x88 }, { 0x5a, 0x88 }, + { 0x5b, 0x44 }, { 0x5c, 0x67 }, + { 0x5d, 0x49 }, { 0x5e, 0x0e }, + { 0x6c, 0x0a }, { 0x6d, 0x55 }, + { 0x6e, 0x11 }, { 0x6f, 0x9f }, + /* "9e for advance AWB" */ + { 0x6a, 0x40 }, { OV7670_REG_BLUE, 0x40 }, + { OV7670_REG_RED, 0x60 }, + { OV7670_REG_COM8, OV7670_COM8_FASTAEC + | OV7670_COM8_AECSTEP + | OV7670_COM8_BFILT + | OV7670_COM8_AGC + | OV7670_COM8_AEC + | OV7670_COM8_AWB }, + + /* Matrix coefficients */ + { 0x4f, 0x80 }, { 0x50, 0x80 }, + { 0x51, 0 }, { 0x52, 0x22 }, + { 0x53, 0x5e }, { 0x54, 0x80 }, + { 0x58, 0x9e }, + + { OV7670_REG_COM16, OV7670_COM16_AWBGAIN }, + { OV7670_REG_EDGE, 0 }, + { 0x75, 0x05 }, { 0x76, 0xe1 }, + { 0x4c, 0 }, { 0x77, 0x01 }, + { OV7670_REG_COM13, 0xc3 }, { 0x4b, 0x09 }, + { 0xc9, 0x60 }, { OV7670_REG_COM16, 0x38 }, + { 0x56, 0x40 }, + + { 0x34, 0x11 }, + { OV7670_REG_COM11, OV7670_COM11_EXP|OV7670_COM11_HZAUTO }, + { 0xa4, 0x88 }, { 0x96, 0 }, + { 0x97, 0x30 }, { 0x98, 0x20 }, + { 0x99, 0x30 }, { 0x9a, 0x84 }, + { 0x9b, 0x29 }, { 0x9c, 0x03 }, + { 0x9d, 0x4c }, { 0x9e, 0x3f }, + { 0x78, 0x04 }, + + /* Extra-weird stuff. Some sort of multiplexor register */ + { 0x79, 0x01 }, { 0xc8, 0xf0 }, + { 0x79, 0x0f }, { 0xc8, 0x00 }, + { 0x79, 0x10 }, { 0xc8, 0x7e }, + { 0x79, 0x0a }, { 0xc8, 0x80 }, + { 0x79, 0x0b }, { 0xc8, 0x01 }, + { 0x79, 0x0c }, { 0xc8, 0x0f }, + { 0x79, 0x0d }, { 0xc8, 0x20 }, + { 0x79, 0x09 }, { 0xc8, 0x80 }, + { 0x79, 0x02 }, { 0xc8, 0xc0 }, + { 0x79, 0x03 }, { 0xc8, 0x40 }, + { 0x79, 0x05 }, { 0xc8, 0x30 }, + { 0x79, 0x26 }, + + /* Format YUV422 */ + { OV7670_REG_COM7, OV7670_COM7_YUV }, /* Selects YUV mode */ + { OV7670_REG_RGB444, 0 }, /* No RGB444 please */ + { OV7670_REG_COM1, 0 }, + { OV7670_REG_COM15, OV7670_COM15_R00FF }, + { OV7670_REG_COM9, 0x18 }, + /* 4x gain ceiling; 0x8 is reserved bit */ + { 0x4f, 0x80 }, /* "matrix coefficient 1" */ + { 0x50, 0x80 }, /* "matrix coefficient 2" */ + { 0x52, 0x22 }, /* "matrix coefficient 4" */ + { 0x53, 0x5e }, /* "matrix coefficient 5" */ + { 0x54, 0x80 }, /* "matrix coefficient 6" */ + { OV7670_REG_COM13, OV7670_COM13_GAMMA|OV7670_COM13_UVSAT }, +}; + + PDEBUG(D_PROBE, "starting OV7xx0 configuration"); + +/* jfm:already done? */ + if (init_ov_sensor(sd) < 0) + PDEBUG(D_ERR, "Failed to read sensor ID"); + else + PDEBUG(D_PROBE, "OV7xx0 initialized"); + + /* Detect sensor (sub)type */ + rc = i2c_r(sd, OV7610_REG_COM_I); + + /* add OV7670 here + * it appears to be wrongly detected as a 7610 by default */ + if (rc < 0) { + PDEBUG(D_ERR, "Error detecting sensor type"); + return -1; + } + if ((rc & 3) == 3) { + /* quick hack to make OV7670s work */ + high = i2c_r(sd, 0x0a); + low = i2c_r(sd, 0x0b); + /* info("%x, %x", high, low); */ + if (high == 0x76 && low == 0x73) { + PDEBUG(D_PROBE, "Sensor is an OV7670"); + sd->sensor = SEN_OV7670; + } else { + PDEBUG(D_PROBE, "Sensor is an OV7610"); + sd->sensor = SEN_OV7610; + } + } else if ((rc & 3) == 1) { + /* I don't know what's different about the 76BE yet. */ + if (i2c_r(sd, 0x15) & 1) + PDEBUG(D_PROBE, "Sensor is an OV7620AE"); + else + PDEBUG(D_PROBE, "Sensor is an OV76BE"); + + /* OV511+ will return all zero isoc data unless we + * configure the sensor as a 7620. Someone needs to + * find the exact reg. setting that causes this. */ + sd->sensor = SEN_OV76BE; + } else if ((rc & 3) == 0) { + /* try to read product id registers */ + high = i2c_r(sd, 0x0a); + if (high < 0) { + PDEBUG(D_ERR, "Error detecting camera chip PID"); + return high; + } + low = i2c_r(sd, 0x0b); + if (low < 0) { + PDEBUG(D_ERR, "Error detecting camera chip VER"); + return low; + } + if (high == 0x76) { + if (low == 0x30) { + PDEBUG(D_PROBE, "Sensor is an OV7630/OV7635"); + sd->sensor = SEN_OV7630; + } else if (low == 0x40) { + PDEBUG(D_PROBE, "Sensor is an OV7645"); + sd->sensor = SEN_OV7640; /* FIXME */ + } else if (low == 0x45) { + PDEBUG(D_PROBE, "Sensor is an OV7645B"); + sd->sensor = SEN_OV7640; /* FIXME */ + } else if (low == 0x48) { + PDEBUG(D_PROBE, "Sensor is an OV7648"); + sd->sensor = SEN_OV7640; /* FIXME */ + } else { + PDEBUG(D_PROBE, "Unknown sensor: 0x76%X", low); + return -1; + } + } else { + PDEBUG(D_PROBE, "Sensor is an OV7620"); + sd->sensor = SEN_OV7620; + } + } else { + PDEBUG(D_ERR, "Unknown image sensor version: %d", rc & 3); + return -1; + } + + if (sd->sensor == SEN_OV7620) { + PDEBUG(D_PROBE, "Writing 7620 registers"); + if (write_i2c_regvals(sd, norm_7620, + sizeof norm_7620 / sizeof norm_7620[0])) + return -1; + } else if (sd->sensor == SEN_OV7630) { + PDEBUG(D_ERR, "7630 is not supported by this driver version"); + return -1; + } else if (sd->sensor == SEN_OV7640) { + PDEBUG(D_PROBE, "Writing 7640 registers"); + if (write_i2c_regvals(sd, norm_7640, + sizeof norm_7640 / sizeof norm_7640[0])) + return -1; + } else if (sd->sensor == SEN_OV7670) { + PDEBUG(D_PROBE, "Writing 7670 registers"); + if (write_i2c_regvals(sd, norm_7670, + sizeof norm_7670 / sizeof norm_7670[0])) + return -1; + } else { + PDEBUG(D_PROBE, "Writing 7610 registers"); + if (write_i2c_regvals(sd, norm_7610, + sizeof norm_7610 / sizeof norm_7610[0])) + return -1; + } + + /* Set sensor-specific vars */ + sd->maxwidth = 640; + sd->maxheight = 480; + return 0; +} + +/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ +static int ov6xx0_configure(struct sd *sd) +{ + int rc; + static struct ov_i2c_regvals norm_6x20[] = { + { 0x12, 0x80 }, /* reset */ + { 0x11, 0x01 }, + { 0x03, 0x60 }, + { 0x05, 0x7f }, /* For when autoadjust is off */ + { 0x07, 0xa8 }, + /* The ratio of 0x0c and 0x0d controls the white point */ + { 0x0c, 0x24 }, + { 0x0d, 0x24 }, + { 0x0f, 0x15 }, /* COMS */ + { 0x10, 0x75 }, /* AEC Exposure time */ + { 0x12, 0x24 }, /* Enable AGC */ + { 0x14, 0x04 }, + /* 0x16: 0x06 helps frame stability with moving objects */ + { 0x16, 0x06 }, +/* { 0x20, 0x30 }, * Aperture correction enable */ + { 0x26, 0xb2 }, /* BLC enable */ + /* 0x28: 0x05 Selects RGB format if RGB on */ + { 0x28, 0x05 }, + { 0x2a, 0x04 }, /* Disable framerate adjust */ +/* { 0x2b, 0xac }, * Framerate; Set 2a[7] first */ + { 0x2d, 0x99 }, + { 0x33, 0xa0 }, /* Color Processing Parameter */ + { 0x34, 0xd2 }, /* Max A/D range */ + { 0x38, 0x8b }, + { 0x39, 0x40 }, + + { 0x3c, 0x39 }, /* Enable AEC mode changing */ + { 0x3c, 0x3c }, /* Change AEC mode */ + { 0x3c, 0x24 }, /* Disable AEC mode changing */ + + { 0x3d, 0x80 }, + /* These next two registers (0x4a, 0x4b) are undocumented. + * They control the color balance */ + { 0x4a, 0x80 }, + { 0x4b, 0x80 }, + { 0x4d, 0xd2 }, /* This reduces noise a bit */ + { 0x4e, 0xc1 }, + { 0x4f, 0x04 }, +/* Do 50-53 have any effect? */ +/* Toggle 0x12[2] off and on here? */ + }; + + static struct ov_i2c_regvals norm_6x30[] = { + { 0x12, 0x80 }, /* Reset */ + { 0x00, 0x1f }, /* Gain */ + { 0x01, 0x99 }, /* Blue gain */ + { 0x02, 0x7c }, /* Red gain */ + { 0x03, 0xc0 }, /* Saturation */ + { 0x05, 0x0a }, /* Contrast */ + { 0x06, 0x95 }, /* Brightness */ + { 0x07, 0x2d }, /* Sharpness */ + { 0x0c, 0x20 }, + { 0x0d, 0x20 }, + { 0x0e, 0x20 }, + { 0x0f, 0x05 }, + { 0x10, 0x9a }, + { 0x11, 0x00 }, /* Pixel clock = fastest */ + { 0x12, 0x24 }, /* Enable AGC and AWB */ + { 0x13, 0x21 }, + { 0x14, 0x80 }, + { 0x15, 0x01 }, + { 0x16, 0x03 }, + { 0x17, 0x38 }, + { 0x18, 0xea }, + { 0x19, 0x04 }, + { 0x1a, 0x93 }, + { 0x1b, 0x00 }, + { 0x1e, 0xc4 }, + { 0x1f, 0x04 }, + { 0x20, 0x20 }, + { 0x21, 0x10 }, + { 0x22, 0x88 }, + { 0x23, 0xc0 }, /* Crystal circuit power level */ + { 0x25, 0x9a }, /* Increase AEC black ratio */ + { 0x26, 0xb2 }, /* BLC enable */ + { 0x27, 0xa2 }, + { 0x28, 0x00 }, + { 0x29, 0x00 }, + { 0x2a, 0x84 }, /* 60 Hz power */ + { 0x2b, 0xa8 }, /* 60 Hz power */ + { 0x2c, 0xa0 }, + { 0x2d, 0x95 }, /* Enable auto-brightness */ + { 0x2e, 0x88 }, + { 0x33, 0x26 }, + { 0x34, 0x03 }, + { 0x36, 0x8f }, + { 0x37, 0x80 }, + { 0x38, 0x83 }, + { 0x39, 0x80 }, + { 0x3a, 0x0f }, + { 0x3b, 0x3c }, + { 0x3c, 0x1a }, + { 0x3d, 0x80 }, + { 0x3e, 0x80 }, + { 0x3f, 0x0e }, + { 0x40, 0x00 }, /* White bal */ + { 0x41, 0x00 }, /* White bal */ + { 0x42, 0x80 }, + { 0x43, 0x3f }, /* White bal */ + { 0x44, 0x80 }, + { 0x45, 0x20 }, + { 0x46, 0x20 }, + { 0x47, 0x80 }, + { 0x48, 0x7f }, + { 0x49, 0x00 }, + { 0x4a, 0x00 }, + { 0x4b, 0x80 }, + { 0x4c, 0xd0 }, + { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ + { 0x4e, 0x40 }, + { 0x4f, 0x07 }, /* UV avg., col. killer: max */ + { 0x50, 0xff }, + { 0x54, 0x23 }, /* Max AGC gain: 18dB */ + { 0x55, 0xff }, + { 0x56, 0x12 }, + { 0x57, 0x81 }, + { 0x58, 0x75 }, + { 0x59, 0x01 }, /* AGC dark current comp.: +1 */ + { 0x5a, 0x2c }, + { 0x5b, 0x0f }, /* AWB chrominance levels */ + { 0x5c, 0x10 }, + { 0x3d, 0x80 }, + { 0x27, 0xa6 }, + { 0x12, 0x20 }, /* Toggle AWB */ + { 0x12, 0x24 }, + }; + + PDEBUG(D_PROBE, "starting sensor configuration"); + + if (init_ov_sensor(sd) < 0) { + PDEBUG(D_ERR, "Failed to read sensor ID."); + return -1; + } + PDEBUG(D_PROBE, "OV6xx0 sensor detected"); + + /* Detect sensor (sub)type */ + rc = i2c_r(sd, OV7610_REG_COM_I); + if (rc < 0) { + PDEBUG(D_ERR, "Error detecting sensor type"); + return -1; + } + + /* Ugh. The first two bits are the version bits, but + * the entire register value must be used. I guess OVT + * underestimated how many variants they would make. */ + if (rc == 0x00) { + sd->sensor = SEN_OV6630; + PDEBUG(D_ERR, + "WARNING: Sensor is an OV66308. Your camera may have"); + PDEBUG(D_ERR, "been misdetected in previous driver versions."); + } else if (rc == 0x01) { + sd->sensor = SEN_OV6620; + PDEBUG(D_PROBE, "Sensor is an OV6620"); + } else if (rc == 0x02) { + sd->sensor = SEN_OV6630; + PDEBUG(D_PROBE, "Sensor is an OV66308AE"); + } else if (rc == 0x03) { + sd->sensor = SEN_OV6630; + PDEBUG(D_PROBE, "Sensor is an OV66308AF"); + } else if (rc == 0x90) { + sd->sensor = SEN_OV6630; + PDEBUG(D_ERR, + "WARNING: Sensor is an OV66307. Your camera may have"); + PDEBUG(D_ERR, "been misdetected in previous driver versions."); + } else { + PDEBUG(D_ERR, "FATAL: Unknown sensor version: 0x%02x", rc); + return -1; + } + + /* Set sensor-specific vars */ + sd->maxwidth = 352; + sd->maxheight = 288; + + if (sd->sensor == SEN_OV6620) { + PDEBUG(D_PROBE, "Writing 6x20 registers"); + if (write_i2c_regvals(sd, norm_6x20, + sizeof norm_6x20 / sizeof norm_6x20[0])) + return -1; + } else { + PDEBUG(D_PROBE, "Writing 6x30 registers"); + if (write_i2c_regvals(sd, norm_6x30, + sizeof norm_6x30 / sizeof norm_6x30[0])) + return -1; + } + return 0; +} + +/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ +static void ov51x_led_control(struct sd *sd, int on) +{ + PDEBUG(D_STREAM, "LED (%s)", on ? "on" : "off"); + +/* if (sd->bridge == BRG_OV511PLUS) */ +/* reg_w(sd, R511_SYS_LED_CTL, on ? 1 : 0); */ +/* else if (sd->bridge == BRG_OV519) */ + reg_w_mask(sd, OV519_GPIO_DATA_OUT0, !on, 1); /* 0 / 1 */ +/* else if (sd->bclass == BCL_OV518) */ +/* reg_w_mask(sd, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); */ +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + +/* (from ov519_configure) */ + static struct ov_regvals init_519[] = { + { 0x5a, 0x6d }, /* EnableSystem */ +/* jfm trace usbsnoop3-1.txt */ +/* jfm 53 = fb */ + { 0x53, 0x9b }, + { 0x54, 0xff }, /* set bit2 to enable jpeg */ + { 0x5d, 0x03 }, + { 0x49, 0x01 }, + { 0x48, 0x00 }, + /* Set LED pin to output mode. Bit 4 must be cleared or sensor + * detection will fail. This deserves further investigation. */ + { OV519_GPIO_IO_CTRL0, 0xee }, + { 0x51, 0x0f }, /* SetUsbInit */ + { 0x51, 0x00 }, + { 0x22, 0x00 }, + /* windows reads 0x55 at this point*/ + }; + + if (write_regvals(sd, init_519, + sizeof init_519 / sizeof init_519[0])) + goto error; +/* jfm: not seen in windows trace */ + if (ov519_init_compression(sd)) + goto error; + ov51x_led_control(sd, 0); /* turn LED off */ + + /* Test for 76xx */ + sd->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(sd, OV7xx0_SID) < 0) + goto error; + + /* The OV519 must be more aggressive about sensor detection since + * I2C write will never fail if the sensor is not present. We have + * to try to initialize the sensor to detect its presence */ + if (init_ov_sensor(sd) < 0) { + /* Test for 6xx0 */ + sd->primary_i2c_slave = OV6xx0_SID; + if (ov51x_set_slave_ids(sd, OV6xx0_SID) < 0) + goto error; + + if (init_ov_sensor(sd) < 0) { + /* Test for 8xx0 */ + sd->primary_i2c_slave = OV8xx0_SID; + if (ov51x_set_slave_ids(sd, OV8xx0_SID) < 0) + goto error; + + if (init_ov_sensor(sd) < 0) { + PDEBUG(D_ERR, + "Can't determine sensor slave IDs"); + goto error; + } else { + if (ov8xx0_configure(sd) < 0) { + PDEBUG(D_ERR, + "Failed to configure OV8xx0 sensor"); + goto error; + } + } + } else { + if (ov6xx0_configure(sd) < 0) { + PDEBUG(D_ERR, "Failed to configure OV6xx0"); + goto error; + } + } + } else { + if (ov7xx0_configure(sd) < 0) { + PDEBUG(D_ERR, "Failed to configure OV7xx0"); + goto error; + } + } + + cam = &gspca_dev->cam; + cam->epaddr = OV511_ENDPOINT_ADDRESS; + if (sd->maxwidth == 640) { + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + } else { + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + } + cam->dev_name = (char *) id->driver_info; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + return 0; +error: + PDEBUG(D_ERR, "OV519 Config failed"); + return -EBUSY; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + return 0; +} + +/* Sets up the OV519 with the given image parameters + * + * OV519 needs a completely different approach, until we can figure out what + * the individual registers do. + * + * Do not put any sensor-specific code in here (including I2C I/O functions) + */ +static int ov519_mode_init_regs(struct sd *sd, + int width, int height) +{ + static struct ov_regvals mode_init_519_ov7670[] = { + { 0x5d, 0x03 }, /* Turn off suspend mode */ + { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ + { 0x54, 0x0f }, /* bit2 (jpeg enable) */ + { 0xa2, 0x20 }, /* a2-a5 are undocumented */ + { 0xa3, 0x18 }, + { 0xa4, 0x04 }, + { 0xa5, 0x28 }, + { 0x37, 0x00 }, /* SetUsbInit */ + { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ + /* Enable both fields, YUV Input, disable defect comp (why?) */ + { 0x20, 0x0c }, + { 0x21, 0x38 }, + { 0x22, 0x1d }, + { 0x17, 0x50 }, /* undocumented */ + { 0x37, 0x00 }, /* undocumented */ + { 0x40, 0xff }, /* I2C timeout counter */ + { 0x46, 0x00 }, /* I2C clock prescaler */ + { 0x59, 0x04 }, /* new from windrv 090403 */ + { 0xff, 0x00 }, /* undocumented */ + /* windows reads 0x55 at this point, why? */ + }; + + static struct ov_regvals mode_init_519[] = { + { 0x5d, 0x03 }, /* Turn off suspend mode */ + { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ + { 0x54, 0x0f }, /* bit2 (jpeg enable) */ + { 0xa2, 0x20 }, /* a2-a5 are undocumented */ + { 0xa3, 0x18 }, + { 0xa4, 0x04 }, + { 0xa5, 0x28 }, + { 0x37, 0x00 }, /* SetUsbInit */ + { 0x55, 0x02 }, /* 4.096 Mhz audio clock */ + /* Enable both fields, YUV Input, disable defect comp (why?) */ + { 0x22, 0x1d }, + { 0x17, 0x50 }, /* undocumented */ + { 0x37, 0x00 }, /* undocumented */ + { 0x40, 0xff }, /* I2C timeout counter */ + { 0x46, 0x00 }, /* I2C clock prescaler */ + { 0x59, 0x04 }, /* new from windrv 090403 */ + { 0xff, 0x00 }, /* undocumented */ + /* windows reads 0x55 at this point, why? */ + }; + +/* int hi_res; */ + + PDEBUG(D_CONF, "mode init %dx%d", width, height); + +/* if (width >= 800 && height >= 600) + hi_res = 1; + else + hi_res = 0; */ + +/* if (ov51x_stop(sd) < 0) + return -EIO; */ + + /******** Set the mode ********/ + if (sd->sensor != SEN_OV7670) { + if (write_regvals(sd, mode_init_519, + sizeof mode_init_519 / sizeof mode_init_519[0])) + return -EIO; + } else { + if (write_regvals(sd, mode_init_519_ov7670, + sizeof mode_init_519_ov7670 + / sizeof mode_init_519_ov7670[0])) + return -EIO; + } + + if (sd->sensor == SEN_OV7640) { + /* Select 8-bit input mode */ + reg_w_mask(sd, OV519_CAM_DFR, 0x10, 0x10); + } + + reg_w(sd, OV519_CAM_H_SIZE, width >> 4); + reg_w(sd, OV519_CAM_V_SIZE, height >> 3); + reg_w(sd, OV519_CAM_X_OFFSETL, 0x00); + reg_w(sd, OV519_CAM_X_OFFSETH, 0x00); + reg_w(sd, OV519_CAM_Y_OFFSETL, 0x00); + reg_w(sd, OV519_CAM_Y_OFFSETH, 0x00); + reg_w(sd, OV519_CAM_DIVIDER, 0x00); + reg_w(sd, OV519_CAM_FORMAT, 0x03); /* YUV422 */ + reg_w(sd, 0x26, 0x00); /* Undocumented */ + + /******** Set the framerate ********/ + if (frame_rate > 0) + sd->frame_rate = frame_rate; + +/* FIXME: These are only valid at the max resolution. */ + sd->clockdiv = 0; + if (sd->sensor == SEN_OV7640) { + switch (sd->frame_rate) { +/*jfm: default was 30 fps */ + case 30: + reg_w(sd, 0xa4, 0x0c); + reg_w(sd, 0x23, 0xff); + break; + case 25: + reg_w(sd, 0xa4, 0x0c); + reg_w(sd, 0x23, 0x1f); + break; + case 20: + reg_w(sd, 0xa4, 0x0c); + reg_w(sd, 0x23, 0x1b); + break; + default: +/* case 15: */ + reg_w(sd, 0xa4, 0x04); + reg_w(sd, 0x23, 0xff); + sd->clockdiv = 1; + break; + case 10: + reg_w(sd, 0xa4, 0x04); + reg_w(sd, 0x23, 0x1f); + sd->clockdiv = 1; + break; + case 5: + reg_w(sd, 0xa4, 0x04); + reg_w(sd, 0x23, 0x1b); + sd->clockdiv = 1; + break; + } + } else if (sd->sensor == SEN_OV8610) { + switch (sd->frame_rate) { + default: /* 15 fps */ +/* case 15: */ + reg_w(sd, 0xa4, 0x06); + reg_w(sd, 0x23, 0xff); + break; + case 10: + reg_w(sd, 0xa4, 0x06); + reg_w(sd, 0x23, 0x1f); + break; + case 5: + reg_w(sd, 0xa4, 0x06); + reg_w(sd, 0x23, 0x1b); + break; + } + sd->clockdiv = 0; + } else if (sd->sensor == SEN_OV7670) { /* guesses, based on 7640 */ + PDEBUG(D_STREAM, "Setting framerate to %d fps", + (sd->frame_rate == 0) ? 15 : sd->frame_rate); + switch (sd->frame_rate) { + case 30: + reg_w(sd, 0xa4, 0x10); + reg_w(sd, 0x23, 0xff); + break; + case 20: + reg_w(sd, 0xa4, 0x10); + reg_w(sd, 0x23, 0x1b); + break; + default: /* 15 fps */ +/* case 15: */ + reg_w(sd, 0xa4, 0x10); + reg_w(sd, 0x23, 0xff); + sd->clockdiv = 1; + break; + } + } + +/* if (ov51x_restart(sd) < 0) + return -EIO; */ + + /* Reset it just for good measure */ +/* if (ov51x_reset(sd, OV511_RESET_NOREGS) < 0) + return -EIO; */ + return 0; +} + +static int mode_init_ov_sensor_regs(struct sd *sd, + struct ovsensor_window *win) +{ + int qvga = win->quarter; + + /******** Mode (VGA/QVGA) and sensor specific regs ********/ + switch (sd->sensor) { + case SEN_OV8610: + /* For OV8610 qvga means qsvga */ + i2c_w_mask(sd, OV7610_REG_COM_C, qvga ? (1 << 5) : 0, 1 << 5); + break; + case SEN_OV7610: + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + break; + case SEN_OV7620: +/* i2c_w(sd, 0x2b, 0x00); */ + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); + i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); + i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); + i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); + i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); + i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); + break; + case SEN_OV76BE: +/* i2c_w(sd, 0x2b, 0x00); */ + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + break; + case SEN_OV7640: +/* i2c_w(sd, 0x2b, 0x00); */ + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + i2c_w_mask(sd, 0x28, qvga ? 0x00 : 0x20, 0x20); +/* i2c_w(sd, 0x24, qvga ? 0x20 : 0x3a); */ +/* i2c_w(sd, 0x25, qvga ? 0x30 : 0x60); */ +/* i2c_w_mask(sd, 0x2d, qvga ? 0x40 : 0x00, 0x40); */ +/* i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); */ +/* i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); */ + break; + case SEN_OV7670: + /* set COM7_FMT_VGA or COM7_FMT_QVGA + * do we need to set anything else? + * HSTART etc are set in set_ov_sensor_window itself */ + i2c_w_mask(sd, OV7670_REG_COM7, + qvga ? OV7670_COM7_FMT_QVGA : OV7670_COM7_FMT_VGA, + OV7670_COM7_FMT_MASK); + break; + case SEN_OV6620: + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + break; + case SEN_OV6630: + i2c_w_mask(sd, 0x14, qvga ? 0x20 : 0x00, 0x20); + break; + default: + return -EINVAL; + } + + /******** Palette-specific regs ********/ +/* Need to do work here for the OV7670 */ + + if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { + /* not valid on the OV6620/OV7620/6630? */ + i2c_w_mask(sd, 0x0e, 0x00, 0x40); + } + + /* The OV518 needs special treatment. Although both the OV518 + * and the OV6630 support a 16-bit video bus, only the 8 bit Y + * bus is actually used. The UV bus is tied to ground. + * Therefore, the OV6630 needs to be in 8-bit multiplexed + * output mode */ + + /* OV7640 is 8-bit only */ + + if (sd->sensor != SEN_OV6630 && sd->sensor != SEN_OV7640) + i2c_w_mask(sd, 0x13, 0x00, 0x20); +/* } */ + + /******** Clock programming ********/ + /* The OV6620 needs special handling. This prevents the + * severe banding that normally occurs */ + if (sd->sensor == SEN_OV6620) { + + /* Clock down */ + i2c_w(sd, 0x2a, 0x04); + i2c_w(sd, 0x11, win->clockdiv); + i2c_w(sd, 0x2a, 0x84); + /* This next setting is critical. It seems to improve + * the gain or the contrast. The "reserved" bits seem + * to have some effect in this case. */ + i2c_w(sd, 0x2d, 0x85); + } else if (win->clockdiv >= 0) { + i2c_w(sd, 0x11, win->clockdiv); + } + + /******** Special Features ********/ +/* no evidence this is possible with OV7670, either */ + /* Test Pattern */ + if (sd->sensor != SEN_OV7640 && sd->sensor != SEN_OV7670) + i2c_w_mask(sd, 0x12, 0x00, 0x02); + + /* Enable auto white balance */ + if (sd->sensor == SEN_OV7670) + i2c_w_mask(sd, OV7670_REG_COM8, OV7670_COM8_AWB, + OV7670_COM8_AWB); + else + i2c_w_mask(sd, 0x12, 0x04, 0x04); + + /* This will go away as soon as ov51x_mode_init_sensor_regs() */ + /* is fully tested. */ + /* 7620/6620/6630? don't have register 0x35, so play it safe */ + if (sd->sensor == SEN_OV7610 || sd->sensor == SEN_OV76BE) { + if (win->width == 640 /*&& win->height == 480*/) + i2c_w(sd, 0x35, 0x9e); + else + i2c_w(sd, 0x35, 0x1e); + } + return 0; +} + +static int set_ov_sensor_window(struct sd *sd, + struct ovsensor_window *win) +{ + int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale; + int ret, hstart, hstop, vstop, vstart; + __u8 v; + + /* The different sensor ICs handle setting up of window differently. + * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!! */ + switch (sd->sensor) { + case SEN_OV8610: + hwsbase = 0x1e; + hwebase = 0x1e; + vwsbase = 0x02; + vwebase = 0x02; + break; + case SEN_OV7610: + case SEN_OV76BE: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = vwebase = 0x05; + break; + case SEN_OV6620: + case SEN_OV6630: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = 0x05; + vwebase = 0x06; + break; + case SEN_OV7620: + hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ + hwebase = 0x2f; + vwsbase = vwebase = 0x05; + break; + case SEN_OV7640: + hwsbase = 0x1a; + hwebase = 0x1a; + vwsbase = vwebase = 0x03; + break; + case SEN_OV7670: + /*handling of OV7670 hardware sensor start and stop values + * is very odd, compared to the other OV sensors */ + vwsbase = vwebase = hwebase = hwsbase = 0x00; + break; + default: + return -EINVAL; + } + + switch (sd->sensor) { + case SEN_OV6620: + case SEN_OV6630: + if (win->quarter) { /* QCIF */ + hwscale = 0; + vwscale = 0; + } else { /* CIF */ + hwscale = 1; + vwscale = 1; /* The datasheet says 0; + * it's wrong */ + } + break; + case SEN_OV8610: + if (win->quarter) { /* QSVGA */ + hwscale = 1; + vwscale = 1; + } else { /* SVGA */ + hwscale = 2; + vwscale = 2; + } + break; + default: /* SEN_OV7xx0 */ + if (win->quarter) { /* QVGA */ + hwscale = 1; + vwscale = 0; + } else { /* VGA */ + hwscale = 2; + vwscale = 1; + } + } + + ret = mode_init_ov_sensor_regs(sd, win); + if (ret < 0) + return ret; + + if (sd->sensor == SEN_OV8610) { + i2c_w_mask(sd, 0x2d, 0x05, 0x40); + /* old 0x95, new 0x05 from windrv 090403 */ + /* bits 5-7: reserved */ + i2c_w_mask(sd, 0x28, 0x20, 0x20); + /* bit 5: progressive mode on */ + } + + /* The below is wrong for OV7670s because their window registers + * only store the high bits in 0x17 to 0x1a */ + + /* SRH Use sd->max values instead of requested win values */ + /* SCS Since we're sticking with only the max hardware widths + * for a given mode */ + /* I can hard code this for OV7670s */ + /* Yes, these numbers do look odd, but they're tested and work! */ + if (sd->sensor == SEN_OV7670) { + if (win->quarter) { /* QVGA from ov7670.c by + * Jonathan Corbet */ + hstart = 164; + hstop = 20; + vstart = 14; + vstop = 494; + } else { /* VGA */ + hstart = 158; + hstop = 14; + vstart = 10; + vstop = 490; + } + /* OV7670 hardware window registers are split across + * multiple locations */ + i2c_w(sd, OV7670_REG_HSTART, (hstart >> 3) & 0xff); + i2c_w(sd, OV7670_REG_HSTOP, (hstop >> 3) & 0xff); + v = i2c_r(sd, OV7670_REG_HREF); + v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x07); + msleep(10); /* need to sleep between read and write to + * same reg! */ + i2c_w(sd, OV7670_REG_HREF, v); + + i2c_w(sd, OV7670_REG_VSTART, (vstart >> 2) & 0xff); + i2c_w(sd, OV7670_REG_VSTOP, (vstop >> 2) & 0xff); + v = i2c_r(sd, OV7670_REG_VREF); + v = (v & 0xc0) | ((vstop & 0x3) << 2) | (vstart & 0x03); + msleep(10); /* need to sleep between read and write to + * same reg! */ + i2c_w(sd, OV7670_REG_VREF, v); + + } else { + i2c_w(sd, 0x17, hwsbase + (win->x >> hwscale)); + i2c_w(sd, 0x18, hwebase + ((win->x + win->width) >> hwscale)); + i2c_w(sd, 0x19, vwsbase + (win->y >> vwscale)); + i2c_w(sd, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); + } + return 0; +} + +static int ov_sensor_mode_setup(struct sd *sd, + int width, int height) +{ + struct ovsensor_window win; + +/* win.format = mode; */ + + /* Unless subcapture is enabled, + * center the image window and downsample + * if possible to increase the field of view */ + /* NOTE: OV518(+) and OV519 does downsampling on its own */ + win.width = width; + win.height = height; + if (width == sd->maxwidth) + win.quarter = 0; + else + win.quarter = 1; + + /* Center it */ + win.x = (win.width - width) / 2; + win.y = (win.height - height) / 2; + + /* Clock is determined by OV519 frame rate code */ + win.clockdiv = sd->clockdiv; + + PDEBUG(D_CONF, "Setting clock divider to %d", win.clockdiv); + return set_ov_sensor_window(sd, &win); +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + + ret = ov519_mode_init_regs(sd, gspca_dev->width, gspca_dev->height); + if (ret < 0) + goto out; + ret = ov_sensor_mode_setup(sd, gspca_dev->width, gspca_dev->height); + if (ret < 0) + goto out; + + ret = ov51x_restart((struct sd *) gspca_dev); + if (ret < 0) + goto out; + PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt); + ov51x_led_control(sd, 1); + return; +out: + PDEBUG(D_ERR, "camera start error:%d", ret); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + ov51x_stop((struct sd *) gspca_dev); + ov51x_led_control((struct sd *) gspca_dev, 0); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + /* Header of ov519 is 16 bytes: + * Byte Value Description + * 0 0xff magic + * 1 0xff magic + * 2 0xff magic + * 3 0xXX 0x50 = SOF, 0x51 = EOF + * 9 0xXX 0x01 initial frame without data, + * 0x00 standard frame with image + * 14 Lo in EOF: length of image data / 8 + * 15 Hi + */ + + if (data[0] == 0xff && data[1] == 0xff && data[2] == 0xff) { + switch (data[3]) { + case 0x50: /* start of frame */ +#define HDRSZ 16 + data += HDRSZ; + len -= HDRSZ; +#undef HDRSZ + if (data[0] == 0xff || data[1] == 0xd8) + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + else + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + case 0x51: /* end of frame */ + if (data[9] != 0) + gspca_dev->last_packet_type = DISCARD_PACKET; + gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + return; + } + } + + /* intermediate packet */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data, len); +} + +/* -- management routines -- */ + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int val; +/* int was_streaming; */ + + val = sd->brightness; + PDEBUG(D_CONF, "brightness:%d", val); +/* was_streaming = gspca_dev->streaming; + * if (was_streaming) + * ov51x_stop(sd); */ + switch (sd->sensor) { + case SEN_OV8610: + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7640: + i2c_w(sd, OV7610_REG_BRT, val); + break; + case SEN_OV7620: + /* 7620 doesn't like manual changes when in auto mode */ +/*fixme + * if (!sd->auto_brt) */ + i2c_w(sd, OV7610_REG_BRT, val); + break; + case SEN_OV7670: +/*jfm - from windblows + * i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_AEC); */ + i2c_w(sd, OV7670_REG_BRIGHT, ov7670_abs_to_sm(val)); + break; + } +/* if (was_streaming) + * ov51x_restart(sd); */ +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int val; +/* int was_streaming; */ + + val = sd->contrast; + PDEBUG(D_CONF, "contrast:%d", val); +/* was_streaming = gspca_dev->streaming; + if (was_streaming) + ov51x_stop(sd); */ + switch (sd->sensor) { + case SEN_OV7610: + case SEN_OV6620: + i2c_w(sd, OV7610_REG_CNT, val); + break; + case SEN_OV6630: + i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); + case SEN_OV8610: { + static __u8 ctab[] = { + 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f + }; + + /* Use Y gamma control instead. Bit 0 enables it. */ + i2c_w(sd, 0x64, ctab[val >> 5]); + break; + } + case SEN_OV7620: { + static __u8 ctab[] = { + 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, + 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff + }; + + /* Use Y gamma control instead. Bit 0 enables it. */ + i2c_w(sd, 0x64, ctab[val >> 4]); + break; + } + case SEN_OV7640: + /* Use gain control instead. */ + i2c_w(sd, OV7610_REG_GAIN, val >> 2); + break; + case SEN_OV7670: + /* check that this isn't just the same as ov7610 */ + i2c_w(sd, OV7670_REG_CONTRAS, val >> 1); + break; + } +/* if (was_streaming) + ov51x_restart(sd); */ +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int val; +/* int was_streaming; */ + + val = sd->colors; + PDEBUG(D_CONF, "saturation:%d", val); +/* was_streaming = gspca_dev->streaming; + if (was_streaming) + ov51x_stop(sd); */ + switch (sd->sensor) { + case SEN_OV8610: + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + i2c_w(sd, OV7610_REG_SAT, val); + break; + case SEN_OV7620: + /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ +/* rc = ov_i2c_write(sd->dev, 0x62, (val >> 9) & 0x7e); + if (rc < 0) + goto out; */ + i2c_w(sd, OV7610_REG_SAT, val); + break; + case SEN_OV7640: + i2c_w(sd, OV7610_REG_SAT, val & 0xf0); + break; + case SEN_OV7670: + /* supported later once I work out how to do it + * transparently fail now! */ + /* set REG_COM13 values for UV sat auto mode */ + break; + } +/* if (was_streaming) + ov51x_restart(sd); */ +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, + {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, + {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, + {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")}, + {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")}, + {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")}, + {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")}, + {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")}, + {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")}, + {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")}, + {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")}, + {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")}, + {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")}, + {} +}; +#undef DVNAME +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); + +module_param(frame_rate, int, 0644); +MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 482ef4a6afc0..72a5b89cd59d 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 15) -static const char version[] = "0.2.15"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -297,7 +297,6 @@ static int sd_open(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; sd->autogain = 1; - return 0; } @@ -338,7 +337,7 @@ static void sd_start(struct gspca_dev *gspca_dev) pac207_write_reg(gspca_dev, 0x13, 0x01); /* Bit 0, auto clear */ pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ - udelay(1000); /* taken from gspca */ + msleep(10); pac207_write_reg(gspca_dev, 0x40, 0x01); /* Start ISO pipe */ sd->sof_read = 0; @@ -743,8 +742,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, PDEBUG(D_STREAM, "Incomplete frame"); } pac207_decode_frame_init(gspca_dev); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, - 0); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); len -= sof - data; data = sof; } diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c new file mode 100644 index 000000000000..8f51976db995 --- /dev/null +++ b/drivers/media/video/gspca/pac7311.c @@ -0,0 +1,754 @@ +/* + * Pixart PAC7311 library + * Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "pac7311" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); +MODULE_DESCRIPTION("Pixart PAC7311"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int avg_lum; + + unsigned char brightness; +#define BRIGHTNESS_MAX 0x20 + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + + char ffseq; + signed char ag_cnt; +#define AG_CNT_START 13 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = BRIGHTNESS_MAX, + .step = 1, + .default_value = 0x10, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_AUTOGAIN 3 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 160, 120, 2}, + {V4L2_PIX_FMT_JPEG, 320, 240, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +#define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ + +const unsigned char pac7311_jpeg_header[] = { + 0xff, 0xd8, + 0xff, 0xe0, 0x00, 0x03, 0x20, + 0xff, 0xc0, 0x00, 0x11, 0x08, + 0x01, 0xe0, /* 12: height */ + 0x02, 0x80, /* 14: width */ + 0x03, /* 16 */ + 0x01, 0x21, 0x00, + 0x02, 0x11, 0x01, + 0x03, 0x11, 0x01, + 0xff, 0xdb, 0x00, 0x84, + 0x00, 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d, + 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a, 0x18, 0x16, + 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d, 0x28, 0x3a, 0x33, 0x3d, + 0x3c, 0x39, 0x33, 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, + 0x44, 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57, 0x5f, + 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71, 0x79, 0x70, 0x64, + 0x78, 0x5c, 0x65, 0x67, 0x63, 0x01, 0x11, 0x12, 0x12, 0x18, + 0x15, 0x18, 0x2f, 0x1a, 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, + 0xff, 0xc4, 0x01, 0xa2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, + 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, + 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, + 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, + 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, + 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, + 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, + 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, + 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, + 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, + 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, + 0x11, 0x00, 0x3f, 0x00 +}; + +static void reg_w(struct usb_device *dev, + __u16 req, + __u16 value, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, buffer, length, + 500); +} + +static void pac7311_reg_read(struct usb_device *dev, __u16 index, + __u8 *buffer) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, 1, + 500); +} + +static void pac7311_reg_write(struct usb_device *dev, + __u16 index, + __u8 value) +{ + __u8 buf; + + buf = value; + reg_w(dev, 0x00, value, index, &buf, 1); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct cam *cam; + + PDEBUG(D_CONF, "Find Sensor PAC7311"); + pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x27, 0x80); + pac7311_reg_write(dev, 0x28, 0xca); + pac7311_reg_write(dev, 0x29, 0x53); + pac7311_reg_write(dev, 0x2a, 0x0e); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x3e, 0x20); + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x05; + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + return 0; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int brightness; + +/*jfm: inverted?*/ + brightness = BRIGHTNESS_MAX - sd->brightness; + pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); + /* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ + pac7311_reg_write(gspca_dev->dev, 0x0f, brightness); + /* load registers to sensor (Bit 0, auto clear) */ + pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); + pac7311_reg_write(gspca_dev->dev, 0x80, sd->contrast); + /* load registers to sensor (Bit 0, auto clear) */ + pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); + pac7311_reg_write(gspca_dev->dev, 0x10, sd->colors); + /* load registers to sensor (Bit 0, auto clear) */ + pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + pac7311_reg_write(gspca_dev->dev, 0x78, 0x00); /* Turn on LED */ + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + struct sd *sd = (struct sd *) gspca_dev; + + pac7311_reg_write(dev, 0xff, 0x01); + reg_w(dev, 0x01, 0, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); + reg_w(dev, 0x01, 0, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); + reg_w(dev, 0x01, 0, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); + reg_w(dev, 0x01, 0, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); + reg_w(dev, 0x01, 0, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); + reg_w(dev, 0x01, 0, 0x002a, "\x00\x00\x00", 3); + reg_w(dev, 0x01, 0, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); + reg_w(dev, 0x01, 0, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); + reg_w(dev, 0x01, 0, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); + reg_w(dev, 0x01, 0, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); + reg_w(dev, 0x01, 0, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); + reg_w(dev, 0x01, 0, 0x0066, "\xd0\xff", 2); + reg_w(dev, 0x01, 0, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); + reg_w(dev, 0x01, 0, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); + reg_w(dev, 0x01, 0, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); + reg_w(dev, 0x01, 0, 0x008f, "\x18\x20", 2); + reg_w(dev, 0x01, 0, 0x0096, "\x01\x08\x04", 3); + reg_w(dev, 0x01, 0, 0x00a0, "\x44\x44\x44\x04", 4); + reg_w(dev, 0x01, 0, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); + reg_w(dev, 0x01, 0, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); + + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x02, 0x04); + pac7311_reg_write(dev, 0x03, 0x54); + pac7311_reg_write(dev, 0x04, 0x07); + pac7311_reg_write(dev, 0x05, 0x2b); + pac7311_reg_write(dev, 0x06, 0x09); + pac7311_reg_write(dev, 0x07, 0x0f); + pac7311_reg_write(dev, 0x08, 0x09); + pac7311_reg_write(dev, 0x09, 0x00); + pac7311_reg_write(dev, 0x0c, 0x07); + pac7311_reg_write(dev, 0x0d, 0x00); + pac7311_reg_write(dev, 0x0e, 0x00); + pac7311_reg_write(dev, 0x0f, 0x62); + pac7311_reg_write(dev, 0x10, 0x08); + pac7311_reg_write(dev, 0x12, 0x07); + pac7311_reg_write(dev, 0x13, 0x00); + pac7311_reg_write(dev, 0x14, 0x00); + pac7311_reg_write(dev, 0x15, 0x00); + pac7311_reg_write(dev, 0x16, 0x00); + pac7311_reg_write(dev, 0x17, 0x00); + pac7311_reg_write(dev, 0x18, 0x00); + pac7311_reg_write(dev, 0x19, 0x00); + pac7311_reg_write(dev, 0x1a, 0x00); + pac7311_reg_write(dev, 0x1b, 0x03); + pac7311_reg_write(dev, 0x1c, 0xa0); + pac7311_reg_write(dev, 0x1d, 0x01); + pac7311_reg_write(dev, 0x1e, 0xf4); + pac7311_reg_write(dev, 0x21, 0x00); + pac7311_reg_write(dev, 0x22, 0x08); + pac7311_reg_write(dev, 0x24, 0x03); + pac7311_reg_write(dev, 0x26, 0x00); + pac7311_reg_write(dev, 0x27, 0x01); + pac7311_reg_write(dev, 0x28, 0xca); + pac7311_reg_write(dev, 0x29, 0x10); + pac7311_reg_write(dev, 0x2a, 0x06); + pac7311_reg_write(dev, 0x2b, 0x78); + pac7311_reg_write(dev, 0x2c, 0x00); + pac7311_reg_write(dev, 0x2d, 0x00); + pac7311_reg_write(dev, 0x2e, 0x00); + pac7311_reg_write(dev, 0x2f, 0x00); + pac7311_reg_write(dev, 0x30, 0x23); + pac7311_reg_write(dev, 0x31, 0x28); + pac7311_reg_write(dev, 0x32, 0x04); + pac7311_reg_write(dev, 0x33, 0x11); + pac7311_reg_write(dev, 0x34, 0x00); + pac7311_reg_write(dev, 0x35, 0x00); + pac7311_reg_write(dev, 0x11, 0x01); + setcontrast(gspca_dev); + setbrightness(gspca_dev); + setcolors(gspca_dev); + + /* set correct resolution */ + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 2: /* 160x120 */ + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x02, 0x03); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x08, 0x09); + pac7311_reg_write(dev, 0x17, 0x20); + pac7311_reg_write(dev, 0x1b, 0x00); +/* pac7311_reg_write(dev, 0x80, 0x69); */ + pac7311_reg_write(dev, 0x87, 0x10); + break; + case 1: /* 320x240 */ + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x02, 0x03); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x08, 0x09); + pac7311_reg_write(dev, 0x17, 0x30); +/* pac7311_reg_write(dev, 0x80, 0x3f); */ + pac7311_reg_write(dev, 0x87, 0x11); + break; + case 0: /* 640x480 */ + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x02, 0x03); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x08, 0x08); + pac7311_reg_write(dev, 0x17, 0x00); +/* pac7311_reg_write(dev, 0x80, 0x1c); */ + pac7311_reg_write(dev, 0x87, 0x12); + break; + } + + /* start stream */ + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x78, 0x04); + pac7311_reg_write(dev, 0x78, 0x05); + + if (sd->autogain) { + sd->ag_cnt = AG_CNT_START; + sd->avg_lum = 0; + } else { + sd->ag_cnt = -1; + } +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x27, 0x80); + pac7311_reg_write(dev, 0x28, 0xca); + pac7311_reg_write(dev, 0x29, 0x53); + pac7311_reg_write(dev, 0x2a, 0x0e); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x3e, 0x20); + pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + pac7311_reg_write(dev, 0xff, 0x04); + pac7311_reg_write(dev, 0x27, 0x80); + pac7311_reg_write(dev, 0x28, 0xca); + pac7311_reg_write(dev, 0x29, 0x53); + pac7311_reg_write(dev, 0x2a, 0x0e); + pac7311_reg_write(dev, 0xff, 0x01); + pac7311_reg_write(dev, 0x3e, 0x20); + pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ +} + +static void setautogain(struct gspca_dev *gspca_dev, int luma) +{ + int luma_mean = 128; + int luma_delta = 20; + __u8 spring = 5; + __u8 Pxclk; + int Gbright; + + pac7311_reg_read(gspca_dev->dev, 0x02, &Pxclk); + Gbright = Pxclk; + PDEBUG(D_FRAM, "luma mean %d", luma); + if (luma < luma_mean - luma_delta || + luma > luma_mean + luma_delta) { + Gbright += (luma_mean - luma) >> spring; + if (Gbright > 0x1a) + Gbright = 0x1a; + else if (Gbright < 4) + Gbright = 4; + PDEBUG(D_FRAM, "gbright %d", Gbright); + pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); + pac7311_reg_write(gspca_dev->dev, 0x0f, Gbright); + /* load registers to sensor (Bit 0, auto clear) */ + pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned char tmpbuf[4]; + int i, p, ffseq; + +/* if (len < 5) { */ + if (len < 6) { +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + + ffseq = sd->ffseq; + + for (p = 0; p < len - 6; p++) { + if ((data[0 + p] == 0xff) + && (data[1 + p] == 0xff) + && (data[2 + p] == 0x00) + && (data[3 + p] == 0xff) + && (data[4 + p] == 0x96)) { + + /* start of frame */ + if (sd->ag_cnt >= 0 && p > 28) { + sd->avg_lum += data[p - 23]; + if (--sd->ag_cnt < 0) { + sd->ag_cnt = AG_CNT_START; + setautogain(gspca_dev, + sd->avg_lum / AG_CNT_START); + sd->avg_lum = 0; + } + } + + /* copy the end of data to the current frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, p); + + /* put the JPEG header in the new frame */ + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + (unsigned char *) pac7311_jpeg_header, + 12); + tmpbuf[0] = gspca_dev->height >> 8; + tmpbuf[1] = gspca_dev->height & 0xff; + tmpbuf[2] = gspca_dev->width >> 8; + tmpbuf[3] = gspca_dev->width & 0xff; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + tmpbuf, 4); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + (unsigned char *) &pac7311_jpeg_header[16], + PAC7311_JPEG_HEADER_SIZE - 16); + + data += p + 7; + len -= p + 7; + ffseq = 0; + break; + } + } + + /* remove the 'ff ff ff xx' sequences */ + switch (ffseq) { + case 3: + data += 1; + len -= 1; + break; + case 2: + if (data[0] == 0xff) { + data += 2; + len -= 2; + frame->data_end -= 2; + } + break; + case 1: + if (data[0] == 0xff + && data[1] == 0xff) { + data += 3; + len -= 3; + frame->data_end -= 1; + } + break; + } + for (i = 0; i < len - 4; i++) { + if (data[i] == 0xff + && data[i + 1] == 0xff + && data[i + 2] == 0xff) { + memmove(&data[i], &data[i + 4], len - i - 4); + len -= 4; + } + } + ffseq = 0; + if (data[len - 4] == 0xff) { + if (data[len - 3] == 0xff + && data[len - 2] == 0xff) { + len -= 4; + } + } else if (data[len - 3] == 0xff) { + if (data[len - 2] == 0xff + && data[len - 1] == 0xff) + ffseq = 3; + } else if (data[len - 2] == 0xff) { + if (data[len - 1] == 0xff) + ffseq = 2; + } else if (data[len - 1] == 0xff) + ffseq = 1; + sd->ffseq = ffseq; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ +/* __u8 brightness = 0; + + pac7311_reg_read(gspca_dev->dev, 0x0008, &brightness); + spca50x->brightness = brightness; + return spca50x->brightness; */ +/* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ +} + + + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + +/* getcontrast(gspca_dev); */ + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + +/* getcolors(gspca_dev); */ + *val = sd->colors; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (val) { + sd->ag_cnt = AG_CNT_START; + sd->avg_lum = 0; + } else { + sd->ag_cnt = -1; + } + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")}, + {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, + {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, + {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, + {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350")}, + {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, + {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c new file mode 100644 index 000000000000..d26255ddfd5b --- /dev/null +++ b/drivers/media/video/gspca/sonixb.c @@ -0,0 +1,879 @@ +/* + * sonix sn9c102 (bayer) library + * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr + * Add Pas106 Stefano Mozzi (C) 2004 + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "sonixb" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + + char sensor; /* Type of image sensor chip */ +#define SENSOR_HV7131R 0 +#define SENSOR_OV6650 1 +#define SENSOR_OV7630 2 +#define SENSOR_OV7630_3 3 +#define SENSOR_PAS106 4 +#define SENSOR_PAS202 5 +#define SENSOR_TAS5110 6 +#define SENSOR_TAS5130CXX 7 +}; + +#define COMP2 0x8f +#define COMP 0xc7 /* 0x87 //0x07 */ +#define COMP1 0xc9 /* 0x89 //0x09 */ + +#define MCK_INIT 0x63 +#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/ + +#define SYS_CLK 0x04 + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +}; + +/* fixme: should have V4L2_PIX_FMT_SN9C10X */ +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_SN9C10X, 160, 120, 2}, + {V4L2_PIX_FMT_SN9C10X, 320, 240, 1}, + {V4L2_PIX_FMT_SN9C10X, 640, 480, 0}, +}; +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_SN9C10X, 176, 144, 1}, + {V4L2_PIX_FMT_SN9C10X, 352, 288, 0}, +}; + +static const __u8 probe_ov7630[] = {0x08, 0x44}; + +static const __u8 initHv7131[] = { + 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */ + 0x28, 0x1e, 0x60, 0x8a, 0x20, + 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c +}; +static const __u8 hv7131_sensor_init[][8] = { + {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10}, + {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10}, + {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10}, + {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16}, + {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15}, +}; +static const __u8 initOv6650[] = { + 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b, + 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00 +}; +static const __u8 ov6650_sensor_init[][8] = +{ + /* Bright, contrast, etc are set througth SCBB interface. + * AVCAP on win2 do not send any data on this controls. */ + /* Anyway, some registers appears to alter bright and constrat */ + {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10}, + {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10}, +/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10}, + * THIS SET GREEN SCREEN + * (pixels could be innverted in decode kind of "brg", + * but blue wont be there. Avoid this data ... */ + {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ + {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, + {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, + {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, + {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, + {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ + {0xa0, 0x60, 0x10, 0x5d, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x2d, 0x0a, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x33, 0x40, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x11, 0xc0, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x00, 0x16, 0x99, 0x04, 0x94, 0x15}, /* bright / Lumino */ + {0xa0, 0x60, 0x2b, 0xab, 0x99, 0x04, 0x94, 0x15}, + /* ?flicker o brillo */ + {0xa0, 0x60, 0x2d, 0x2a, 0x99, 0x04, 0x94, 0x15}, + {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x33, 0x00, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, + {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, + /* Low Light (Enabled: 0x32 0x1 | Disabled: 0x32 0x00) */ + {0xa0, 0x60, 0x33, 0x29, 0x99, 0x04, 0x94, 0x16}, + /* Low Ligth (Enabled: 0x33 0x13 | Disabled: 0x33 0x29) */ +/* {0xa0, 0x60, 0x11, 0xc1, 0x99, 0x04, 0x94, 0x16}, */ + {0xa0, 0x60, 0x00, 0x17, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ + {0xa0, 0x60, 0x00, 0x18, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ +}; +static const __u8 initOv7630[] = { + 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ + 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ + 0x28, 0x1e, /* H & V sizes r15 .. r16 */ + 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ + 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ +}; +static const __u8 initOv7630_3[] = { + 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ + 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ + 0x28, 0x1e, /* H & V sizes r15 .. r16 */ + 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ + 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ +}; +static const __u8 ov7630_sensor_init_com[][8] = { + {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, +/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ + {0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10}, /* jfm */ + {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, + {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, + {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, + {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10}, + {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, + {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, + {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, +/* {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, jfm */ + {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, /* jfm */ + {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, + {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, + {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, + {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10}, + {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, + {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, +}; +static const __u8 ov7630_sensor_init[][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ + {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ + {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ +}; +static const __u8 ov7630_sensor_init_3[][8] = { + {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ + {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ +/* {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d}, + * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */ +/* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */ + {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d}, +}; + +static const __u8 initPas106[] = { + 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, + 0x16, 0x12, 0x28, COMP1, MCK_INIT1, + 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c +}; +/* compression 0x86 mckinit1 0x2b */ +static const __u8 pas106_data[][2] = { + {0x02, 0x04}, /* Pixel Clock Divider 6 */ + {0x03, 0x13}, /* Frame Time MSB */ +/* {0x03, 0x12}, * Frame Time MSB */ + {0x04, 0x06}, /* Frame Time LSB */ +/* {0x04, 0x05}, * Frame Time LSB */ + {0x05, 0x65}, /* Shutter Time Line Offset */ +/* {0x05, 0x6d}, * Shutter Time Line Offset */ +/* {0x06, 0xb1}, * Shutter Time Pixel Offset */ + {0x06, 0xcd}, /* Shutter Time Pixel Offset */ + {0x07, 0xc1}, /* Black Level Subtract Sign */ +/* {0x07, 0x00}, * Black Level Subtract Sign */ + {0x08, 0x06}, /* Black Level Subtract Level */ + {0x08, 0x06}, /* Black Level Subtract Level */ +/* {0x08, 0x01}, * Black Level Subtract Level */ + {0x09, 0x05}, /* Color Gain B Pixel 5 a */ + {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */ + {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */ + {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */ + {0x0d, 0x00}, /* Color GainH Pixel */ + {0x0e, 0x0e}, /* Global Gain */ + {0x0f, 0x00}, /* Contrast */ + {0x10, 0x06}, /* H&V synchro polarity */ + {0x11, 0x06}, /* ?default */ + {0x12, 0x06}, /* DAC scale */ + {0x14, 0x02}, /* ?default */ + {0x13, 0x01}, /* Validate Settings */ +}; +static const __u8 initPas202[] = { + 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */ + 0x28, 0x1e, 0x28, 0x89, 0x30, + 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c +}; +static const __u8 pas202_sensor_init[][8] = { + {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10}, + {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10}, + {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10}, + {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10}, + {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10}, + {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10}, + {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, + {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10}, + {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10}, + {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10}, + {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10}, + + {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, + {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15}, + {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16}, + {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16}, + {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16}, + {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, + {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}, + {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}, +}; + +static const __u8 initTas5110[] = { + 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */ + 0x16, 0x12, 0x60, 0x86, 0x2b, + 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07 +}; +static const __u8 tas5110_sensor_init[][8] = { + {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10}, + {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10}, + {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17}, +}; + +static const __u8 initTas5130[] = { + 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a, + 0x28, 0x1e, 0x60, COMP, MCK_INIT, + 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c +}; +static const __u8 tas5130_sensor_init[][8] = { +/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10}, + * shutter 0x47 short exposure? */ + {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10}, + /* shutter 0x01 long exposure */ + {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, +}; + +static void reg_r(struct usb_device *dev, + __u16 value, __u8 *buffer) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, + 0, /* index */ + buffer, 1, + 500); +} + +static void reg_w(struct usb_device *dev, + __u16 value, + const __u8 *buffer, + __u16 len) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0x08, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, + 0, /* index */ + (__u8 *) buffer, len, + 500); +} + +static int i2c_w(struct usb_device *dev, const __u8 *buffer) +{ + int retry = 60; + __u8 ByteReceive; + + /* is i2c ready */ + reg_w(dev, 0x08, buffer, 8); + while (retry--) { + msleep(10); + reg_r(dev, 0x08, &ByteReceive); + if (ByteReceive == 4) + return 0; + } + return -1; +} + +static void i2c_w_vector(struct usb_device *dev, + const __u8 buffer[][8], int len) +{ + for (;;) { + reg_w(dev, 0x08, *buffer, 8); + len -= 8; + if (len <= 0) + break; + buffer++; + } +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value; + + switch (sd->sensor) { + case SENSOR_OV6650: { + __u8 i2cOV6650[] = + {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; + + i2cOV6650[3] = sd->brightness; + if (i2c_w(gspca_dev->dev, i2cOV6650) < 0) + goto err; + break; + } + case SENSOR_OV7630: { + __u8 i2cOV[] = + {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16}; + + /* change reg 0x06 */ + i2cOV[3] = sd->brightness; + if (i2c_w(gspca_dev->dev, i2cOV) < 0) + goto err; + break; + } + case SENSOR_PAS106: { + __u8 i2c1[] = + {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14}; + + i2c1[3] = sd->brightness >> 3; + i2c1[2] = 0x0e; + if (i2c_w(gspca_dev->dev, i2c1) < 0) + goto err; + i2c1[3] = 0x01; + i2c1[2] = 0x13; + if (i2c_w(gspca_dev->dev, i2c1) < 0) + goto err; + break; + } + case SENSOR_PAS202: { + /* __u8 i2cpexpo1[] = + {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */ + __u8 i2cpexpo[] = + {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16}; + __u8 i2cp202[] = + {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15}; + static __u8 i2cpdoit[] = + {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16}; + + /* change reg 0x10 */ + i2cpexpo[4] = 0xff - sd->brightness; +/* if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0) + goto err; */ +/* if(i2c_w(gspca_dev->dev,i2cpdoit) < 0) + goto err; */ + if (i2c_w(gspca_dev->dev, i2cpexpo) < 0) + goto err; + if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) + goto err; + i2cp202[3] = sd->brightness >> 3; + if (i2c_w(gspca_dev->dev, i2cp202) < 0) + goto err; + if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) + goto err; + break; + } + case SENSOR_TAS5130CXX: + case SENSOR_TAS5110: { + __u8 i2c[] = + {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; + + value = 0xff - sd->brightness; + i2c[4] = value; + PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); + if (i2c_w(gspca_dev->dev, i2c) < 0) + goto err; + break; + } + } + return; +err: + PDEBUG(D_ERR, "i2c error brightness"); +} +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 gain; + __u8 rgb_value; + + gain = sd->contrast >> 4; + /* red and blue gain */ + rgb_value = gain << 4 | gain; + reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); + /* green gain */ + rgb_value = gain; + reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; +/* __u16 vendor; */ + __u16 product; + int sif = 0; + +/* vendor = id->idVendor; */ + product = id->idProduct; +/* switch (vendor) { */ +/* case 0x0c45: * Sonix */ + switch (product) { + case 0x6001: /* SN9C102 */ + case 0x6005: /* SN9C101 */ + case 0x6007: /* SN9C101 */ + sd->sensor = SENSOR_TAS5110; + sif = 1; + break; + case 0x6009: /* SN9C101 */ + case 0x600d: /* SN9C101 */ + case 0x6029: /* SN9C101 */ + sd->sensor = SENSOR_PAS106; + sif = 1; + break; + case 0x6011: /* SN9C101 - SN9C101G */ + sd->sensor = SENSOR_OV6650; + sif = 1; + break; + case 0x6019: /* SN9C101 */ + case 0x602c: /* SN9C102 */ + case 0x602e: /* SN9C102 */ + sd->sensor = SENSOR_OV7630; + break; + case 0x60b0: /* SN9C103 */ + sd->sensor = SENSOR_OV7630_3; + break; + case 0x6024: /* SN9C102 */ + case 0x6025: /* SN9C102 */ + sd->sensor = SENSOR_TAS5130CXX; + break; + case 0x6028: /* SN9C102 */ + sd->sensor = SENSOR_PAS202; + break; + case 0x602d: /* SN9C102 */ + sd->sensor = SENSOR_HV7131R; + break; + case 0x60af: /* SN9C103 */ + sd->sensor = SENSOR_PAS202; + break; + } +/* break; */ +/* } */ + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + if (!sif) { + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + } else { + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + } + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ + reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + __u8 ByteReceive; + + reg_r(gspca_dev->dev, 0x00, &ByteReceive); + if (ByteReceive != 0x10) + return -ENODEV; + return 0; +} + +static void pas106_i2cinit(struct usb_device *dev) +{ + int i; + const __u8 *data; + __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 }; + + i = ARRAY_SIZE(pas106_data); + data = pas106_data[0]; + while (--i >= 0) { + memcpy(&i2c1[2], data, 2); + /* copy 2 bytes from the template */ + if (i2c_w(dev, i2c1) < 0) + PDEBUG(D_ERR, "i2c error pas106"); + data += 2; + } +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int mode, l; + const __u8 *sn9c10x; + __u8 reg01, reg17; + __u8 reg17_19[3]; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + switch (sd->sensor) { + case SENSOR_HV7131R: + sn9c10x = initHv7131; + reg17_19[0] = 0x60; + reg17_19[1] = (mode << 4) | 0x8a; + reg17_19[2] = 0x20; + break; + case SENSOR_OV6650: + sn9c10x = initOv6650; + reg17_19[0] = 0x68; + reg17_19[1] = (mode << 4) | 0x8b; + reg17_19[2] = 0x20; + break; + case SENSOR_OV7630: + sn9c10x = initOv7630; + reg17_19[0] = 0x68; + reg17_19[1] = (mode << 4) | COMP2; + reg17_19[2] = MCK_INIT1; + break; + case SENSOR_OV7630_3: + sn9c10x = initOv7630_3; + reg17_19[0] = 0x68; + reg17_19[1] = (mode << 4) | COMP2; + reg17_19[2] = MCK_INIT1; + break; + case SENSOR_PAS106: + sn9c10x = initPas106; + reg17_19[0] = 0x24; /* 0x28 */ + reg17_19[1] = (mode << 4) | COMP1; + reg17_19[2] = MCK_INIT1; + break; + case SENSOR_PAS202: + sn9c10x = initPas202; + reg17_19[0] = mode ? 0x24 : 0x20; + reg17_19[1] = (mode << 4) | 0x89; + reg17_19[2] = 0x20; + break; + case SENSOR_TAS5110: + sn9c10x = initTas5110; + reg17_19[0] = 0x60; + reg17_19[1] = (mode << 4) | 0x86; + reg17_19[2] = 0x2b; /* 0xf3; */ + break; + default: +/* case SENSOR_TAS5130CXX: */ + sn9c10x = initTas5130; + reg17_19[0] = 0x60; + reg17_19[1] = (mode << 4) | COMP; + reg17_19[2] = mode ? 0x23 : 0x43; + break; + } + switch (sd->sensor) { + case SENSOR_OV7630: + reg01 = 0x06; + reg17 = 0x29; + l = 0x10; + break; + case SENSOR_OV7630_3: + reg01 = 0x44; + reg17 = 0x68; + l = 0x10; + break; + default: + reg01 = sn9c10x[0]; + reg17 = sn9c10x[0x17 - 1]; + l = 0x1f; + break; + } + + /* reg 0x01 bit 2 video transfert on */ + reg_w(dev, 0x01, ®01, 1); + /* reg 0x17 SensorClk enable inv Clk 0x60 */ + reg_w(dev, 0x17, ®17, 1); +/*fixme: for ov7630 102 + reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */ + /* Set the registers from the template */ + reg_w(dev, 0x01, sn9c10x, l); + switch (sd->sensor) { + case SENSOR_HV7131R: + i2c_w_vector(dev, hv7131_sensor_init, + sizeof hv7131_sensor_init); + break; + case SENSOR_OV6650: + i2c_w_vector(dev, ov6650_sensor_init, + sizeof ov6650_sensor_init); + break; + case SENSOR_OV7630: + i2c_w_vector(dev, ov7630_sensor_init_com, + sizeof ov7630_sensor_init_com); + msleep(200); + i2c_w_vector(dev, ov7630_sensor_init, + sizeof ov7630_sensor_init); + break; + case SENSOR_OV7630_3: + i2c_w_vector(dev, ov7630_sensor_init_com, + sizeof ov7630_sensor_init_com); + msleep(200); + i2c_w_vector(dev, ov7630_sensor_init_3, + sizeof ov7630_sensor_init_3); + break; + case SENSOR_PAS106: + pas106_i2cinit(dev); + break; + case SENSOR_PAS202: + i2c_w_vector(dev, pas202_sensor_init, + sizeof pas202_sensor_init); + break; + case SENSOR_TAS5110: + i2c_w_vector(dev, tas5110_sensor_init, + sizeof tas5110_sensor_init); + break; + default: +/* case SENSOR_TAS5130CXX: */ + i2c_w_vector(dev, tas5130_sensor_init, + sizeof tas5130_sensor_init); + break; + } + /* H_size V_size 0x28, 0x1e maybe 640x480 */ + reg_w(dev, 0x15, &sn9c10x[0x15 - 1], 2); + /* compression register */ + reg_w(dev, 0x18, ®17_19[1], 1); + /* H_start */ /*fixme: not ov7630*/ + reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); + /* V_START */ /*fixme: not ov7630*/ + reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); + /* reset 0x17 SensorClk enable inv Clk 0x60 */ + /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ + reg_w(dev, 0x17, ®17_19[0], 1); + /*MCKSIZE ->3 */ /*fixme: not ov7630*/ + reg_w(dev, 0x19, ®17_19[2], 1); + /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ + reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); + /* Enable video transfert */ + reg_w(dev, 0x01, &sn9c10x[0], 1); + /* Compression */ + reg_w(dev, 0x18, ®17_19[1], 2); + msleep(20); + + setcontrast(gspca_dev); + setbrightness(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + __u8 ByteSend = 0; + + ByteSend = 0x09; /* 0X00 */ + reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + int p; + + if (len > 6 && len < 24) { + for (p = 0; p < len - 6; p++) { + if (data[0 + p] == 0xff + && data[1 + p] == 0xff + && data[2 + p] == 0x00 + && data[3 + p] == 0xc4 + && data[4 + p] == 0xc4 + && data[5 + p] == 0x96) { /* start of frame */ + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + data, 0); + data += 12; + len -= 12; + gspca_frame_add(gspca_dev, FIRST_PACKET, + frame, data, len); + return; + } + } + } + gspca_frame_add(gspca_dev, INTER_PACKET, + frame, data, len); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, + {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, + {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, + {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, + {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, + {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia-OV6650-SN9C101G")}, + {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, + {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, + {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, + {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, + {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, + {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, + {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, + {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, + {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, + {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c new file mode 100644 index 000000000000..6180bc565ca1 --- /dev/null +++ b/drivers/media/video/gspca/sonixj.c @@ -0,0 +1,1629 @@ +/* + * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library + * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "sonixj" + +#include "gspca.h" +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int avg_lum; + unsigned int exposure; + + unsigned short brightness; + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + + signed char ag_cnt; +#define AG_CNT_START 13 + + char qindex; + char sensor; /* Type of image sensor chip */ +#define SENSOR_HV7131R 0 +#define SENSOR_MI0360 1 +#define SENSOR_MO4000 2 +#define SENSOR_OV7648 3 +#define SENSOR_OV7660 4 + unsigned char customid; +#define SN9C102P 0 +#define SN9C105 1 +#define SN9C110 2 +#define SN9C120 3 +#define SN9C325 4 + unsigned char i2c_base; + unsigned char i2c_ctrl_reg; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xffff, + .step = 1, + .default_value = 0x7fff, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 63, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_AUTOGAIN 3 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 160, 120, 2}, + {V4L2_PIX_FMT_JPEG, 320, 240, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +/*Data from sn9c102p+hv71331r */ +static __u8 sn_hv7131[] = { + 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ + 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ +/* rega regb regc regd rege regf reg10 reg11 */ + 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, +/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ +}; + +static __u8 sn_mi0360[] = { + 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ + 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, +/* rega regb regc regd rege regf reg10 reg11 */ + 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, +/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +/* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ +}; + +static __u8 sn_mo4000[] = { + 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, +/* reg9 rega regb regc regd rege regf reg10 reg11*/ + 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, +/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, +/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ + 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, + 0xd3, 0xdf, 0xea, 0xf5 +}; + +static __u8 sn_ov7648[] = { + 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, + 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static __u8 sn_ov7660[] = { +/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ + 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, +/* reg9 rega regb regc regd rege regf reg10 reg11*/ + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, +/* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ + 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 0x07, 0x00, 0x00, +/* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* sequence specific to the sensors - !! index = SENSOR_xxx */ +static __u8 *sn_tb[] = { + sn_hv7131, + sn_mi0360, + sn_mo4000, + sn_ov7648, + sn_ov7660 +}; + +static __u8 regsn20[] = { + 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, + 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff +}; +static __u8 regsn20_sn9c325[] = { + 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, + 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 +}; + +static __u8 reg84[] = { + 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, + 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, +/* 0x00, 0x00, 0x00, 0x00, 0x00 */ + 0xf7, 0x0f, 0x0a, 0x00, 0x00 +}; +static __u8 reg84_sn9c325[] = { + 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, + 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, + 0xf8, 0x0f, 0x00, 0x00, 0x00 +}; + +static __u8 hv7131r_sensor_init[][8] = { + {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, + {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10}, + {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10}, + {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10}, + {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10}, + {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */ + {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */ + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10}, + + {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, + {0, 0, 0, 0, 0, 0, 0, 0} +}; +static __u8 mi0360_sensor_init[][8] = { + {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10}, + {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10}, + {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10}, + {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10}, + {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10}, + {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10}, + {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10}, + {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10}, + {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10}, + {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10}, + + {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, + {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10}, + {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10}, + + {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */ + {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10}, + {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */ + + {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10}, + {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */ +/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */ +/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ + {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ + {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ + {0, 0, 0, 0, 0, 0, 0, 0} +}; +static __u8 mo4000_sensor_init[][8] = { + {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, + {0, 0, 0, 0, 0, 0, 0, 0} +}; +static __u8 ov7660_sensor_init[][8] = { + {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ + {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, + /* Outformat ?? rawRGB */ + {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ +/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, + * GAIN BLUE RED VREF */ + {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, + /* GAIN BLUE RED VREF */ + {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, + /* COM 1 BAVE GEAVE AECHH */ + {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ + {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ +/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, + * AECH CLKRC COM7 COM8 */ + {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, + /* AECH CLKRC COM7 COM8 */ + {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ + {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, + /* HSTART HSTOP VSTRT VSTOP */ + {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */ + {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ + {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, + /* BOS GBOS GROS ROS (BGGR offset) */ +/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, + * AEW AEB VPT BBIAS */ + {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, + /* AEW AEB VPT BBIAS */ + {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, + /* GbBIAS RSVD EXHCH EXHCL */ + {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10}, + /* RBIAS ADVFL ASDVFH YAVE */ + {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10}, + /* HSYST HSYEN HREF */ + {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */ + {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10}, + /* ADC ACOM OFON TSLB */ + {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10}, + /* COM11 COM12 COM13 COM14 */ + {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10}, + /* EDGE COM15 COM16 COM17 */ + {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */ + {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */ + {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */ + {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */ + {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */ + {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */ + {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */ + {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */ + {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */ + {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10}, + /* LCC1 LCC2 LCC3 LCC4 */ + {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */ + {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, + {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10}, + /* band gap reference [0..3] DBLV */ + {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */ + {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */ + {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */ + {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */ + {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, +/****** (some exchanges in the win trace) ******/ + {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, + /* bits[3..0]reserved */ + {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, + /* VREF vertical frame ctrl */ + {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ + {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, +/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, */ +/****** (some exchanges in the win trace) ******/ + {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ + {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ + {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, +/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, */ +/****** (some exchanges in the win trace) ******/ +/**********startsensor KO if changed !!****/ + {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, +/* here may start the isoc exchanges */ + {0, 0, 0, 0, 0, 0, 0, 0} +}; +/* reg0x04 reg0x07 reg 0x10 */ +/* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ + +static __u8 ov7648_sensor_init[][8] = { + {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, + {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, + {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, + {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10}, + {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10}, + {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10}, + {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10}, + {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10}, + {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10}, + {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10}, + {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10}, + {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10}, + {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10}, + {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10}, + {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10}, + {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10}, + {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10}, + {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10}, + {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10}, + /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10}, + * This is currently setting a + * blue tint, and some things more , i leave it here for future test if + * somene is having problems with color on this sensor + {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10}, + {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10}, + {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, + {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, + {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */ + {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, + {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */ + {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */ + {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/ +/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */ + {0, 0, 0, 0, 0, 0, 0, 0} +}; + +static __u8 qtable4[] = { + 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, + 0x06, 0x08, 0x0A, 0x11, + 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, + 0x19, 0x19, 0x17, 0x15, + 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17, + 0x21, 0x2E, 0x21, 0x23, + 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32, + 0x25, 0x29, 0x2C, 0x29, + 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B, + 0x17, 0x1B, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, + 0x29, 0x29, 0x29, 0x29 +}; + +static void reg_r(struct usb_device *dev, + __u16 value, + __u8 *buffer, int len) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, 0, + buffer, len, + 500); +} + +static void reg_w(struct usb_device *dev, + __u16 value, + __u8 *buffer, + int len) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, 0, + buffer, len, + 500); +} + +/* write 2 bytes */ +static void i2c_w2(struct gspca_dev *gspca_dev, + __u8 *buffer) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 mode[8]; + + /* is i2c ready */ + mode[0] = sd->i2c_ctrl_reg | (2 << 4); + mode[1] = sd->i2c_base; + mode[2] = buffer[0]; + mode[3] = buffer[1]; + mode[4] = 0; + mode[5] = 0; + mode[6] = 0; + mode[7] = 0x10; + reg_w(dev, 0x08, mode, 8); +} + +/* write 8 bytes */ +static void i2c_w8(struct usb_device *dev, __u8 *buffer) +{ + reg_w(dev, 0x08, buffer, 8); + msleep(1); +} + +/* read 5 bytes */ +static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, + __u8 *buffer) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 mode[8]; + + mode[0] = sd->i2c_ctrl_reg | 0x10; + mode[1] = sd->i2c_base; + mode[2] = reg; + mode[3] = 0; + mode[4] = 0; + mode[5] = 0; + mode[6] = 0; + mode[7] = 0x10; + i2c_w8(dev, mode); + mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02; + mode[2] = 0; + i2c_w8(dev, mode); + reg_r(dev, 0x0a, buffer, 5); +} + +static int probesensor(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 reg02; + static __u8 datasend[] = { 2, 0 }; + /* reg val1 val2 val3 val4 */ + __u8 datarecd[6]; + + i2c_w2(gspca_dev, datasend); +/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ + msleep(10); + reg02 = 0x66; + reg_w(dev, 0x02, ®02, 1); /* Gpio on */ + msleep(10); + i2c_r5(gspca_dev, 0, datarecd); /* read sensor id */ + if (datarecd[0] == 0x02 + && datarecd[1] == 0x09 + && datarecd[2] == 0x01 + && datarecd[3] == 0x00 + && datarecd[4] == 0x00) { + PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); + sd->sensor = SENSOR_HV7131R; + return SENSOR_HV7131R; + } + PDEBUG(D_PROBE, "Find Sensor %d %d %d", + datarecd[0], datarecd[1], datarecd[2]); + PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); + return -ENODEV; +} + +static int configure_gpio(struct gspca_dev *gspca_dev, + __u8 *sn9c1xx) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 data; + __u8 regF1; + __u8 *reg9a; + static __u8 reg9a_def[] = + {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; + static __u8 reg9a_sn9c120[] = /* from win trace */ + {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; + static __u8 reg9a_sn9c325[] = + {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; + + + regF1 = 0x00; + reg_w(dev, 0xf1, ®F1, 1); + + reg_w(dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ + + /* configure gpio */ + reg_w(dev, 0x01, &sn9c1xx[1], 2); + reg_w(dev, 0x08, &sn9c1xx[8], 2); + reg_w(dev, 0x17, &sn9c1xx[0x17], 3); + switch (sd->customid) { + case SN9C325: + reg9a = reg9a_sn9c325; + break; + case SN9C120: + reg9a = reg9a_sn9c120; + break; + default: + reg9a = reg9a_def; + break; + } + reg_w(dev, 0x9a, reg9a, 6); + + data = 0x60; /*fixme:jfm 60 00 00 (3) */ + reg_w(dev, 0xd4, &data, 1); + + reg_w(dev, 0x03, &sn9c1xx[3], 0x0f); + + switch (sd->customid) { + case SN9C120: /* from win trace */ + data = 0x61; + reg_w(dev, 0x01, &data, 1); + data = 0x20; + reg_w(dev, 0x17, &data, 1); + data = 0x60; + reg_w(dev, 0x01, &data, 1); + break; + case SN9C325: + data = 0x43; + reg_w(dev, 0x01, &data, 1); + data = 0xae; + reg_w(dev, 0x17, &data, 1); + data = 0x42; + reg_w(dev, 0x01, &data, 1); + break; + default: + data = 0x43; + reg_w(dev, 0x01, &data, 1); + data = 0x61; + reg_w(dev, 0x17, &data, 1); + data = 0x42; + reg_w(dev, 0x01, &data, 1); + } + + if (sd->sensor == SENSOR_HV7131R) { + if (probesensor(gspca_dev) < 0) + return -ENODEV; + } + return 0; +} + +static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + struct usb_device *dev = gspca_dev->dev; + static __u8 SetSensorClk[] = /* 0x08 Mclk */ + { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; + + while (hv7131r_sensor_init[i][0]) { + i2c_w8(dev, hv7131r_sensor_init[i]); + i++; + } + i2c_w8(dev, SetSensorClk); +} + +static void mi0360_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + struct usb_device *dev = gspca_dev->dev; + + while (mi0360_sensor_init[i][0]) { + i2c_w8(dev, mi0360_sensor_init[i]); + i++; + } +} + +static void mo4000_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + struct usb_device *dev = gspca_dev->dev; + + while (mo4000_sensor_init[i][0]) { + i2c_w8(dev, mo4000_sensor_init[i]); + i++; + } +} + +static void ov7648_InitSensor(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int i = 0; + + while (ov7648_sensor_init[i][0]) { + i2c_w8(dev, ov7648_sensor_init[i]); + i++; + } +} + +static void ov7660_InitSensor(struct gspca_dev *gspca_dev) +{ + int i = 0; + struct usb_device *dev = gspca_dev->dev; + + while (ov7660_sensor_init[i][0]) { + i2c_w8(dev, ov7660_sensor_init[i]); + i++; + } +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; + sd->sensor = -1; + switch (vendor) { + case 0x0458: /* Genius */ +/* switch (product) { + case 0x7025: */ + sd->customid = SN9C120; + sd->sensor = SENSOR_MI0360; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x5d; +/* break; + } */ + break; + case 0x045e: +/* switch (product) { + case 0x00f5: + case 0x00f7: */ + sd->customid = SN9C105; + sd->sensor = SENSOR_OV7660; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; +/* break; + } */ + break; + case 0x0471: /* Philips */ +/* switch (product) { + case 0x0327: + case 0x0328: + case 0x0330: */ + sd->customid = SN9C105; + sd->sensor = SENSOR_MI0360; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x5d; +/* break; + } */ + break; + case 0x0c45: /* Sonix */ + switch (product) { + case 0x6040: + sd->customid = SN9C102P; + sd->sensor = SENSOR_MI0360; /* from BW600.inf */ +/* sd->sensor = SENSOR_HV7131R; * gspcav1 value */ + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x11; + break; +/* case 0x607a: * from BW600.inf + sd->customid = SN9C102P; + sd->sensor = SENSOR_OV7648; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x607c: + sd->customid = SN9C102P; + sd->sensor = SENSOR_HV7131R; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x11; + break; +/* case 0x607e: * from BW600.inf + sd->customid = SN9C102P; + sd->sensor = SENSOR_OV7630; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x60c0: + sd->customid = SN9C105; + sd->sensor = SENSOR_MI0360; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x5d; + break; +/* case 0x60c8: * from BW600.inf + sd->customid = SN9C105; + sd->sensor = SENSOR_OM6801; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ +/* case 0x60cc: * from BW600.inf + sd->customid = SN9C105; + sd->sensor = SENSOR_HV7131GP; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x60ec: + sd->customid = SN9C105; + sd->sensor = SENSOR_MO4000; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; +/* case 0x60ef: * from BW600.inf + sd->customid = SN9C105; + sd->sensor = SENSOR_ICM105C; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ +/* case 0x60fa: * from BW600.inf + sd->customid = SN9C105; + sd->sensor = SENSOR_OV7648; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x60fb: + sd->customid = SN9C105; + sd->sensor = SENSOR_OV7660; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; + case 0x60fc: + sd->customid = SN9C105; + sd->sensor = SENSOR_HV7131R; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x11; + break; +/* case 0x60fe: * from BW600.inf + sd->customid = SN9C105; + sd->sensor = SENSOR_OV7630; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ +/* case 0x6108: * from BW600.inf + sd->customid = SN9C120; + sd->sensor = SENSOR_OM6801; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ +/* case 0x6122: * from BW600.inf + sd->customid = SN9C110; + sd->sensor = SENSOR_ICM105C; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x612a: +/* sd->customid = SN9C110; * in BW600.inf */ + sd->customid = SN9C325; + sd->sensor = SENSOR_OV7648; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; +/* case 0x6123: * from BW600.inf + sd->customid = SN9C110; + sd->sensor = SENSOR_SanyoCCD; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x612c: + sd->customid = SN9C110; + sd->sensor = SENSOR_MO4000; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; +/* case 0x612e: * from BW600.inf + sd->customid = SN9C110; + sd->sensor = SENSOR_OV7630; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ +/* case 0x612f: * from BW600.inf + sd->customid = SN9C110; + sd->sensor = SENSOR_ICM105C; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x6130: + sd->customid = SN9C120; + sd->sensor = SENSOR_MI0360; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x5d; + break; + case 0x6138: + sd->customid = SN9C120; + sd->sensor = SENSOR_MO4000; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; +/* case 0x613a: * from BW600.inf + sd->customid = SN9C120; + sd->sensor = SENSOR_OV7648; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + case 0x613b: + sd->customid = SN9C120; + sd->sensor = SENSOR_OV7660; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x21; + break; + case 0x613c: + sd->customid = SN9C120; + sd->sensor = SENSOR_HV7131R; + sd->i2c_ctrl_reg = 0x81; + sd->i2c_base = 0x11; + break; +/* case 0x613e: * from BW600.inf + sd->customid = SN9C120; + sd->sensor = SENSOR_OV7630; + sd->i2c_ctrl_reg = 0x??; + sd->i2c_base = 0x??; + break; */ + } + break; + } + if (sd->sensor < 0) { + PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", + vendor, product); + return -EINVAL; + } + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + sd->qindex = 4; /* set the quantization table */ + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; +/* __u8 *sn9c1xx; */ + __u8 regF1; + __u8 regGpio[] = { 0x29, 0x74 }; + + /* setup a selector by customid */ + regF1 = 0x01; + reg_w(dev, 0xf1, ®F1, 1); + reg_r(dev, 0x00, ®F1, 1); /* -> regF1 = 0x00 */ + reg_w(dev, 0xf1, ®F1, 1); + reg_r(dev, 0x00, ®F1, 1); + switch (sd->customid) { + case SN9C102P: + if (regF1 != 0x11) + return -ENODEV; + reg_w(dev, 0x02, ®Gpio[1], 1); + break; + case SN9C105: + if (regF1 != 0x11) + return -ENODEV; + reg_w(dev, 0x02, regGpio, 2); + break; + case SN9C110: + if (regF1 != 0x12) + return -ENODEV; + regGpio[1] = 0x62; + reg_w(dev, 0x02, ®Gpio[1], 1); + break; + case SN9C120: + if (regF1 != 0x12) + return -ENODEV; + regGpio[1] = 0x70; + reg_w(dev, 0x02, regGpio, 2); + break; + default: +/* case SN9C325: */ + if (regF1 != 0x12) + return -ENODEV; + regGpio[1] = 0x62; + reg_w(dev, 0x02, ®Gpio[1], 1); + break; + } + + regF1 = 0x01; + reg_w(dev, 0xf1, ®F1, 1); + + return 0; +} + +static unsigned int setexposure(struct gspca_dev *gspca_dev, + unsigned int expo) +{ + struct sd *sd = (struct sd *) gspca_dev; + static __u8 doit[] = /* update sensor */ + { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; + static __u8 sensorgo[] = /* sensor on */ + { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; + static __u8 gainMo[] = + { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; + + switch (sd->sensor) { + case SENSOR_HV7131R: { + __u8 Expodoit[] = + { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 }; + + Expodoit[3] = expo >> 16; + Expodoit[4] = expo >> 8; + Expodoit[5] = expo; + i2c_w8(gspca_dev->dev, Expodoit); + break; + } + case SENSOR_MI0360: { + __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */ + { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 }; + + if (expo > 0x0635) + expo = 0x0635; + else if (expo < 0x0001) + expo = 0x0001; + expoMi[3] = expo >> 8; + expoMi[4] = expo; + i2c_w8(gspca_dev->dev, expoMi); + i2c_w8(gspca_dev->dev, doit); + i2c_w8(gspca_dev->dev, sensorgo); + break; + } + case SENSOR_MO4000: { + __u8 expoMof[] = + { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 }; + __u8 expoMo10[] = + { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 }; + + if (expo > 0x1fff) + expo = 0x1fff; + else if (expo < 0x0001) + expo = 0x0001; + expoMof[3] = (expo & 0x03fc) >> 2; + i2c_w8(gspca_dev->dev, expoMof); + expoMo10[3] = ((expo & 0x1c00) >> 10) + | ((expo & 0x0003) << 4); + i2c_w8(gspca_dev->dev, expoMo10); + i2c_w8(gspca_dev->dev, gainMo); + PDEBUG(D_CONF," set exposure %d", + ((expoMo10[3] & 0x07) << 10) + | (expoMof[3] << 2) + | ((expoMo10[3] & 0x30) >> 4)); + break; + } + } + return expo; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned int expo; + __u8 k2; + + switch (sd->sensor) { + case SENSOR_HV7131R: + expo = sd->brightness << 4; + if (expo > 0x002dc6c0) + expo = 0x002dc6c0; + else if (expo < 0x02a0) + expo = 0x02a0; + sd->exposure = setexposure(gspca_dev, expo); + break; + case SENSOR_MI0360: + expo = sd->brightness >> 4; + sd->exposure = setexposure(gspca_dev, expo); + break; + case SENSOR_MO4000: + expo = sd->brightness >> 4; + sd->exposure = setexposure(gspca_dev, expo); + break; + case SENSOR_OV7660: + return; /*jfm??*/ + } + + k2 = sd->brightness >> 10; + reg_w(gspca_dev->dev, 0x96, &k2, 1); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 k2; + __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 }; + + if (sd->sensor == SENSOR_OV7660) + return; /*jfm??*/ + k2 = sd->contrast; + contrast[2] = k2; + contrast[0] = (k2 + 1) >> 1; + contrast[4] = (k2 + 1) / 5; + reg_w(gspca_dev->dev, 0x84, contrast, 6); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 data; + int colour; + + colour = sd->colors - 128; + if (colour > 0) + data = (colour + 32) & 0x7f; /* blue */ + else + data = (-colour + 32) & 0x7f; /* red */ + reg_w(gspca_dev->dev, 0x05, &data, 1); +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int i; + __u8 data; + __u8 reg1; + __u8 reg17; + __u8 *sn9c1xx; + int mode; + static __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; + static __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; + static __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; + static __u8 CA_sn9c120[] = { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ + static __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ + static __u8 CE_sn9c325[] = + { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ + + sn9c1xx = sn_tb[(int) sd->sensor]; + configure_gpio(gspca_dev, sn9c1xx); + +/*fixme:jfm this sequence should appear at end of sd_start */ +/* with + data = 0x44; + reg_w(dev, 0x01, &data, 1); */ + reg_w(dev, 0x15, &sn9c1xx[0x15], 1); + reg_w(dev, 0x16, &sn9c1xx[0x16], 1); + reg_w(dev, 0x12, &sn9c1xx[0x12], 1); + reg_w(dev, 0x13, &sn9c1xx[0x13], 1); + reg_w(dev, 0x18, &sn9c1xx[0x18], 1); + reg_w(dev, 0xd2, &DC29[0], 1); + reg_w(dev, 0xd3, &DC29[1], 1); + reg_w(dev, 0xc6, &DC29[2], 1); + reg_w(dev, 0xc7, &DC29[3], 1); + reg_w(dev, 0xc8, &DC29[4], 1); + reg_w(dev, 0xc9, &DC29[5], 1); +/*fixme:jfm end of ending sequence */ + reg_w(dev, 0x18, &sn9c1xx[0x18], 1); + if (sd->customid == SN9C325) + data = 0xae; + else + data = 0x60; + reg_w(dev, 0x17, &data, 1); + reg_w(dev, 0x05, &sn9c1xx[5], 1); + reg_w(dev, 0x07, &sn9c1xx[7], 1); + reg_w(dev, 0x06, &sn9c1xx[6], 1); + reg_w(dev, 0x14, &sn9c1xx[0x14], 1); + if (sd->customid == SN9C325) { + reg_w(dev, 0x20, regsn20_sn9c325, 0x11); + for (i = 0; i < 8; i++) + reg_w(dev, 0x84, reg84_sn9c325, 0x15); + data = 0x0a; + reg_w(dev, 0x9a, &data, 1); + data = 0x60; + reg_w(dev, 0x99, &data, 1); + } else { + reg_w(dev, 0x20, regsn20, 0x11); + for (i = 0; i < 8; i++) + reg_w(dev, 0x84, reg84, 0x15); + data = 0x08; + reg_w(dev, 0x9a, &data, 1); + data = 0x59; + reg_w(dev, 0x99, &data, 1); + } + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + reg1 = 0x02; + reg17 = 0x61; + switch (sd->sensor) { + case SENSOR_HV7131R: + hv7131R_InitSensor(gspca_dev); + if (mode) + reg1 = 0x46; /* 320 clk 48Mhz */ + else + reg1 = 0x06; /* 640 clk 24Mz */ + break; + case SENSOR_MI0360: + mi0360_InitSensor(gspca_dev); + if (mode) + reg1 = 0x46; /* 320 clk 48Mhz */ + else + reg1 = 0x06; /* 640 clk 24Mz */ + break; + case SENSOR_MO4000: + mo4000_InitSensor(gspca_dev); + if (mode) { +/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ + reg1 = 0x06; /* clk 24Mz */ + } else { + reg17 = 0x22; /* 640 MCKSIZE */ + reg1 = 0x06; /* 640 clk 24Mz */ + } + break; + case SENSOR_OV7648: + reg17 = 0xa2; + reg1 = 0x44; + ov7648_InitSensor(gspca_dev); +/* if (mode) + ; * 320x2... + else + ; * 640x... */ + break; + default: +/* case SENSOR_OV7660: */ + ov7660_InitSensor(gspca_dev); + if (mode) { +/* reg17 = 0x21; * 320 */ +/* reg1 = 0x44; */ + reg1 = 0x46; + } else { + reg17 = 0xa2; /* 640 */ + reg1 = 0x40; + } + break; + } + reg_w(dev, 0xc0, C0, 6); + switch (sd->customid) { + case SN9C120: /*jfm ?? */ + reg_w(dev, 0xca, CA_sn9c120, 4); + break; + default: + reg_w(dev, 0xca, CA, 4); + break; + } + switch (sd->customid) { + case SN9C120: /*jfm ?? */ + case SN9C325: + reg_w(dev, 0xce, CE_sn9c325, 4); + break; + default: + reg_w(dev, 0xce, CE, 4); + /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ + break; + } + + /* here change size mode 0 -> VGA; 1 -> CIF */ + data = 0x40 | sn9c1xx[0x18] | (mode << 4); + reg_w(dev, 0x18, &data, 1); + + reg_w(dev, 0x100, qtable4, 0x40); + reg_w(dev, 0x140, qtable4 + 0x40, 0x40); + + data = sn9c1xx[0x18] | (mode << 4); + reg_w(dev, 0x18, &data, 1); + + reg_w(dev, 0x17, ®17, 1); + reg_w(dev, 0x01, ®1, 1); + setbrightness(gspca_dev); + setcontrast(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + static __u8 stophv7131[] = + { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; + static __u8 stopmi0360[] = + { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; + __u8 regF1; + __u8 data; + __u8 *sn9c1xx; + + data = 0x0b; + switch (sd->sensor) { + case SENSOR_HV7131R: + i2c_w8(dev, stophv7131); + data = 0x2b; + break; + case SENSOR_MI0360: + i2c_w8(dev, stopmi0360); + data = 0x29; + break; + case SENSOR_MO4000: + break; + case SENSOR_OV7648: + data = 0x29; + break; + default: +/* case SENSOR_OV7660: */ + break; + } + sn9c1xx = sn_tb[(int) sd->sensor]; + reg_w(dev, 0x01, &sn9c1xx[1], 1); + reg_w(dev, 0x17, &sn9c1xx[0x17], 1); + reg_w(dev, 0x01, &sn9c1xx[1], 1); + reg_w(dev, 0x01, &data, 1); + regF1 = 0x01; + reg_w(dev, 0xf1, ®F1, 1); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + /* Thanks S., without your advice, autobright should not work :) */ + int delta; + int expotimes = 0; + __u8 luma_mean = 130; + __u8 luma_delta = 20; + + delta = sd->avg_lum; + if (delta < luma_mean - luma_delta || + delta > luma_mean + luma_delta) { + switch (sd->sensor) { + case SENSOR_HV7131R: + expotimes = sd->exposure >> 8; + expotimes += (luma_mean - delta) >> 4; + if (expotimes < 0) + expotimes = 0; + sd->exposure = setexposure(gspca_dev, + (unsigned int) (expotimes << 8)); + break; + case SENSOR_MO4000: + case SENSOR_MI0360: + expotimes = sd->exposure; + expotimes += (luma_mean - delta) >> 6; + if (expotimes < 0) + expotimes = 0; + sd->exposure = setexposure(gspca_dev, + (unsigned int) expotimes); + setcolors(gspca_dev); + break; + } + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + int sof, avg_lum; + + sof = len - 64; + if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) { + + /* end of frame */ + gspca_frame_add(gspca_dev, LAST_PACKET, + frame, data, sof + 2); + if (sd->ag_cnt < 0) + return; + if (--sd->ag_cnt >= 0) + return; + sd->ag_cnt = AG_CNT_START; +/* w1 w2 w3 */ +/* w4 w5 w6 */ +/* w7 w8 */ +/* w4 */ + avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6; +/* w6 */ + avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6; +/* w2 */ + avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6; +/* w8 */ + avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6; +/* w5 */ + avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4; + avg_lum >>= 4; + sd->avg_lum = avg_lum; + PDEBUG(D_PACK, "mean lum %d", avg_lum); + setautogain(gspca_dev); + return; + } + if (gspca_dev->last_packet_type == LAST_PACKET) { + + /* put the JPEG 422 header */ + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21); + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static unsigned int getexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 hexpo, mexpo, lexpo; + __u8 expo[6]; + + switch (sd->sensor) { + case SENSOR_HV7131R: + /* read sensor exposure */ + i2c_r5(gspca_dev, 0x25, expo); + return (expo[0] << 16) | (expo[1] << 8) | expo[2]; + case SENSOR_MI0360: + /* read sensor exposure */ + i2c_r5(gspca_dev, 0x09, expo); + return (expo[0] << 8) | expo[1]; + case SENSOR_MO4000: + i2c_r5(gspca_dev, 0x0e, expo); + hexpo = 0; /* expo[1] & 0x07; */ + mexpo = 0x40; /* expo[2] &0xff; */ + lexpo = (expo[1] & 0x30) >> 4; + PDEBUG(D_CONF, "exposure %d", + (hexpo << 10) | (mexpo << 2) | lexpo); + return (hexpo << 10) | (mexpo << 2) | lexpo; + default: +/* case SENSOR_OV7660: */ + /* read sensor exposure */ + i2c_r5(gspca_dev, 0x04, expo); + hexpo = expo[3] & 0x2f; + lexpo = expo[0] & 0x02; + i2c_r5(gspca_dev, 0x08, expo); + mexpo = expo[2]; + return (hexpo << 10) | (mexpo << 2) | lexpo; + } +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* hardcoded registers seem not readable */ + switch (sd->sensor) { + case SENSOR_HV7131R: +/* sd->brightness = 0x7fff; */ + sd->brightness = getexposure(gspca_dev) >> 4; + break; + case SENSOR_MI0360: + sd->brightness = getexposure(gspca_dev) << 4; + break; + case SENSOR_MO4000: +/* sd->brightness = 0x1fff; */ + sd->brightness = getexposure(gspca_dev) << 4; + break; + } +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (val) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, + {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, + {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, + {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, + {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, + {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, + {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, + {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, + {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")}, + {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")}, + {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")}, + {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, + {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, + {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, + {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, + {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, + {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, + {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + info("v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + info("deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c new file mode 100644 index 000000000000..c0dd969a3106 --- /dev/null +++ b/drivers/media/video/gspca/spca500.c @@ -0,0 +1,1195 @@ +/* + * SPCA500 chip based cameras initialization data + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "spca500" + +#include "gspca.h" +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char packet[ISO_MAX_SIZE + 128]; + /* !! no more than 128 ff in an ISO packet */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + + char qindex; + char subtype; +#define AgfaCl20 0 +#define AiptekPocketDV 1 +#define BenqDC1016 2 +#define CreativePCCam300 3 +#define DLinkDSC350 4 +#define Gsmartmini 5 +#define IntelPocketPCCamera 6 +#define KodakEZ200 7 +#define LogitechClickSmart310 8 +#define LogitechClickSmart510 9 +#define LogitechTraveler 10 +#define MustekGsmart300 11 +#define Optimedia 12 +#define PalmPixDC85 13 +#define ToptroIndus 14 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x7f, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_JPEG, 176, 144, 1}, + {V4L2_PIX_FMT_JPEG, 352, 288, 0}, +}; + +/* Frame packet header offsets for the spca500 */ +#define SPCA500_OFFSET_PADDINGLB 2 +#define SPCA500_OFFSET_PADDINGHB 3 +#define SPCA500_OFFSET_MODE 4 +#define SPCA500_OFFSET_IMGWIDTH 5 +#define SPCA500_OFFSET_IMGHEIGHT 6 +#define SPCA500_OFFSET_IMGMODE 7 +#define SPCA500_OFFSET_QTBLINDEX 8 +#define SPCA500_OFFSET_FRAMSEQ 9 +#define SPCA500_OFFSET_CDSPINFO 10 +#define SPCA500_OFFSET_GPIO 11 +#define SPCA500_OFFSET_AUGPIO 12 +#define SPCA500_OFFSET_DATA 16 + + +static __u16 spca500_visual_defaults[][3] = { + {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, + * hue (H byte) = 0, + * saturation/hue enable, + * brightness/contrast enable. + */ + {0x00, 0x0000, 0x8167}, /* brightness = 0 */ + {0x00, 0x0020, 0x8168}, /* contrast = 0 */ + {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, + * hue (H byte) = 0, saturation/hue enable, + * brightness/contrast enable. + * was 0x0003, now 0x0000. + */ + {0x00, 0x0000, 0x816a}, /* hue (L byte) = 0 */ + {0x00, 0x0020, 0x8169}, /* saturation = 0x20 */ + {0x00, 0x0050, 0x8157}, /* edge gain high threshold */ + {0x00, 0x0030, 0x8158}, /* edge gain low threshold */ + {0x00, 0x0028, 0x8159}, /* edge bandwidth high threshold */ + {0x00, 0x000a, 0x815a}, /* edge bandwidth low threshold */ + {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ + {0x0c, 0x0004, 0x0000}, + /* set interface */ + + {0, 0, 0} +}; +static __u16 Clicksmart510_defaults[][3] = { + {0x00, 0x00, 0x8211}, + {0x00, 0x01, 0x82c0}, + {0x00, 0x10, 0x82cb}, + {0x00, 0x0f, 0x800d}, + {0x00, 0x82, 0x8225}, + {0x00, 0x21, 0x8228}, + {0x00, 0x00, 0x8203}, + {0x00, 0x00, 0x8204}, + {0x00, 0x08, 0x8205}, + {0x00, 0xf8, 0x8206}, + {0x00, 0x28, 0x8207}, + {0x00, 0xa0, 0x8208}, + {0x00, 0x08, 0x824a}, + {0x00, 0x08, 0x8214}, + {0x00, 0x80, 0x82c1}, + {0x00, 0x00, 0x82c2}, + {0x00, 0x00, 0x82ca}, + {0x00, 0x80, 0x82c1}, + {0x00, 0x04, 0x82c2}, + {0x00, 0x00, 0x82ca}, + {0x00, 0xfc, 0x8100}, + {0x00, 0xfc, 0x8105}, + {0x00, 0x30, 0x8101}, + {0x00, 0x00, 0x8102}, + {0x00, 0x00, 0x8103}, + {0x00, 0x66, 0x8107}, + {0x00, 0x00, 0x816b}, + {0x00, 0x00, 0x8155}, + {0x00, 0x01, 0x8156}, + {0x00, 0x60, 0x8157}, + {0x00, 0x40, 0x8158}, + {0x00, 0x0a, 0x8159}, + {0x00, 0x06, 0x815a}, + {0x00, 0x00, 0x813f}, + {0x00, 0x00, 0x8200}, + {0x00, 0x19, 0x8201}, + {0x00, 0x00, 0x82c1}, + {0x00, 0xa0, 0x82c2}, + {0x00, 0x00, 0x82ca}, + {0x00, 0x00, 0x8117}, + {0x00, 0x00, 0x8118}, + {0x00, 0x65, 0x8119}, + {0x00, 0x00, 0x811a}, + {0x00, 0x00, 0x811b}, + {0x00, 0x55, 0x811c}, + {0x00, 0x65, 0x811d}, + {0x00, 0x55, 0x811e}, + {0x00, 0x16, 0x811f}, + {0x00, 0x19, 0x8120}, + {0x00, 0x80, 0x8103}, + {0x00, 0x83, 0x816b}, + {0x00, 0x25, 0x8168}, + {0x00, 0x01, 0x820f}, + {0x00, 0xff, 0x8115}, + {0x00, 0x48, 0x8116}, + {0x00, 0x50, 0x8151}, + {0x00, 0x40, 0x8152}, + {0x00, 0x78, 0x8153}, + {0x00, 0x40, 0x8154}, + {0x00, 0x00, 0x8167}, + {0x00, 0x20, 0x8168}, + {0x00, 0x00, 0x816a}, + {0x00, 0x03, 0x816b}, + {0x00, 0x20, 0x8169}, + {0x00, 0x60, 0x8157}, + {0x00, 0x00, 0x8190}, + {0x00, 0x00, 0x81a1}, + {0x00, 0x00, 0x81b2}, + {0x00, 0x27, 0x8191}, + {0x00, 0x27, 0x81a2}, + {0x00, 0x27, 0x81b3}, + {0x00, 0x4b, 0x8192}, + {0x00, 0x4b, 0x81a3}, + {0x00, 0x4b, 0x81b4}, + {0x00, 0x66, 0x8193}, + {0x00, 0x66, 0x81a4}, + {0x00, 0x66, 0x81b5}, + {0x00, 0x79, 0x8194}, + {0x00, 0x79, 0x81a5}, + {0x00, 0x79, 0x81b6}, + {0x00, 0x8a, 0x8195}, + {0x00, 0x8a, 0x81a6}, + {0x00, 0x8a, 0x81b7}, + {0x00, 0x9b, 0x8196}, + {0x00, 0x9b, 0x81a7}, + {0x00, 0x9b, 0x81b8}, + {0x00, 0xa6, 0x8197}, + {0x00, 0xa6, 0x81a8}, + {0x00, 0xa6, 0x81b9}, + {0x00, 0xb2, 0x8198}, + {0x00, 0xb2, 0x81a9}, + {0x00, 0xb2, 0x81ba}, + {0x00, 0xbe, 0x8199}, + {0x00, 0xbe, 0x81aa}, + {0x00, 0xbe, 0x81bb}, + {0x00, 0xc8, 0x819a}, + {0x00, 0xc8, 0x81ab}, + {0x00, 0xc8, 0x81bc}, + {0x00, 0xd2, 0x819b}, + {0x00, 0xd2, 0x81ac}, + {0x00, 0xd2, 0x81bd}, + {0x00, 0xdb, 0x819c}, + {0x00, 0xdb, 0x81ad}, + {0x00, 0xdb, 0x81be}, + {0x00, 0xe4, 0x819d}, + {0x00, 0xe4, 0x81ae}, + {0x00, 0xe4, 0x81bf}, + {0x00, 0xed, 0x819e}, + {0x00, 0xed, 0x81af}, + {0x00, 0xed, 0x81c0}, + {0x00, 0xf7, 0x819f}, + {0x00, 0xf7, 0x81b0}, + {0x00, 0xf7, 0x81c1}, + {0x00, 0xff, 0x81a0}, + {0x00, 0xff, 0x81b1}, + {0x00, 0xff, 0x81c2}, + {0x00, 0x03, 0x8156}, + {0x00, 0x00, 0x8211}, + {0x00, 0x20, 0x8168}, + {0x00, 0x01, 0x8202}, + {0x00, 0x30, 0x8101}, + {0x00, 0x00, 0x8111}, + {0x00, 0x00, 0x8112}, + {0x00, 0x00, 0x8113}, + {0x00, 0x00, 0x8114}, + {} +}; + +static unsigned char qtable_creative_pccam[2][64] = { + { /* Q-table Y-components */ + 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, + 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, + 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, + 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, + 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, + 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, + 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, + 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, + { /* Q-table C-components */ + 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, + 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} +}; + +static unsigned char qtable_kodak_ez200[2][64] = { + { /* Q-table Y-components */ + 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, + 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, + 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06, + 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06, + 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08, + 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09, + 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a, + 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a}, + { /* Q-table C-components */ + 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a, + 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, + 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} +}; + +static unsigned char qtable_pocketdv[2][64] = { + { /* Q-table Y-components start registers 0x8800 */ + 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, + 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, + 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, + 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19, + 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f, + 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25, + 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, + 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, + }, + { /* Q-table C-components start registers 0x8840 */ + 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, + 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, + 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, + 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} +}; + +static void spca5xxRegRead(struct usb_device *dev, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, 500); +} + +static int reg_write(struct usb_device *dev, + __u16 req, __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x, 0x%x", + index, value, ret); + if (ret < 0) + PDEBUG(D_ERR, "reg write: error %d", ret); + return ret; +} + +/* returns: negative is error, pos or zero is data */ +static int reg_read(struct usb_device *dev, + __u16 req, /* bRequest */ + __u16 index, /* wIndex */ + __u16 length) /* wLength (1 or 2 only) */ +{ + int ret; + __u8 buf[2]; + + buf[1] = 0; + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, + buf, length, + 500); /* timeout */ + if (ret < 0) { + PDEBUG(D_ERR, "reg_read err %d", ret); + return -1; + } + return (buf[1] << 8) + buf[0]; +} + +/* + * Simple function to wait for a given 8-bit value to be returned from + * a reg_read call. + * Returns: negative is error or timeout, zero is success. + */ +static int reg_readwait(struct usb_device *dev, + __u16 reg, __u16 index, __u16 value) +{ + int ret, cnt = 20; + + while (--cnt > 0) { + ret = reg_read(dev, reg, index, 1); + if (ret == value) + return 0; + msleep(50); + } + return -EIO; +} + +static int write_vector(struct gspca_dev *gspca_dev, + __u16 data[][3]) +{ + struct usb_device *dev = gspca_dev->dev; + int ret, i = 0; + + while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { + ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + if (ret < 0) + return ret; + i++; + } + return 0; +} + +static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, + unsigned int request, + unsigned int ybase, + unsigned int cbase, + unsigned char qtable[2][64]) +{ + struct usb_device *dev = gspca_dev->dev; + int i, err; + + /* loop over y components */ + for (i = 0; i < 64; i++) { + err = reg_write(dev, request, ybase + i, qtable[0][i]); + if (err < 0) + return err; + } + + /* loop over c components */ + for (i = 0; i < 64; i++) { + err = reg_write(dev, request, cbase + i, qtable[1][i]); + if (err < 0) + return err; + } + return 0; +} + +static void spca500_ping310(struct gspca_dev *gspca_dev) +{ + __u8 Data[2]; + + spca5xxRegRead(gspca_dev->dev, 0x0d04, Data, 2); + PDEBUG(D_PACK, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", + Data[0], Data[1]); +} + +static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) +{ + __u8 Data[2]; + + spca5xxRegRead(gspca_dev->dev, 0x0d05, Data, 2); + PDEBUG(D_PACK, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", Data[0], + Data[1]); + reg_write(gspca_dev->dev, 0x00, 0x8167, 0x5a); + spca500_ping310(gspca_dev); + + reg_write(gspca_dev->dev, 0x00, 0x8168, 0x22); + reg_write(gspca_dev->dev, 0x00, 0x816a, 0xc0); + reg_write(gspca_dev->dev, 0x00, 0x816b, 0x0b); + reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); + reg_write(gspca_dev->dev, 0x00, 0x8157, 0x5b); + reg_write(gspca_dev->dev, 0x00, 0x8158, 0x5b); + reg_write(gspca_dev->dev, 0x00, 0x813f, 0x03); + reg_write(gspca_dev->dev, 0x00, 0x8151, 0x4a); + reg_write(gspca_dev->dev, 0x00, 0x8153, 0x78); + reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x04); + /* 00 for adjust shutter */ + reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); + reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); + reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x02); +} + +static void spca500_setmode(struct gspca_dev *gspca_dev, + __u8 xmult, __u8 ymult) +{ + int mode; + + /* set x multiplier */ + reg_write(gspca_dev->dev, 0, 0x8001, xmult); + + /* set y multiplier */ + reg_write(gspca_dev->dev, 0, 0x8002, ymult); + + /* use compressed mode, VGA, with mode specific subsample */ + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + reg_write(gspca_dev->dev, 0, 0x8003, mode << 4); +} + +static int spca500_full_reset(struct gspca_dev *gspca_dev) +{ + int err; + + /* send the reset command */ + err = reg_write(gspca_dev->dev, 0xe0, 0x0001, 0x0000); + if (err < 0) + return err; + + /* wait for the reset to complete */ + err = reg_readwait(gspca_dev->dev, 0x06, 0x0000, 0x0000); + if (err < 0) + return err; + err = reg_write(gspca_dev->dev, 0xe0, 0x0000, 0x0000); + if (err < 0) + return err; + err = reg_readwait(gspca_dev->dev, 0x06, 0, 0); + if (err < 0) { + PDEBUG(D_ERR, "reg_readwait() failed"); + return err; + } + /* all ok */ + return 0; +} + +/* Synchro the Bridge with sensor */ +/* Maybe that will work on all spca500 chip */ +/* because i only own a clicksmart310 try for that chip */ +/* using spca50x_set_packet_size() cause an Ooops here */ +/* usb_set_interface from kernel 2.6.x clear all the urb stuff */ +/* up-port the same feature as in 2.4.x kernel */ +static int spca500_synch310(struct gspca_dev *gspca_dev) +{ + __u8 Data; + + if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { + PDEBUG(D_ERR, "Set packet size: set interface error"); + goto error; + } + spca500_ping310(gspca_dev); + + spca5xxRegRead(gspca_dev->dev, 0x0d00, &Data, 1); + + /* need alt setting here */ + PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); + + /* Windoze use pipe with altsetting 6 why 7 here */ + if (usb_set_interface(gspca_dev->dev, + gspca_dev->iface, + gspca_dev->alt) < 0) { + PDEBUG(D_ERR, "Set packet size: set interface error"); + goto error; + } + return 0; +error: + return -EBUSY; +} + +static void spca500_reinit(struct gspca_dev *gspca_dev) +{ + int err; + __u8 Data; + + /* some unknow command from Aiptek pocket dv and family300 */ + + reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); + reg_write(gspca_dev->dev, 0x00, 0x0d03, 0x00); + reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); + + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + + err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, + qtable_pocketdv); + if (err < 0) + PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); + + /* set qtable index */ + reg_write(gspca_dev->dev, 0x00, 0x8880, 2); + /* family cam Quicksmart stuff */ + reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + /* Set agc transfer: synced inbetween frames */ + reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); + /* Init SDRAM - needed for SDRAM access */ + reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + /*Start init sequence or stream */ + + reg_write(gspca_dev->dev, 0, 0x8003, 0x00); + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + msleep(2000); + if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x040a: /* Kodak cameras */ +/* switch (product) { */ +/* case 0x0300: */ + sd->subtype = KodakEZ200; +/* break; */ +/* } */ + break; + case 0x041e: /* Creative cameras */ +/* switch (product) { */ +/* case 0x400a: */ + sd->subtype = CreativePCCam300; +/* break; */ +/* } */ + break; + case 0x046d: /* Logitech Labtec */ + switch (product) { + case 0x0890: + sd->subtype = LogitechTraveler; + break; + case 0x0900: + sd->subtype = LogitechClickSmart310; + break; + case 0x0901: + sd->subtype = LogitechClickSmart510; + break; + } + break; + case 0x04a5: /* Benq */ +/* switch (product) { */ +/* case 0x300c: */ + sd->subtype = BenqDC1016; +/* break; */ +/* } */ + break; + case 0x04fc: /* SunPlus */ +/* switch (product) { */ +/* case 0x7333: */ + sd->subtype = PalmPixDC85; +/* break; */ +/* } */ + break; + case 0x055f: /* Mustek cameras */ + switch (product) { + case 0xc200: + sd->subtype = MustekGsmart300; + break; + case 0xc220: + sd->subtype = Gsmartmini; + break; + } + break; + case 0x06bd: /* Agfa Cl20 */ +/* switch (product) { */ +/* case 0x0404: */ + sd->subtype = AgfaCl20; +/* break; */ +/* } */ + break; + case 0x06be: /* Optimedia */ +/* switch (product) { */ +/* case 0x0800: */ + sd->subtype = Optimedia; +/* break; */ +/* } */ + break; + case 0x084d: /* D-Link / Minton */ +/* switch (product) { */ +/* case 0x0003: * DSC-350 / S-Cam F5 */ + sd->subtype = DLinkDSC350; +/* break; */ +/* } */ + break; + case 0x08ca: /* Aiptek */ +/* switch (product) { */ +/* case 0x0103: */ + sd->subtype = AiptekPocketDV; +/* break; */ +/* } */ + break; + case 0x2899: /* ToptroIndustrial */ +/* switch (product) { */ +/* case 0x012c: */ + sd->subtype = ToptroIndus; +/* break; */ +/* } */ + break; + case 0x8086: /* Intel */ +/* switch (product) { */ +/* case 0x0630: * Pocket PC Camera */ + sd->subtype = IntelPocketPCCamera; +/* break; */ +/* } */ + break; + } + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + if (sd->subtype != LogitechClickSmart310) { + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + } else { + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + } + sd->qindex = 5; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* initialisation of spca500 based cameras is deferred */ + PDEBUG(D_STREAM, "SPCA500 init"); + if (sd->subtype == LogitechClickSmart310) + spca500_clksmart310_init(gspca_dev); +/* else + spca500_initialise(gspca_dev); */ + PDEBUG(D_STREAM, "SPCA500 init done"); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int err; + __u8 Data; + __u8 xmult, ymult; + + if (sd->subtype == LogitechClickSmart310) { + xmult = 0x16; + ymult = 0x12; + } else { + xmult = 0x28; + ymult = 0x1e; + } + + /* is there a sensor here ? */ + spca5xxRegRead(gspca_dev->dev, 0x8a04, &Data, 1); + PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data); + PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X", + gspca_dev->curr_mode, xmult, ymult); + + /* setup qtable */ + switch (sd->subtype) { + case LogitechClickSmart310: + spca500_setmode(gspca_dev, xmult, ymult); + + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, 0x8840, + qtable_creative_pccam); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + /* Init SDRAM - needed for SDRAM access */ + reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + msleep(500); + if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_readwait() failed"); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + + spca500_synch310(gspca_dev); + + write_vector(gspca_dev, spca500_visual_defaults); + spca500_setmode(gspca_dev, xmult, ymult); + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + PDEBUG(D_ERR, "failed to enable drop packet"); + reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, 0x8840, + qtable_creative_pccam); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + + /* Init SDRAM - needed for SDRAM access */ + reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + + if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_readwait() failed"); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + break; + case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ + case IntelPocketPCCamera: /* FIXME: Temporary fix for + * Intel Pocket PC Camera + * - NWG (Sat 29th March 2003) */ + + /* do a full reset */ + if ((err = spca500_full_reset(gspca_dev)) < 0) + PDEBUG(D_ERR, "spca500_full_reset failed"); + + /* enable drop packet */ + err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + if (err < 0) + PDEBUG(D_ERR, "failed to enable drop packet"); + reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, 0x8840, + qtable_creative_pccam); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + + spca500_setmode(gspca_dev, xmult, ymult); + reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + + if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_readwait() failed"); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + + /* write_vector(gspca_dev, spca500_visual_defaults); */ + break; + case KodakEZ200: /* Kodak EZ200 */ + + /* do a full reset */ + err = spca500_full_reset(gspca_dev); + if (err < 0) + PDEBUG(D_ERR, "spca500_full_reset failed"); + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_write(gspca_dev->dev, 0x00, 0x8880, 0); + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, 0x8840, + qtable_kodak_ez200); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + spca500_setmode(gspca_dev, xmult, ymult); + + reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + + if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_readwait() failed"); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + + /* write_vector(gspca_dev, spca500_visual_defaults); */ + break; + + case BenqDC1016: + case DLinkDSC350: /* FamilyCam 300 */ + case AiptekPocketDV: /* Aiptek PocketDV */ + case Gsmartmini: /*Mustek Gsmart Mini */ + case MustekGsmart300: /* Mustek Gsmart 300 */ + case PalmPixDC85: + case Optimedia: + case ToptroIndus: + case AgfaCl20: + spca500_reinit(gspca_dev); + reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, 0x8840, qtable_pocketdv); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + reg_write(gspca_dev->dev, 0x00, 0x8880, 2); + + /* familycam Quicksmart pocketDV stuff */ + reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + /* Set agc transfer: synced inbetween frames */ + reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); + /* Init SDRAM - needed for SDRAM access */ + reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + + spca500_setmode(gspca_dev,xmult,ymult); + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + + reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + break; + case LogitechTraveler: + case LogitechClickSmart510: + reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); + /* enable drop packet */ + reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + + err = spca50x_setup_qtable(gspca_dev, + 0x00, 0x8800, + 0x8840, qtable_creative_pccam); + if (err < 0) + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + /* Init SDRAM - needed for SDRAM access */ + reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + + spca500_setmode(gspca_dev, xmult, ymult); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); + + spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); + reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + write_vector(gspca_dev, Clicksmart510_defaults); + break; + } +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + __u8 data = 0; + + reg_write(gspca_dev->dev, 0, 0x8003, 0x00); + + /* switch to video camera mode */ + reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1); + PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + int i; + unsigned char *s, *d; + static unsigned char ffd9[] = {0xff, 0xd9}; + +/* frames are jpeg 4.1.1 without 0xff escape */ + if (data[0] == 0xff) { + if (data[1] != 0x01) { /* drop packet */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + ffd9, 2); + + /* put the JPEG header in the new frame */ + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x22); + + data += SPCA500_OFFSET_DATA; + len -= SPCA500_OFFSET_DATA; + } else { + data += 1; + len -= 1; + } + + /* add 0x00 after 0xff */ + for (i = len; --i >= 0; ) + if (data[i] == 0xff) + break; + if (i < 0) { /* no 0xff */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + return; + } + s = data; + d = sd->packet; + for (i = 0; i < len; i++) { + *d++ = *s++; + if (s[-1] == 0xff) + *d++ = 0x00; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + sd->packet, d - sd->packet); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, 0x00, 0x8167, + (__u8) (sd->brightness - 128)); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2); +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2; +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2); +} + +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2; +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcolors(gspca_dev); + *val = sd->colors; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, + {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, + {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, + {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")}, + {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")}, + {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")}, + {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")}, + {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")}, + {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")}, + {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")}, + {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")}, + {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")}, + {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")}, + {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")}, + {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c new file mode 100644 index 000000000000..c6468cf3506a --- /dev/null +++ b/drivers/media/video/gspca/spca501.c @@ -0,0 +1,2219 @@ +/* + * SPCA501 chip based cameras initialization data + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "spca501" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned short contrast; + __u8 brightness; + __u8 colors; + + char subtype; +#define Arowana300KCMOSCamera 0 +#define IntelCreateAndShare 1 +#define KodakDVC325 2 +#define MystFromOriUnknownCamera 3 +#define SmileIntlCamera 4 +#define ThreeComHomeConnectLite 5 +#define ViewQuestM318B 6 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define MY_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 127, + .step = 1, + .default_value = 63, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define MY_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xffff, + .step = 1, + .default_value = 0xaa00, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define MY_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 63, + .step = 1, + .default_value = 31, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_SPCA501, 160, 120, 2}, + {V4L2_PIX_FMT_SPCA501, 320, 240, 1}, + {V4L2_PIX_FMT_SPCA501, 640, 480, 0}, +}; + +#define SPCA50X_REG_USB 0x2 /* spca505 501 */ +/* + * Data to initialize a SPCA501. From a capture file provided by Bill Roehl + * With SPCA501 chip description + */ +#define CCDSP_SET /* set CCDSP parameters */ +#define TG_SET /* set time generator set */ +#undef DSPWIN_SET /* set DSP windows parameters */ +#undef ALTER_GAMA /* Set alternate set to YUV transform coeffs. */ +#define SPCA501_SNAPBIT 0x80 +#define SPCA501_SNAPCTRL 0x10 +/* Frame packet header offsets for the spca501 */ +#define SPCA501_OFFSET_GPIO 1 +#define SPCA501_OFFSET_TYPE 2 +#define SPCA501_OFFSET_TURN3A 3 +#define SPCA501_OFFSET_FRAMSEQ 4 +#define SPCA501_OFFSET_COMPRESS 5 +#define SPCA501_OFFSET_QUANT 6 +#define SPCA501_OFFSET_QUANT2 7 +#define SPCA501_OFFSET_DATA 8 + +#define SPCA501_PROP_COMP_ENABLE(d) ((d) & 1) +#define SPCA501_PROP_SNAP(d) ((d) & 0x40) +#define SPCA501_PROP_SNAP_CTRL(d) ((d) & 0x10) +#define SPCA501_PROP_COMP_THRESH(d) (((d) & 0x0e) >> 1) +#define SPCA501_PROP_COMP_QUANT(d) (((d) & 0x70) >> 4) + +/* SPCA501 CCDSP control */ +#define SPCA501_REG_CCDSP 0x01 +/* SPCA501 control/status registers */ +#define SPCA501_REG_CTLRL 0x02 + +/* registers for color correction and YUV transformation */ +#define SPCA501_A11 0x08 +#define SPCA501_A12 0x09 +#define SPCA501_A13 0x0A +#define SPCA501_A21 0x0B +#define SPCA501_A22 0x0C +#define SPCA501_A23 0x0D +#define SPCA501_A31 0x0E +#define SPCA501_A32 0x0F +#define SPCA501_A33 0x10 + +/* Data for video camera initialization before capturing */ +static __u16 spca501_open_data[][3] = { + /* bmRequest,value,index */ + + {0x2, 0x50, 0x00}, /* C/S enable soft reset */ + {0x2, 0x40, 0x00}, /* C/S disable soft reset */ + {0x2, 0x02, 0x05}, /* C/S general purpose I/O data */ + {0x2, 0x03, 0x05}, /* C/S general purpose I/O data */ + +#ifdef CCDSP_SET + {0x1, 0x38, 0x01}, /* CCDSP options */ + {0x1, 0x05, 0x02}, /* CCDSP Optical black level for user settings */ + {0x1, 0xC0, 0x03}, /* CCDSP Optical black settings */ + + {0x1, 0x67, 0x07}, + {0x1, 0x63, 0x3f}, /* CCDSP CCD gamma enable */ + {0x1, 0x03, 0x56}, /* Add gamma correction */ + + {0x1, 0xFF, 0x15}, /* CCDSP High luminance for white balance */ + {0x1, 0x01, 0x16}, /* CCDSP Low luminance for white balance */ + +/* Color correction and RGB-to-YUV transformation coefficients changing */ +#ifdef ALTER_GAMA + {0x0, 0x00, 0x08}, /* A11 */ + {0x0, 0x00, 0x09}, /* A12 */ + {0x0, 0x90, 0x0A}, /* A13 */ + {0x0, 0x12, 0x0B}, /* A21 */ + {0x0, 0x00, 0x0C}, /* A22 */ + {0x0, 0x00, 0x0D}, /* A23 */ + {0x0, 0x00, 0x0E}, /* A31 */ + {0x0, 0x02, 0x0F}, /* A32 */ + {0x0, 0x00, 0x10}, /* A33 */ +#else + {0x1, 0x2a, 0x08}, /* A11 0x31 */ + {0x1, 0xf8, 0x09}, /* A12 f8 */ + {0x1, 0xf8, 0x0A}, /* A13 f8 */ + {0x1, 0xf8, 0x0B}, /* A21 f8 */ + {0x1, 0x14, 0x0C}, /* A22 0x14 */ + {0x1, 0xf8, 0x0D}, /* A23 f8 */ + {0x1, 0xf8, 0x0E}, /* A31 f8 */ + {0x1, 0xf8, 0x0F}, /* A32 f8 */ + {0x1, 0x20, 0x10}, /* A33 0x20 */ +#endif + {0x1, 0x00, 0x11}, /* R offset */ + {0x1, 0x00, 0x12}, /* G offset */ + {0x1, 0x00, 0x13}, /* B offset */ + {0x1, 0x00, 0x14}, /* GB offset */ + +#endif + +#ifdef TG_SET + /* Time generator manipulations */ + {0x0, 0xfc, 0x0}, /* Set up high bits of shutter speed */ + {0x0, 0x01, 0x1}, /* Set up low bits of shutter speed */ + + {0x0, 0xe4, 0x04}, /* DCLK*2 clock phase adjustment */ + {0x0, 0x08, 0x05}, /* ADCK phase adjustment, inv. ext. VB */ + {0x0, 0x03, 0x06}, /* FR phase adjustment */ + {0x0, 0x01, 0x07}, /* FCDS phase adjustment */ + {0x0, 0x39, 0x08}, /* FS phase adjustment */ + {0x0, 0x88, 0x0a}, /* FH1 phase and delay adjustment */ + {0x0, 0x03, 0x0f}, /* pixel identification */ + {0x0, 0x00, 0x11}, /* clock source selection (default) */ + + /*VERY strange manipulations with + * select DMCLP or OBPX to be ADCLP output (0x0C) + * OPB always toggle or not (0x0D) but they allow + * us to set up brightness + */ + {0x0, 0x01, 0x0c}, + {0x0, 0xe0, 0x0d}, + /* Done */ +#endif + +#ifdef DSPWIN_SET + {0x1, 0xa0, 0x01}, /* Setting image processing parameters */ + {0x1, 0x1c, 0x17}, /* Changing Windows positions X1 */ + {0x1, 0xe2, 0x19}, /* X2 */ + {0x1, 0x1c, 0x1b}, /* X3 */ + {0x1, 0xe2, 0x1d}, /* X4 */ + {0x1, 0x5f, 0x1f}, /* X5 */ + {0x1, 0x32, 0x20}, /* Y5 */ + {0x1, 0x01, 0x10}, /* Changing A33 */ +#endif + + {0x2, 0x204a, 0x07},/* Setting video compression & resolution 160x120 */ + {0x2, 0x94, 0x06}, /* Setting video no compression */ + {} +}; + +/* + The SPCAxxx docs from Sunplus document these values + in tables, one table per register number. In the data + below, dmRequest is the register number, index is the Addr, + and value is a combination of Bit values. + Bit Value (hex) + 0 01 + 1 02 + 2 04 + 3 08 + 4 10 + 5 20 + 6 40 + 7 80 + */ + +/* Data for chip initialization (set default values) */ +static __u16 spca501_init_data[][3] = { + /* Set all the values to powerup defaults */ + /* bmRequest,value,index */ + {0x0, 0xAA, 0x00}, + {0x0, 0x02, 0x01}, + {0x0, 0x01, 0x02}, + {0x0, 0x02, 0x03}, + {0x0, 0xCE, 0x04}, + {0x0, 0x00, 0x05}, + {0x0, 0x00, 0x06}, + {0x0, 0x00, 0x07}, + {0x0, 0x00, 0x08}, + {0x0, 0x00, 0x09}, + {0x0, 0x90, 0x0A}, + {0x0, 0x12, 0x0B}, + {0x0, 0x00, 0x0C}, + {0x0, 0x00, 0x0D}, + {0x0, 0x00, 0x0E}, + {0x0, 0x02, 0x0F}, + {0x0, 0x00, 0x10}, + {0x0, 0x00, 0x11}, + {0x0, 0x00, 0x12}, + {0x0, 0x00, 0x13}, + {0x0, 0x00, 0x14}, + {0x0, 0x00, 0x15}, + {0x0, 0x00, 0x16}, + {0x0, 0x00, 0x17}, + {0x0, 0x00, 0x18}, + {0x0, 0x00, 0x19}, + {0x0, 0x00, 0x1A}, + {0x0, 0x00, 0x1B}, + {0x0, 0x00, 0x1C}, + {0x0, 0x00, 0x1D}, + {0x0, 0x00, 0x1E}, + {0x0, 0x00, 0x1F}, + {0x0, 0x00, 0x20}, + {0x0, 0x00, 0x21}, + {0x0, 0x00, 0x22}, + {0x0, 0x00, 0x23}, + {0x0, 0x00, 0x24}, + {0x0, 0x00, 0x25}, + {0x0, 0x00, 0x26}, + {0x0, 0x00, 0x27}, + {0x0, 0x00, 0x28}, + {0x0, 0x00, 0x29}, + {0x0, 0x00, 0x2A}, + {0x0, 0x00, 0x2B}, + {0x0, 0x00, 0x2C}, + {0x0, 0x00, 0x2D}, + {0x0, 0x00, 0x2E}, + {0x0, 0x00, 0x2F}, + {0x0, 0x00, 0x30}, + {0x0, 0x00, 0x31}, + {0x0, 0x00, 0x32}, + {0x0, 0x00, 0x33}, + {0x0, 0x00, 0x34}, + {0x0, 0x00, 0x35}, + {0x0, 0x00, 0x36}, + {0x0, 0x00, 0x37}, + {0x0, 0x00, 0x38}, + {0x0, 0x00, 0x39}, + {0x0, 0x00, 0x3A}, + {0x0, 0x00, 0x3B}, + {0x0, 0x00, 0x3C}, + {0x0, 0x00, 0x3D}, + {0x0, 0x00, 0x3E}, + {0x0, 0x00, 0x3F}, + {0x0, 0x00, 0x40}, + {0x0, 0x00, 0x41}, + {0x0, 0x00, 0x42}, + {0x0, 0x00, 0x43}, + {0x0, 0x00, 0x44}, + {0x0, 0x00, 0x45}, + {0x0, 0x00, 0x46}, + {0x0, 0x00, 0x47}, + {0x0, 0x00, 0x48}, + {0x0, 0x00, 0x49}, + {0x0, 0x00, 0x4A}, + {0x0, 0x00, 0x4B}, + {0x0, 0x00, 0x4C}, + {0x0, 0x00, 0x4D}, + {0x0, 0x00, 0x4E}, + {0x0, 0x00, 0x4F}, + {0x0, 0x00, 0x50}, + {0x0, 0x00, 0x51}, + {0x0, 0x00, 0x52}, + {0x0, 0x00, 0x53}, + {0x0, 0x00, 0x54}, + {0x0, 0x00, 0x55}, + {0x0, 0x00, 0x56}, + {0x0, 0x00, 0x57}, + {0x0, 0x00, 0x58}, + {0x0, 0x00, 0x59}, + {0x0, 0x00, 0x5A}, + {0x0, 0x00, 0x5B}, + {0x0, 0x00, 0x5C}, + {0x0, 0x00, 0x5D}, + {0x0, 0x00, 0x5E}, + {0x0, 0x00, 0x5F}, + {0x0, 0x00, 0x60}, + {0x0, 0x00, 0x61}, + {0x0, 0x00, 0x62}, + {0x0, 0x00, 0x63}, + {0x0, 0x00, 0x64}, + {0x0, 0x00, 0x65}, + {0x0, 0x00, 0x66}, + {0x0, 0x00, 0x67}, + {0x0, 0x00, 0x68}, + {0x0, 0x00, 0x69}, + {0x0, 0x00, 0x6A}, + {0x0, 0x00, 0x6B}, + {0x0, 0x00, 0x6C}, + {0x0, 0x00, 0x6D}, + {0x0, 0x00, 0x6E}, + {0x0, 0x00, 0x6F}, + {0x0, 0x00, 0x70}, + {0x0, 0x00, 0x71}, + {0x0, 0x00, 0x72}, + {0x0, 0x00, 0x73}, + {0x0, 0x00, 0x74}, + {0x0, 0x00, 0x75}, + {0x0, 0x00, 0x76}, + {0x0, 0x00, 0x77}, + {0x0, 0x00, 0x78}, + {0x0, 0x00, 0x79}, + {0x0, 0x00, 0x7A}, + {0x0, 0x00, 0x7B}, + {0x0, 0x00, 0x7C}, + {0x0, 0x00, 0x7D}, + {0x0, 0x00, 0x7E}, + {0x0, 0x00, 0x7F}, + {0x0, 0x00, 0x80}, + {0x0, 0x00, 0x81}, + {0x0, 0x00, 0x82}, + {0x0, 0x00, 0x83}, + {0x0, 0x00, 0x84}, + {0x0, 0x00, 0x85}, + {0x0, 0x00, 0x86}, + {0x0, 0x00, 0x87}, + {0x0, 0x00, 0x88}, + {0x0, 0x00, 0x89}, + {0x0, 0x00, 0x8A}, + {0x0, 0x00, 0x8B}, + {0x0, 0x00, 0x8C}, + {0x0, 0x00, 0x8D}, + {0x0, 0x00, 0x8E}, + {0x0, 0x00, 0x8F}, + {0x0, 0x00, 0x90}, + {0x0, 0x00, 0x91}, + {0x0, 0x00, 0x92}, + {0x0, 0x00, 0x93}, + {0x0, 0x00, 0x94}, + {0x0, 0x00, 0x95}, + {0x0, 0x00, 0x96}, + {0x0, 0x00, 0x97}, + {0x0, 0x00, 0x98}, + {0x0, 0x00, 0x99}, + {0x0, 0x00, 0x9A}, + {0x0, 0x00, 0x9B}, + {0x0, 0x00, 0x9C}, + {0x0, 0x00, 0x9D}, + {0x0, 0x00, 0x9E}, + {0x0, 0x00, 0x9F}, + {0x0, 0x00, 0xA0}, + {0x0, 0x00, 0xA1}, + {0x0, 0x00, 0xA2}, + {0x0, 0x00, 0xA3}, + {0x0, 0x00, 0xA4}, + {0x0, 0x00, 0xA5}, + {0x0, 0x00, 0xA6}, + {0x0, 0x00, 0xA7}, + {0x0, 0x00, 0xA8}, + {0x0, 0x00, 0xA9}, + {0x0, 0x00, 0xAA}, + {0x0, 0x00, 0xAB}, + {0x0, 0x00, 0xAC}, + {0x0, 0x00, 0xAD}, + {0x0, 0x00, 0xAE}, + {0x0, 0x00, 0xAF}, + {0x0, 0x00, 0xB0}, + {0x0, 0x00, 0xB1}, + {0x0, 0x00, 0xB2}, + {0x0, 0x00, 0xB3}, + {0x0, 0x00, 0xB4}, + {0x0, 0x00, 0xB5}, + {0x0, 0x00, 0xB6}, + {0x0, 0x00, 0xB7}, + {0x0, 0x00, 0xB8}, + {0x0, 0x00, 0xB9}, + {0x0, 0x00, 0xBA}, + {0x0, 0x00, 0xBB}, + {0x0, 0x00, 0xBC}, + {0x0, 0x00, 0xBD}, + {0x0, 0x00, 0xBE}, + {0x0, 0x00, 0xBF}, + {0x0, 0x00, 0xC0}, + {0x0, 0x00, 0xC1}, + {0x0, 0x00, 0xC2}, + {0x0, 0x00, 0xC3}, + {0x0, 0x00, 0xC4}, + {0x0, 0x00, 0xC5}, + {0x0, 0x00, 0xC6}, + {0x0, 0x00, 0xC7}, + {0x0, 0x00, 0xC8}, + {0x0, 0x00, 0xC9}, + {0x0, 0x00, 0xCA}, + {0x0, 0x00, 0xCB}, + {0x0, 0x00, 0xCC}, + {0x1, 0xF4, 0x00}, + {0x1, 0x38, 0x01}, + {0x1, 0x40, 0x02}, + {0x1, 0x0A, 0x03}, + {0x1, 0x40, 0x04}, + {0x1, 0x40, 0x05}, + {0x1, 0x40, 0x06}, + {0x1, 0x67, 0x07}, + {0x1, 0x31, 0x08}, + {0x1, 0x00, 0x09}, + {0x1, 0x00, 0x0A}, + {0x1, 0x00, 0x0B}, + {0x1, 0x14, 0x0C}, + {0x1, 0x00, 0x0D}, + {0x1, 0x00, 0x0E}, + {0x1, 0x00, 0x0F}, + {0x1, 0x1E, 0x10}, + {0x1, 0x00, 0x11}, + {0x1, 0x00, 0x12}, + {0x1, 0x00, 0x13}, + {0x1, 0x00, 0x14}, + {0x1, 0xFF, 0x15}, + {0x1, 0x01, 0x16}, + {0x1, 0x32, 0x17}, + {0x1, 0x23, 0x18}, + {0x1, 0xCE, 0x19}, + {0x1, 0x23, 0x1A}, + {0x1, 0x32, 0x1B}, + {0x1, 0x8D, 0x1C}, + {0x1, 0xCE, 0x1D}, + {0x1, 0x8D, 0x1E}, + {0x1, 0x00, 0x1F}, + {0x1, 0x00, 0x20}, + {0x1, 0xFF, 0x3E}, + {0x1, 0x02, 0x3F}, + {0x1, 0x00, 0x40}, + {0x1, 0x00, 0x41}, + {0x1, 0x00, 0x42}, + {0x1, 0x00, 0x43}, + {0x1, 0x00, 0x44}, + {0x1, 0x00, 0x45}, + {0x1, 0x00, 0x46}, + {0x1, 0x00, 0x47}, + {0x1, 0x00, 0x48}, + {0x1, 0x00, 0x49}, + {0x1, 0x00, 0x4A}, + {0x1, 0x00, 0x4B}, + {0x1, 0x00, 0x4C}, + {0x1, 0x00, 0x4D}, + {0x1, 0x00, 0x4E}, + {0x1, 0x00, 0x4F}, + {0x1, 0x00, 0x50}, + {0x1, 0x00, 0x51}, + {0x1, 0x00, 0x52}, + {0x1, 0x00, 0x53}, + {0x1, 0x00, 0x54}, + {0x1, 0x00, 0x55}, + {0x1, 0x00, 0x56}, + {0x1, 0x00, 0x57}, + {0x1, 0x00, 0x58}, + {0x1, 0x00, 0x59}, + {0x1, 0x00, 0x5A}, + {0x2, 0x03, 0x00}, + {0x2, 0x00, 0x01}, + {0x2, 0x00, 0x05}, + {0x2, 0x00, 0x06}, + {0x2, 0x00, 0x07}, + {0x2, 0x00, 0x10}, + {0x2, 0x00, 0x11}, + /* Strange - looks like the 501 driver doesn't do anything + * at insert time except read the EEPROM + */ + {} +}; + +/* Data for video camera init before capture. + * Capture and decoding by Colin Peart. + * This is is for the 3com HomeConnect Lite which is spca501a based. + */ +static __u16 spca501_3com_open_data[][3] = { + /* bmRequest,value,index */ + {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */ + {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */ + {0x2, 0x0002, 0x0005}, /* C/S GPIO */ + {0x2, 0x0003, 0x0005}, /* C/S GPIO */ + +#ifdef CCDSP_SET + {0x1, 0x0020, 0x0001}, /* CCDSP Options */ + + {0x1, 0x0020, 0x0002}, /* CCDSP Black Level */ + {0x1, 0x006e, 0x0007}, /* CCDSP Gamma options */ + {0x1, 0x0090, 0x0015}, /* CCDSP Luminance Low */ + {0x1, 0x00ff, 0x0016}, /* CCDSP Luminance High */ + {0x1, 0x0003, 0x003F}, /* CCDSP Gamma correction toggle */ + +#ifdef ALTER_GAMMA + {0x1, 0x0010, 0x0008}, /* CCDSP YUV A11 */ + {0x1, 0x0000, 0x0009}, /* CCDSP YUV A12 */ + {0x1, 0x0000, 0x000a}, /* CCDSP YUV A13 */ + {0x1, 0x0000, 0x000b}, /* CCDSP YUV A21 */ + {0x1, 0x0010, 0x000c}, /* CCDSP YUV A22 */ + {0x1, 0x0000, 0x000d}, /* CCDSP YUV A23 */ + {0x1, 0x0000, 0x000e}, /* CCDSP YUV A31 */ + {0x1, 0x0000, 0x000f}, /* CCDSP YUV A32 */ + {0x1, 0x0010, 0x0010}, /* CCDSP YUV A33 */ + {0x1, 0x0000, 0x0011}, /* CCDSP R Offset */ + {0x1, 0x0000, 0x0012}, /* CCDSP G Offset */ + {0x1, 0x0001, 0x0013}, /* CCDSP B Offset */ + {0x1, 0x0001, 0x0014}, /* CCDSP BG Offset */ + {0x1, 0x003f, 0x00C1}, /* CCDSP Gamma Correction Enable */ +#endif +#endif + +#ifdef TG_SET + {0x0, 0x00fc, 0x0000}, /* TG Shutter Speed High Bits */ + {0x0, 0x0000, 0x0001}, /* TG Shutter Speed Low Bits */ + {0x0, 0x00e4, 0x0004}, /* TG DCLK*2 Adjust */ + {0x0, 0x0008, 0x0005}, /* TG ADCK Adjust */ + {0x0, 0x0003, 0x0006}, /* TG FR Phase Adjust */ + {0x0, 0x0001, 0x0007}, /* TG FCDS Phase Adjust */ + {0x0, 0x0039, 0x0008}, /* TG FS Phase Adjust */ + {0x0, 0x0088, 0x000a}, /* TG MH1 */ + {0x0, 0x0003, 0x000f}, /* TG Pixel ID */ + + /* Like below, unexplained toglleing */ + {0x0, 0x0080, 0x000c}, + {0x0, 0x0000, 0x000d}, + {0x0, 0x0080, 0x000c}, + {0x0, 0x0004, 0x000d}, + {0x0, 0x0000, 0x000c}, + {0x0, 0x0000, 0x000d}, + {0x0, 0x0040, 0x000c}, + {0x0, 0x0017, 0x000d}, + {0x0, 0x00c0, 0x000c}, + {0x0, 0x0000, 0x000d}, + {0x0, 0x0080, 0x000c}, + {0x0, 0x0006, 0x000d}, + {0x0, 0x0080, 0x000c}, + {0x0, 0x0004, 0x000d}, + {0x0, 0x0002, 0x0003}, +#endif + +#ifdef DSPWIN_SET + {0x1, 0x001c, 0x0017}, /* CCDSP W1 Start X */ + {0x1, 0x00e2, 0x0019}, /* CCDSP W2 Start X */ + {0x1, 0x001c, 0x001b}, /* CCDSP W3 Start X */ + {0x1, 0x00e2, 0x001d}, /* CCDSP W4 Start X */ + {0x1, 0x00aa, 0x001f}, /* CCDSP W5 Start X */ + {0x1, 0x0070, 0x0020}, /* CCDSP W5 Start Y */ +#endif + {0x0, 0x0001, 0x0010}, /* TG Start Clock */ + +/* {0x2, 0x006a, 0x0001}, * C/S Enable ISOSYNCH Packet Engine */ + {0x2, 0x0068, 0x0001}, /* C/S Diable ISOSYNCH Packet Engine */ + {0x2, 0x0000, 0x0005}, + {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ + {0x2, 0x0043, 0x0000}, /* C/S Set Timing Mode, Disable TG soft reset */ + {0x2, 0x0002, 0x0005}, /* C/S GPIO */ + {0x2, 0x0003, 0x0005}, /* C/S GPIO */ + + {0x2, 0x006a, 0x0001}, /* C/S Enable ISOSYNCH Packet Engine */ + {} +}; + +/* + * Data used to initialize a SPCA501C with HV7131B sensor. + * From a capture file taken with USBSnoop v 1.5 + * I have a "SPCA501C pc camera chipset" manual by sunplus, but some + * of the value meanings are obscure or simply "reserved". + * to do list: + * 1) Understand what every value means + * 2) Understand why some values seem to appear more than once + * 3) Write a small comment for each line of the following arrays. + */ +static __u16 spca501c_arowana_open_data[][3] = { + /* bmRequest,value,index */ + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x01, 0x0006, 0x0011}, + {0x01, 0x00ff, 0x0012}, + {0x01, 0x0014, 0x0013}, + {0x01, 0x0000, 0x0014}, + {0x01, 0x0042, 0x0051}, + {0x01, 0x0040, 0x0052}, + {0x01, 0x0051, 0x0053}, + {0x01, 0x0040, 0x0054}, + {0x01, 0x0000, 0x0055}, + {0x00, 0x0025, 0x0000}, + {0x00, 0x0026, 0x0000}, + {0x00, 0x0001, 0x0000}, + {0x00, 0x0027, 0x0000}, + {0x00, 0x008a, 0x0000}, + {} +}; + +static __u16 spca501c_arowana_init_data[][3] = { + /* bmRequest,value,index */ + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x01, 0x0006, 0x0011}, + {0x01, 0x00ff, 0x0012}, + {0x01, 0x0014, 0x0013}, + {0x01, 0x0000, 0x0014}, + {0x01, 0x0042, 0x0051}, + {0x01, 0x0040, 0x0052}, + {0x01, 0x0051, 0x0053}, + {0x01, 0x0040, 0x0054}, + {0x01, 0x0000, 0x0055}, + {0x00, 0x0025, 0x0000}, + {0x00, 0x0026, 0x0000}, + {0x00, 0x0001, 0x0000}, + {0x00, 0x0027, 0x0000}, + {0x00, 0x008a, 0x0000}, + {0x02, 0x0000, 0x0005}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0xfffd, 0x000a}, + {0x01, 0x0023, 0x000b}, + {0x01, 0xffea, 0x000c}, + {0x01, 0xfff4, 0x000d}, + {0x01, 0xfffc, 0x000e}, + {0x01, 0xffe3, 0x000f}, + {0x01, 0x001f, 0x0010}, + {0x01, 0x00a8, 0x0001}, + {0x01, 0x0067, 0x0007}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x00c8, 0x0015}, + {0x01, 0x0032, 0x0016}, + {0x01, 0x0000, 0x0011}, + {0x01, 0x0000, 0x0012}, + {0x01, 0x0000, 0x0013}, + {0x01, 0x000a, 0x0003}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xc000, 0x0001}, + {0x02, 0x0000, 0x0005}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x000f, 0x0000}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0xfffd, 0x000a}, + {0x01, 0x0023, 0x000b}, + {0x01, 0xffea, 0x000c}, + {0x01, 0xfff4, 0x000d}, + {0x01, 0xfffc, 0x000e}, + {0x01, 0xffe3, 0x000f}, + {0x01, 0x001f, 0x0010}, + {0x01, 0x00a8, 0x0001}, + {0x01, 0x0067, 0x0007}, + {0x01, 0x0042, 0x0051}, + {0x01, 0x0051, 0x0053}, + {0x01, 0x000a, 0x0003}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xc000, 0x0001}, + {0x02, 0x0000, 0x0005}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x000c, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0000, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, + {0x00, 0x0000, 0x0024}, + {0x00, 0x00d5, 0x0025}, + {0x00, 0x0000, 0x0026}, + {0x00, 0x000b, 0x0027}, + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, + {0xff, 0x0000, 0x00d0}, + {0xff, 0x00d8, 0x00d1}, + {0xff, 0x0000, 0x00d4}, + {0xff, 0x0000, 0x00d5}, + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0x00fd, 0x000a}, + {0x01, 0x0038, 0x000b}, + {0x01, 0x00d1, 0x000c}, + {0x01, 0x00f7, 0x000d}, + {0x01, 0x00ed, 0x000e}, + {0x01, 0x00d8, 0x000f}, + {0x01, 0x0038, 0x0010}, + {0x01, 0x00ff, 0x0015}, + {0x01, 0x0001, 0x0016}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, + {0x01, 0x00ff, 0x003e}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0060, 0x0057}, + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x100a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x001e, 0x0000}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x0011, 0x0008}, + {0x01, 0x0032, 0x0009}, + {0x01, 0xfffd, 0x000a}, + {0x01, 0x0023, 0x000b}, + {0x01, 0xffea, 0x000c}, + {0x01, 0xfff4, 0x000d}, + {0x01, 0xfffc, 0x000e}, + {0x01, 0xffe3, 0x000f}, + {0x01, 0x001f, 0x0010}, + {0x01, 0x00a8, 0x0001}, + {0x01, 0x0067, 0x0007}, + {0x01, 0x0042, 0x0051}, + {0x01, 0x0051, 0x0053}, + {0x01, 0x000a, 0x0003}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x0007, 0x0005}, + {0x01, 0x0042, 0x0051}, + {0x01, 0x0051, 0x0053}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x002d, 0x0000}, + {0x01, 0x0003, 0x003f}, + {0x01, 0x0001, 0x0056}, + {0x02, 0xc000, 0x0001}, + {0x02, 0x0000, 0x0005}, + {} +}; + +/* Unknow camera from Ori Usbid 0x0000:0x0000 */ +/* Based on snoops from Ori Cohen */ +static __u16 spca501c_mysterious_open_data[][3] = { + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, +/* DSP Registers */ + {0x01, 0x0016, 0x0011}, /* RGB offset */ + {0x01, 0x0000, 0x0012}, + {0x01, 0x0006, 0x0013}, + {0x01, 0x0078, 0x0051}, + {0x01, 0x0040, 0x0052}, + {0x01, 0x0046, 0x0053}, + {0x01, 0x0040, 0x0054}, + {0x00, 0x0025, 0x0000}, +/* {0x00, 0x0000, 0x0000 }, */ +/* Part 2 */ +/* TG Registers */ + {0x00, 0x0026, 0x0000}, + {0x00, 0x0001, 0x0000}, + {0x00, 0x0027, 0x0000}, + {0x00, 0x008a, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x2000, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0015, 0x0001}, + {0x05, 0x00ea, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0023, 0x0001}, + {0x05, 0x0003, 0x0000}, + {0x05, 0x0030, 0x0001}, + {0x05, 0x002b, 0x0000}, + {0x05, 0x0031, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0032, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0033, 0x0001}, + {0x05, 0x0023, 0x0000}, + {0x05, 0x0034, 0x0001}, + {0x05, 0x0002, 0x0000}, + {0x05, 0x0050, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0051, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0052, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0054, 0x0001}, + {0x05, 0x0001, 0x0000}, + {} +}; + +/* Based on snoops from Ori Cohen */ +static __u16 spca501c_mysterious_init_data[][3] = { +/* Part 3 */ +/* TG registers */ +/* {0x00, 0x0000, 0x0000}, */ + {0x00, 0x0000, 0x0001}, + {0x00, 0x0000, 0x0002}, + {0x00, 0x0006, 0x0003}, + {0x00, 0x0000, 0x0004}, + {0x00, 0x0090, 0x0005}, + {0x00, 0x0000, 0x0006}, + {0x00, 0x0040, 0x0007}, + {0x00, 0x00c0, 0x0008}, + {0x00, 0x004a, 0x0009}, + {0x00, 0x0000, 0x000a}, + {0x00, 0x0000, 0x000b}, + {0x00, 0x0001, 0x000c}, + {0x00, 0x0001, 0x000d}, + {0x00, 0x0000, 0x000e}, + {0x00, 0x0002, 0x000f}, + {0x00, 0x0001, 0x0010}, + {0x00, 0x0000, 0x0011}, + {0x00, 0x0001, 0x0012}, + {0x00, 0x0002, 0x0020}, + {0x00, 0x0080, 0x0021}, /* 640 */ + {0x00, 0x0001, 0x0022}, + {0x00, 0x00e0, 0x0023}, /* 480 */ + {0x00, 0x0000, 0x0024}, /* Offset H hight */ + {0x00, 0x00d3, 0x0025}, /* low */ + {0x00, 0x0000, 0x0026}, /* Offset V */ + {0x00, 0x000d, 0x0027}, /* low */ + {0x00, 0x0000, 0x0046}, + {0x00, 0x0000, 0x0047}, + {0x00, 0x0000, 0x0048}, + {0x00, 0x0000, 0x0049}, + {0x00, 0x0008, 0x004a}, +/* DSP Registers */ + {0x01, 0x00a6, 0x0000}, + {0x01, 0x0028, 0x0001}, + {0x01, 0x0000, 0x0002}, + {0x01, 0x000a, 0x0003}, /* Level Calc bit7 ->1 Auto */ + {0x01, 0x0040, 0x0004}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x000f, 0x0008}, /* A11 Color correction coeff */ + {0x01, 0x002d, 0x0009}, /* A12 */ + {0x01, 0x0005, 0x000a}, /* A13 */ + {0x01, 0x0023, 0x000b}, /* A21 */ + {0x01, 0x00e0, 0x000c}, /* A22 */ + {0x01, 0x00fd, 0x000d}, /* A23 */ + {0x01, 0x00f4, 0x000e}, /* A31 */ + {0x01, 0x00e4, 0x000f}, /* A32 */ + {0x01, 0x0028, 0x0010}, /* A33 */ + {0x01, 0x00ff, 0x0015}, /* Reserved */ + {0x01, 0x0001, 0x0016}, /* Reserved */ + {0x01, 0x0032, 0x0017}, /* Win1 Start begin */ + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x0000, 0x001f}, + {0x01, 0x0000, 0x0020}, /* Win1 Start end */ + {0x01, 0x00ff, 0x003e}, /* Reserved begin */ + {0x01, 0x0002, 0x003f}, + {0x01, 0x0000, 0x0040}, + {0x01, 0x0035, 0x0041}, + {0x01, 0x0053, 0x0042}, + {0x01, 0x0069, 0x0043}, + {0x01, 0x007c, 0x0044}, + {0x01, 0x008c, 0x0045}, + {0x01, 0x009a, 0x0046}, + {0x01, 0x00a8, 0x0047}, + {0x01, 0x00b4, 0x0048}, + {0x01, 0x00bf, 0x0049}, + {0x01, 0x00ca, 0x004a}, + {0x01, 0x00d4, 0x004b}, + {0x01, 0x00dd, 0x004c}, + {0x01, 0x00e7, 0x004d}, + {0x01, 0x00ef, 0x004e}, + {0x01, 0x00f8, 0x004f}, + {0x01, 0x00ff, 0x0050}, + {0x01, 0x0003, 0x0056}, /* Reserved end */ + {0x01, 0x0060, 0x0057}, /* Edge Gain */ + {0x01, 0x0040, 0x0058}, + {0x01, 0x0011, 0x0059}, /* Edge Bandwidth */ + {0x01, 0x0001, 0x005a}, + {0x02, 0x0007, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x02, 0x0007, 0x0005}, + {0x02, 0x0015, 0x0006}, + {0x02, 0x200a, 0x0007}, + {0x02, 0xa048, 0x0000}, + {0x02, 0xc000, 0x0001}, + {0x02, 0x000f, 0x0005}, + {0x02, 0xa048, 0x0000}, + {0x05, 0x0022, 0x0004}, + {0x05, 0x0025, 0x0001}, + {0x05, 0x0000, 0x0000}, +/* Part 4 */ + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0001, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x05, 0x0021, 0x0001}, + {0x05, 0x00d2, 0x0000}, + {0x05, 0x0020, 0x0001}, + {0x05, 0x0000, 0x0000}, + {0x00, 0x0090, 0x0005}, + {0x01, 0x00a6, 0x0000}, + {0x02, 0x0000, 0x0005}, + {0x05, 0x0026, 0x0001}, + {0x05, 0x0001, 0x0000}, + {0x05, 0x0027, 0x0001}, + {0x05, 0x004e, 0x0000}, +/* Part 5 */ + {0x01, 0x0003, 0x003f}, + {0x01, 0x0001, 0x0056}, + {0x01, 0x000f, 0x0008}, + {0x01, 0x002d, 0x0009}, + {0x01, 0x0005, 0x000a}, + {0x01, 0x0023, 0x000b}, + {0x01, 0xffe0, 0x000c}, + {0x01, 0xfffd, 0x000d}, + {0x01, 0xfff4, 0x000e}, + {0x01, 0xffe4, 0x000f}, + {0x01, 0x0028, 0x0010}, + {0x01, 0x00a8, 0x0001}, + {0x01, 0x0066, 0x0007}, + {0x01, 0x0032, 0x0017}, + {0x01, 0x0023, 0x0018}, + {0x01, 0x00ce, 0x0019}, + {0x01, 0x0023, 0x001a}, + {0x01, 0x0032, 0x001b}, + {0x01, 0x008d, 0x001c}, + {0x01, 0x00ce, 0x001d}, + {0x01, 0x008d, 0x001e}, + {0x01, 0x00c8, 0x0015}, /* c8 Poids fort Luma */ + {0x01, 0x0032, 0x0016}, /* 32 */ + {0x01, 0x0016, 0x0011}, /* R 00 */ + {0x01, 0x0016, 0x0012}, /* G 00 */ + {0x01, 0x0016, 0x0013}, /* B 00 */ + {0x01, 0x000a, 0x0003}, + {0x02, 0xc002, 0x0001}, + {0x02, 0x0007, 0x0005}, + {} +}; + +static int reg_write(struct usb_device *dev, + __u16 req, __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x", + req, index, value); + if (ret < 0) + PDEBUG(D_ERR, "reg write: error %d", ret); + return ret; +} + +/* returns: negative is error, pos or zero is data */ +static int reg_read(struct usb_device *dev, + __u16 req, /* bRequest */ + __u16 index, /* wIndex */ + __u16 length) /* wLength (1 or 2 only) */ +{ + int ret; + __u8 buf[2]; + + buf[1] = 0; + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, + buf, length, + 500); /* timeout */ + if (ret < 0) { + PDEBUG(D_ERR, "reg_read err %d", ret); + return -1; + } + return (buf[1] << 8) + buf[0]; +} + +static int write_vector(struct gspca_dev *gspca_dev, + __u16 data[][3]) +{ + struct usb_device *dev = gspca_dev->dev; + int ret, i = 0; + + while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { + ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + if (ret < 0) { + PDEBUG(D_ERR, + "Reg write failed for 0x%02x,0x%02x,0x%02x", + data[i][0], data[i][1], data[i][2]); + return ret; + } + i++; + } + return 0; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, sd->brightness); + reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness); + reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, sd->brightness); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u16 brightness; + + brightness = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, 2); + sd->brightness = brightness << 1; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, 0x00, 0x00, + (sd->contrast >> 8) & 0xff); + reg_write(gspca_dev->dev, 0x00, 0x01, + sd->contrast & 0xff); +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ +/* spca50x->contrast = 0xaa01; */ +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors); +} + +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, 2); +/* sd->hue = (reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, */ +/* 2) & 0xFF) << 8; */ +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x0000: /* Unknow Camera */ +/* switch (product) { */ +/* case 0x0000: */ + sd->subtype = MystFromOriUnknownCamera; +/* break; */ +/* } */ + break; + case 0x040a: /* Kodak cameras */ +/* switch (product) { */ +/* case 0x0002: */ + sd->subtype = KodakDVC325; +/* break; */ +/* } */ + break; + case 0x0497: /* Smile International */ +/* switch (product) { */ +/* case 0xc001: */ + sd->subtype = SmileIntlCamera; +/* break; */ +/* } */ + break; + case 0x0506: /* 3COM cameras */ +/* switch (product) { */ +/* case 0x00df: */ + sd->subtype = ThreeComHomeConnectLite; +/* break; */ +/* } */ + break; + case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ + switch (product) { + case 0x0401: + sd->subtype = IntelCreateAndShare; + break; + case 0x0402: + sd->subtype = ViewQuestM318B; + break; + } + break; + case 0x1776: /* Arowana */ +/* switch (product) { */ +/* case 0x501c: */ + sd->subtype = Arowana300KCMOSCamera; +/* break; */ +/* } */ + break; + } + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; + + switch (sd->subtype) { + case Arowana300KCMOSCamera: + case SmileIntlCamera: + /* Arowana 300k CMOS Camera data */ + if (write_vector(gspca_dev, spca501c_arowana_init_data)) + goto error; + break; + case MystFromOriUnknownCamera: + /* UnKnow Ori CMOS Camera data */ + if (write_vector(gspca_dev, spca501c_mysterious_open_data)) + goto error; + break; + default: + /* generic spca501 init data */ + if (write_vector(gspca_dev, spca501_init_data)) + goto error; + break; + } + return 0; +error: + return -EINVAL; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + PDEBUG(D_STREAM, "SPCA501 init"); + switch (sd->subtype) { + case ThreeComHomeConnectLite: + /* Special handling for 3com data */ + write_vector(gspca_dev, spca501_3com_open_data); + break; + case Arowana300KCMOSCamera: + case SmileIntlCamera: + /* Arowana 300k CMOS Camera data */ + write_vector(gspca_dev, spca501c_arowana_open_data); + break; + case MystFromOriUnknownCamera: + /* UnKnow CMOS Camera data */ + write_vector(gspca_dev, spca501c_mysterious_init_data); + break; + default: + /* Generic 501 open data */ + write_vector(gspca_dev, spca501_open_data); + } + PDEBUG(D_STREAM, "Initializing SPCA501 finished"); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int mode; + + /* memorize the wanted pixel format */ + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + + /* Enable ISO packet machine CTRL reg=2, + * index=1 bitmask=0x2 (bit ordinal 1) */ + reg_write(dev, SPCA50X_REG_USB, 0x6, 0x94); + switch (mode) { + case 0: /* 640x480 */ + reg_write(dev, SPCA50X_REG_USB, 0x07, 0x004a); + break; + case 1: /* 320x240 */ + reg_write(dev, SPCA50X_REG_USB, 0x07, 0x104a); + break; + default: +/* case 2: * 160x120 */ + reg_write(dev, SPCA50X_REG_USB, 0x07, 0x204a); + break; + } + reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); + + /* HDG atleast the Intel CreateAndShare needs to have one of its + * brightness / contrast / color set otherwise it assumes wath seems + * max contrast. Note that strange enough setting any of these is + * enough to fix the max contrast problem, to be sure we set all 3 */ + setbrightness(gspca_dev); + setcontrast(gspca_dev); + setcolors(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + /* Disable ISO packet + * machine CTRL reg=2, index=1 bitmask=0x0 (bit ordinal 1) */ + reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ + reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00); +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + switch (data[0]) { + case 0: /* start of frame */ + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + data, 0); + data += SPCA501_OFFSET_DATA; + len -= SPCA501_OFFSET_DATA; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + return; + case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + data++; + len--; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data, len); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcolors(gspca_dev); + *val = sd->colors; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, + {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, + {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, + {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")}, + {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")}, + {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")}, + {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c new file mode 100644 index 000000000000..5b23518d970d --- /dev/null +++ b/drivers/media/video/gspca/spca505.c @@ -0,0 +1,933 @@ +/* + * SPCA505 chip based cameras initialization data + * + * V4L2 by Jean-Francis Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define MODULE_NAME "spca505" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int buflen; + unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ + unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ + + unsigned char brightness; + + char subtype; +#define IntelPCCameraPro 0 +#define Nxultra 1 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 127, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_YUYV, 160, 120, 5}, + {V4L2_PIX_FMT_YUYV, 176, 144, 4}, + {V4L2_PIX_FMT_YUYV, 320, 240, 2}, + {V4L2_PIX_FMT_YUYV, 352, 288, 1}, + {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +}; + +#define SPCA50X_OFFSET_DATA 10 + +#define SPCA50X_REG_USB 0x02 /* spca505 501 */ + +#define SPCA50X_USB_CTRL 0x00 /* spca505 */ +#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */ +#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */ +#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */ +#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */ + +#define SPCA50X_GLOBAL_MISC1 0x01 /* 505 */ +#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */ +#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */ + +/* + * Data to initialize a SPCA505. Common to the CCD and external modes + */ +static __u16 spca505_init_data[][3] = { + /* line bmRequest,value,index */ + /* 1819 */ + {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, + /* Sensor reset */ + /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3}, + /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1}, + /* Block USB reset */ + /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, + SPCA50X_GLOBAL_MISC0}, + + /* 1831 */ {0x5, 0x01, 0x10}, + /* Maybe power down some stuff */ + /* 1834 */ {0x5, 0x0f, 0x11}, + + /* Setup internal CCD ? */ + /* 1837 */ {0x6, 0x10, 0x08}, + /* 1840 */ {0x6, 0x00, 0x09}, + /* 1843 */ {0x6, 0x00, 0x0a}, + /* 1846 */ {0x6, 0x00, 0x0b}, + /* 1849 */ {0x6, 0x10, 0x0c}, + /* 1852 */ {0x6, 0x00, 0x0d}, + /* 1855 */ {0x6, 0x00, 0x0e}, + /* 1858 */ {0x6, 0x00, 0x0f}, + /* 1861 */ {0x6, 0x10, 0x10}, + /* 1864 */ {0x6, 0x02, 0x11}, + /* 1867 */ {0x6, 0x00, 0x12}, + /* 1870 */ {0x6, 0x04, 0x13}, + /* 1873 */ {0x6, 0x02, 0x14}, + /* 1876 */ {0x6, 0x8a, 0x51}, + /* 1879 */ {0x6, 0x40, 0x52}, + /* 1882 */ {0x6, 0xb6, 0x53}, + /* 1885 */ {0x6, 0x3d, 0x54}, + {} +}; + +/* + * Data to initialize the camera using the internal CCD + */ +static __u16 spca505_open_data_ccd[][3] = { + /* line bmRequest,value,index */ + /* Internal CCD data set */ + /* 1891 */ {0x3, 0x04, 0x01}, + /* This could be a reset */ + /* 1894 */ {0x3, 0x00, 0x01}, + + /* Setup compression and image registers. 0x6 and 0x7 seem to be + related to H&V hold, and are resolution mode specific */ + /* 1897 */ {0x4, 0x10, 0x01}, + /* DIFF(0x50), was (0x10) */ + /* 1900 */ {0x4, 0x00, 0x04}, + /* 1903 */ {0x4, 0x00, 0x05}, + /* 1906 */ {0x4, 0x20, 0x06}, + /* 1909 */ {0x4, 0x20, 0x07}, + + /* 1912 */ {0x8, 0x0a, 0x00}, + /* DIFF (0x4a), was (0xa) */ + + /* 1915 */ {0x5, 0x00, 0x10}, + /* 1918 */ {0x5, 0x00, 0x11}, + /* 1921 */ {0x5, 0x00, 0x00}, + /* DIFF not written */ + /* 1924 */ {0x5, 0x00, 0x01}, + /* DIFF not written */ + /* 1927 */ {0x5, 0x00, 0x02}, + /* DIFF not written */ + /* 1930 */ {0x5, 0x00, 0x03}, + /* DIFF not written */ + /* 1933 */ {0x5, 0x00, 0x04}, + /* DIFF not written */ + /* 1936 */ {0x5, 0x80, 0x05}, + /* DIFF not written */ + /* 1939 */ {0x5, 0xe0, 0x06}, + /* DIFF not written */ + /* 1942 */ {0x5, 0x20, 0x07}, + /* DIFF not written */ + /* 1945 */ {0x5, 0xa0, 0x08}, + /* DIFF not written */ + /* 1948 */ {0x5, 0x0, 0x12}, + /* DIFF not written */ + /* 1951 */ {0x5, 0x02, 0x0f}, + /* DIFF not written */ + /* 1954 */ {0x5, 0x10, 0x46}, + /* DIFF not written */ + /* 1957 */ {0x5, 0x8, 0x4a}, + /* DIFF not written */ + + /* 1960 */ {0x3, 0x08, 0x03}, + /* DIFF (0x3,0x28,0x3) */ + /* 1963 */ {0x3, 0x08, 0x01}, + /* 1966 */ {0x3, 0x0c, 0x03}, + /* DIFF not written */ + /* 1969 */ {0x3, 0x21, 0x00}, + /* DIFF (0x39) */ + +/* Extra block copied from init to hopefully ensure CCD is in a sane state */ + /* 1837 */ {0x6, 0x10, 0x08}, + /* 1840 */ {0x6, 0x00, 0x09}, + /* 1843 */ {0x6, 0x00, 0x0a}, + /* 1846 */ {0x6, 0x00, 0x0b}, + /* 1849 */ {0x6, 0x10, 0x0c}, + /* 1852 */ {0x6, 0x00, 0x0d}, + /* 1855 */ {0x6, 0x00, 0x0e}, + /* 1858 */ {0x6, 0x00, 0x0f}, + /* 1861 */ {0x6, 0x10, 0x10}, + /* 1864 */ {0x6, 0x02, 0x11}, + /* 1867 */ {0x6, 0x00, 0x12}, + /* 1870 */ {0x6, 0x04, 0x13}, + /* 1873 */ {0x6, 0x02, 0x14}, + /* 1876 */ {0x6, 0x8a, 0x51}, + /* 1879 */ {0x6, 0x40, 0x52}, + /* 1882 */ {0x6, 0xb6, 0x53}, + /* 1885 */ {0x6, 0x3d, 0x54}, + /* End of extra block */ + + /* 1972 */ {0x6, 0x3f, 0x1}, + /* Block skipped */ + /* 1975 */ {0x6, 0x10, 0x02}, + /* 1978 */ {0x6, 0x64, 0x07}, + /* 1981 */ {0x6, 0x10, 0x08}, + /* 1984 */ {0x6, 0x00, 0x09}, + /* 1987 */ {0x6, 0x00, 0x0a}, + /* 1990 */ {0x6, 0x00, 0x0b}, + /* 1993 */ {0x6, 0x10, 0x0c}, + /* 1996 */ {0x6, 0x00, 0x0d}, + /* 1999 */ {0x6, 0x00, 0x0e}, + /* 2002 */ {0x6, 0x00, 0x0f}, + /* 2005 */ {0x6, 0x10, 0x10}, + /* 2008 */ {0x6, 0x02, 0x11}, + /* 2011 */ {0x6, 0x00, 0x12}, + /* 2014 */ {0x6, 0x04, 0x13}, + /* 2017 */ {0x6, 0x02, 0x14}, + /* 2020 */ {0x6, 0x8a, 0x51}, + /* 2023 */ {0x6, 0x40, 0x52}, + /* 2026 */ {0x6, 0xb6, 0x53}, + /* 2029 */ {0x6, 0x3d, 0x54}, + /* 2032 */ {0x6, 0x60, 0x57}, + /* 2035 */ {0x6, 0x20, 0x58}, + /* 2038 */ {0x6, 0x15, 0x59}, + /* 2041 */ {0x6, 0x05, 0x5a}, + + /* 2044 */ {0x5, 0x01, 0xc0}, + /* 2047 */ {0x5, 0x10, 0xcb}, + /* 2050 */ {0x5, 0x80, 0xc1}, + /* */ + /* 2053 */ {0x5, 0x0, 0xc2}, + /* 4 was 0 */ + /* 2056 */ {0x5, 0x00, 0xca}, + /* 2059 */ {0x5, 0x80, 0xc1}, + /* */ + /* 2062 */ {0x5, 0x04, 0xc2}, + /* 2065 */ {0x5, 0x00, 0xca}, + /* 2068 */ {0x5, 0x0, 0xc1}, + /* */ + /* 2071 */ {0x5, 0x00, 0xc2}, + /* 2074 */ {0x5, 0x00, 0xca}, + /* 2077 */ {0x5, 0x40, 0xc1}, + /* */ + /* 2080 */ {0x5, 0x17, 0xc2}, + /* 2083 */ {0x5, 0x00, 0xca}, + /* 2086 */ {0x5, 0x80, 0xc1}, + /* */ + /* 2089 */ {0x5, 0x06, 0xc2}, + /* 2092 */ {0x5, 0x00, 0xca}, + /* 2095 */ {0x5, 0x80, 0xc1}, + /* */ + /* 2098 */ {0x5, 0x04, 0xc2}, + /* 2101 */ {0x5, 0x00, 0xca}, + + /* 2104 */ {0x3, 0x4c, 0x3}, + /* 2107 */ {0x3, 0x18, 0x1}, + + /* 2110 */ {0x6, 0x70, 0x51}, + /* 2113 */ {0x6, 0xbe, 0x53}, + /* 2116 */ {0x6, 0x71, 0x57}, + /* 2119 */ {0x6, 0x20, 0x58}, + /* 2122 */ {0x6, 0x05, 0x59}, + /* 2125 */ {0x6, 0x15, 0x5a}, + + /* 2128 */ {0x4, 0x00, 0x08}, + /* Compress = OFF (0x1 to turn on) */ + /* 2131 */ {0x4, 0x12, 0x09}, + /* 2134 */ {0x4, 0x21, 0x0a}, + /* 2137 */ {0x4, 0x10, 0x0b}, + /* 2140 */ {0x4, 0x21, 0x0c}, + /* 2143 */ {0x4, 0x05, 0x00}, + /* was 5 (Image Type ? ) */ + /* 2146 */ {0x4, 0x00, 0x01}, + + /* 2149 */ {0x6, 0x3f, 0x01}, + + /* 2152 */ {0x4, 0x00, 0x04}, + /* 2155 */ {0x4, 0x00, 0x05}, + /* 2158 */ {0x4, 0x40, 0x06}, + /* 2161 */ {0x4, 0x40, 0x07}, + + /* 2164 */ {0x6, 0x1c, 0x17}, + /* 2167 */ {0x6, 0xe2, 0x19}, + /* 2170 */ {0x6, 0x1c, 0x1b}, + /* 2173 */ {0x6, 0xe2, 0x1d}, + /* 2176 */ {0x6, 0xaa, 0x1f}, + /* 2179 */ {0x6, 0x70, 0x20}, + + /* 2182 */ {0x5, 0x01, 0x10}, + /* 2185 */ {0x5, 0x00, 0x11}, + /* 2188 */ {0x5, 0x01, 0x00}, + /* 2191 */ {0x5, 0x05, 0x01}, + /* 2194 */ {0x5, 0x00, 0xc1}, + /* */ + /* 2197 */ {0x5, 0x00, 0xc2}, + /* 2200 */ {0x5, 0x00, 0xca}, + + /* 2203 */ {0x6, 0x70, 0x51}, + /* 2206 */ {0x6, 0xbe, 0x53}, + {} +}; + +/* + Made by Tomasz Zablocki (skalamandra@poczta.onet.pl) + * SPCA505b chip based cameras initialization data + * + */ +/* jfm */ +#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */ +/* #define initial_brightness 0x0 //0x0(white)-0xff(black) */ +/* + * Data to initialize a SPCA505. Common to the CCD and external modes + */ +static __u16 spca505b_init_data[][3] = { +/* start */ + {0x02, 0x00, 0x00}, /* init */ + {0x02, 0x00, 0x01}, + {0x02, 0x00, 0x02}, + {0x02, 0x00, 0x03}, + {0x02, 0x00, 0x04}, + {0x02, 0x00, 0x05}, + {0x02, 0x00, 0x06}, + {0x02, 0x00, 0x07}, + {0x02, 0x00, 0x08}, + {0x02, 0x00, 0x09}, + {0x03, 0x00, 0x00}, + {0x03, 0x00, 0x01}, + {0x03, 0x00, 0x02}, + {0x03, 0x00, 0x03}, + {0x03, 0x00, 0x04}, + {0x03, 0x00, 0x05}, + {0x03, 0x00, 0x06}, + {0x04, 0x00, 0x00}, + {0x04, 0x00, 0x02}, + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + {0x04, 0x00, 0x06}, + {0x04, 0x00, 0x07}, + {0x04, 0x00, 0x08}, + {0x04, 0x00, 0x09}, + {0x04, 0x00, 0x0a}, + {0x04, 0x00, 0x0b}, + {0x04, 0x00, 0x0c}, + {0x07, 0x00, 0x00}, + {0x07, 0x00, 0x03}, + {0x08, 0x00, 0x00}, + {0x08, 0x00, 0x01}, + {0x08, 0x00, 0x02}, + {0x00, 0x01, 0x00}, + {0x00, 0x01, 0x01}, + {0x00, 0x01, 0x34}, + {0x00, 0x01, 0x35}, + {0x06, 0x18, 0x08}, + {0x06, 0xfc, 0x09}, + {0x06, 0xfc, 0x0a}, + {0x06, 0xfc, 0x0b}, + {0x06, 0x18, 0x0c}, + {0x06, 0xfc, 0x0d}, + {0x06, 0xfc, 0x0e}, + {0x06, 0xfc, 0x0f}, + {0x06, 0x18, 0x10}, + {0x06, 0xfe, 0x12}, + {0x06, 0x00, 0x11}, + {0x06, 0x00, 0x14}, + {0x06, 0x00, 0x13}, + {0x06, 0x28, 0x51}, + {0x06, 0xff, 0x53}, + {0x02, 0x00, 0x08}, + + {0x03, 0x00, 0x03}, + {0x03, 0x10, 0x03}, + {} +}; + +/* + * Data to initialize the camera using the internal CCD + */ +static __u16 spca505b_open_data_ccd[][3] = { + +/* {0x02,0x00,0x00}, */ + {0x03, 0x04, 0x01}, /* rst */ + {0x03, 0x00, 0x01}, + {0x03, 0x00, 0x00}, + {0x03, 0x21, 0x00}, + {0x03, 0x00, 0x04}, + {0x03, 0x00, 0x03}, + {0x03, 0x18, 0x03}, + {0x03, 0x08, 0x01}, + {0x03, 0x1c, 0x03}, + {0x03, 0x5c, 0x03}, + {0x03, 0x5c, 0x03}, + {0x03, 0x18, 0x01}, + +/* same as 505 */ + {0x04, 0x10, 0x01}, + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + {0x04, 0x20, 0x06}, + {0x04, 0x20, 0x07}, + + {0x08, 0x0a, 0x00}, + + {0x05, 0x00, 0x10}, + {0x05, 0x00, 0x11}, + {0x05, 0x00, 0x12}, + {0x05, 0x6f, 0x00}, + {0x05, initial_brightness >> 6, 0x00}, + {0x05, initial_brightness << 2, 0x01}, + {0x05, 0x00, 0x02}, + {0x05, 0x01, 0x03}, + {0x05, 0x00, 0x04}, + {0x05, 0x03, 0x05}, + {0x05, 0xe0, 0x06}, + {0x05, 0x20, 0x07}, + {0x05, 0xa0, 0x08}, + {0x05, 0x00, 0x12}, + {0x05, 0x02, 0x0f}, + {0x05, 128, 0x14}, /* max exposure off (0=on) */ + {0x05, 0x01, 0xb0}, + {0x05, 0x01, 0xbf}, + {0x03, 0x02, 0x06}, + {0x05, 0x10, 0x46}, + {0x05, 0x08, 0x4a}, + + {0x06, 0x00, 0x01}, + {0x06, 0x10, 0x02}, + {0x06, 0x64, 0x07}, + {0x06, 0x18, 0x08}, + {0x06, 0xfc, 0x09}, + {0x06, 0xfc, 0x0a}, + {0x06, 0xfc, 0x0b}, + {0x04, 0x00, 0x01}, + {0x06, 0x18, 0x0c}, + {0x06, 0xfc, 0x0d}, + {0x06, 0xfc, 0x0e}, + {0x06, 0xfc, 0x0f}, + {0x06, 0x11, 0x10}, /* contrast */ + {0x06, 0x00, 0x11}, + {0x06, 0xfe, 0x12}, + {0x06, 0x00, 0x13}, + {0x06, 0x00, 0x14}, + {0x06, 0x9d, 0x51}, + {0x06, 0x40, 0x52}, + {0x06, 0x7c, 0x53}, + {0x06, 0x40, 0x54}, + {0x06, 0x02, 0x57}, + {0x06, 0x03, 0x58}, + {0x06, 0x15, 0x59}, + {0x06, 0x05, 0x5a}, + {0x06, 0x03, 0x56}, + {0x06, 0x02, 0x3f}, + {0x06, 0x00, 0x40}, + {0x06, 0x39, 0x41}, + {0x06, 0x69, 0x42}, + {0x06, 0x87, 0x43}, + {0x06, 0x9e, 0x44}, + {0x06, 0xb1, 0x45}, + {0x06, 0xbf, 0x46}, + {0x06, 0xcc, 0x47}, + {0x06, 0xd5, 0x48}, + {0x06, 0xdd, 0x49}, + {0x06, 0xe3, 0x4a}, + {0x06, 0xe8, 0x4b}, + {0x06, 0xed, 0x4c}, + {0x06, 0xf2, 0x4d}, + {0x06, 0xf7, 0x4e}, + {0x06, 0xfc, 0x4f}, + {0x06, 0xff, 0x50}, + + {0x05, 0x01, 0xc0}, + {0x05, 0x10, 0xcb}, + {0x05, 0x40, 0xc1}, + {0x05, 0x04, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x40, 0xc1}, + {0x05, 0x09, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0xc0, 0xc1}, + {0x05, 0x09, 0xc2}, + {0x05, 0x00, 0xca}, + {0x05, 0x40, 0xc1}, + {0x05, 0x59, 0xc2}, + {0x05, 0x00, 0xca}, + {0x04, 0x00, 0x01}, + {0x05, 0x80, 0xc1}, + {0x05, 0xec, 0xc2}, + {0x05, 0x0, 0xca}, + + {0x06, 0x02, 0x57}, + {0x06, 0x01, 0x58}, + {0x06, 0x15, 0x59}, + {0x06, 0x0a, 0x5a}, + {0x06, 0x01, 0x57}, + {0x06, 0x8a, 0x03}, + {0x06, 0x0a, 0x6c}, + {0x06, 0x30, 0x01}, + {0x06, 0x20, 0x02}, + {0x06, 0x00, 0x03}, + + {0x05, 0x8c, 0x25}, + + {0x06, 0x4d, 0x51}, /* maybe saturation (4d) */ + {0x06, 0x84, 0x53}, /* making green (84) */ + {0x06, 0x00, 0x57}, /* sharpness (1) */ + {0x06, 0x18, 0x08}, + {0x06, 0xfc, 0x09}, + {0x06, 0xfc, 0x0a}, + {0x06, 0xfc, 0x0b}, + {0x06, 0x18, 0x0c}, /* maybe hue (18) */ + {0x06, 0xfc, 0x0d}, + {0x06, 0xfc, 0x0e}, + {0x06, 0xfc, 0x0f}, + {0x06, 0x18, 0x10}, /* maybe contrast (18) */ + + {0x05, 0x01, 0x02}, + + {0x04, 0x00, 0x08}, /* compression */ + {0x04, 0x12, 0x09}, + {0x04, 0x21, 0x0a}, + {0x04, 0x10, 0x0b}, + {0x04, 0x21, 0x0c}, + {0x04, 0x1d, 0x00}, /* imagetype (1d) */ + {0x04, 0x41, 0x01}, /* hardware snapcontrol */ + + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + {0x04, 0x10, 0x06}, + {0x04, 0x10, 0x07}, + {0x04, 0x40, 0x06}, + {0x04, 0x40, 0x07}, + {0x04, 0x00, 0x04}, + {0x04, 0x00, 0x05}, + + {0x06, 0x1c, 0x17}, + {0x06, 0xe2, 0x19}, + {0x06, 0x1c, 0x1b}, + {0x06, 0xe2, 0x1d}, + {0x06, 0x5f, 0x1f}, + {0x06, 0x32, 0x20}, + + {0x05, initial_brightness >> 6, 0x00}, + {0x05, initial_brightness << 2, 0x01}, + {0x05, 0x06, 0xc1}, + {0x05, 0x58, 0xc2}, + {0x05, 0x0, 0xca}, + {0x05, 0x0, 0x11}, + {} +}; + +static int reg_write(struct usb_device *dev, + __u16 reg, __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + reg, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", + reg, index, value, ret); + if (ret < 0) + PDEBUG(D_ERR, "reg write: error %d", ret); + return ret; +} + +/* returns: negative is error, pos or zero is data */ +static int reg_read(struct usb_device *dev, + __u16 reg, /* bRequest */ + __u16 index, /* wIndex */ + __u16 length) /* wLength (1 or 2 only) */ +{ + int ret; + unsigned char buf[4]; + + buf[1] = 0; + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + reg, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (__u16) 0, /* value */ + (__u16) index, + buf, + length, + 500); /* timeout */ + if (ret < 0) { + PDEBUG(D_ERR, "reg_read err %d", ret); + return -1; + } + return (buf[1] << 8) + buf[0]; +} + +static int write_vector(struct gspca_dev *gspca_dev, + __u16 data[][3]) +{ + struct usb_device *dev = gspca_dev->dev; + int ret, i = 0; + + while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { + ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + if (ret < 0) { + PDEBUG(D_ERR, + "Register write failed for 0x%x,0x%x,0x%x", + data[i][0], data[i][1], data[i][2]); + return ret; + } + i++; + } + return 0; +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x041e: /* Creative cameras */ +/* switch (product) { */ +/* case 0x401d: * here505b */ + sd->subtype = Nxultra; +/* break; */ +/* } */ + break; + case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ +/* switch (product) { */ +/* case 0x0430: */ +/* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ + sd->subtype = IntelPCCameraPro; +/* break; */ +/* } */ + break; + } + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + if (sd->subtype != IntelPCCameraPro) + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + else /* no 640x480 for IntelPCCameraPro */ + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + + if (sd->subtype == Nxultra) { + if (write_vector(gspca_dev, spca505b_init_data)) + return -EIO; + } else { + if (write_vector(gspca_dev, spca505_init_data)) + return -EIO; + } + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int ret; + + PDEBUG(D_STREAM, "Initializing SPCA505"); + if (sd->subtype == Nxultra) + write_vector(gspca_dev, spca505b_open_data_ccd); + else + write_vector(gspca_dev, spca505_open_data_ccd); + ret = reg_read(gspca_dev->dev, 6, 0x16, 2); + + if (ret < 0) { + PDEBUG(D_ERR|D_STREAM, + "register read failed for after vector read err = %d", + ret); + return -EIO; + } + PDEBUG(D_STREAM, + "After vector read returns : 0x%x should be 0x0101", + ret & 0xffff); + + ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a); + if (ret < 0) { + PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d", + ret); + return -EIO; + } + reg_write(gspca_dev->dev, 5, 0xc2, 18); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int ret; + + /* necessary because without it we can see stream + * only once after loading module */ + /* stopping usb registers Tomasz change */ + reg_write(dev, 0x02, 0x0, 0x0); + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 0: + reg_write(dev, 0x04, 0x00, 0x00); + reg_write(dev, 0x04, 0x06, 0x10); + reg_write(dev, 0x04, 0x07, 0x10); + break; + case 1: + reg_write(dev, 0x04, 0x00, 0x01); + reg_write(dev, 0x04, 0x06, 0x1a); + reg_write(dev, 0x04, 0x07, 0x1a); + break; + case 2: + reg_write(dev, 0x04, 0x00, 0x02); + reg_write(dev, 0x04, 0x06, 0x1c); + reg_write(dev, 0x04, 0x07, 0x1d); + break; + case 4: + reg_write(dev, 0x04, 0x00, 0x04); + reg_write(dev, 0x04, 0x06, 0x34); + reg_write(dev, 0x04, 0x07, 0x34); + break; + default: +/* case 5: */ + reg_write(dev, 0x04, 0x00, 0x05); + reg_write(dev, 0x04, 0x06, 0x40); + reg_write(dev, 0x04, 0x07, 0x40); + break; + } +/* Enable ISO packet machine - should we do this here or in ISOC init ? */ + ret = reg_write(dev, SPCA50X_REG_USB, + SPCA50X_USB_CTRL, + SPCA50X_CUSB_ENABLE); + +/* reg_write(dev, 0x5, 0x0, 0x0); */ +/* reg_write(dev, 0x5, 0x0, 0x1); */ +/* reg_write(dev, 0x5, 0x11, 0x2); */ +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + /* Disable ISO packet machine */ + reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ + /* This maybe reset or power control */ + reg_write(gspca_dev->dev, 0x03, 0x03, 0x20); + reg_write(gspca_dev->dev, 0x03, 0x01, 0x0); + reg_write(gspca_dev->dev, 0x03, 0x00, 0x1); + reg_write(gspca_dev->dev, 0x05, 0x10, 0x1); + reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); +} + +/* convert YYUV per line to YUYV (YUV 4:2:2) */ +static void yyuv_decode(unsigned char *out, + unsigned char *in, + int width, + int height) +{ + unsigned char *Ui, *Vi, *yi, *yi1; + unsigned char *out1; + int i, j; + + yi = in; + for (i = height / 2; --i >= 0; ) { + out1 = out + width * 2; /* next line */ + yi1 = yi + width; + Ui = yi1 + width; + Vi = Ui + width / 2; + for (j = width / 2; --j >= 0; ) { + *out++ = 128 + *yi++; + *out++ = 128 + *Ui; + *out++ = 128 + *yi++; + *out++ = 128 + *Vi; + + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Ui++; + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Vi++; + } + yi += width * 2; + out = out1; + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (data[0]) { + case 0: /* start of frame */ + if (gspca_dev->last_packet_type == FIRST_PACKET) { + yyuv_decode(sd->tmpbuf2, sd->tmpbuf, + gspca_dev->width, + gspca_dev->height); + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + sd->tmpbuf2, + gspca_dev->width + * gspca_dev->height + * 2); + } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, 0); + data += SPCA50X_OFFSET_DATA; + len -= SPCA50X_OFFSET_DATA; + if (len > 0) + memcpy(sd->tmpbuf, data, len); + else + len = 0; + sd->buflen = len; + return; + case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + data += 1; + len -= 1; + memcpy(&sd->tmpbuf[sd->buflen], data, len); + sd->buflen += len; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + __u8 brightness = sd->brightness; + reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6); + reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2); + +} +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = 255 + - ((reg_read(gspca_dev->dev, 5, 0x01, 1) >> 2) + + (reg_read(gspca_dev->dev, 5, 0x0, 1) << 6)); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, + {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof (struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c new file mode 100644 index 000000000000..614fb3ad7711 --- /dev/null +++ b/drivers/media/video/gspca/spca506.c @@ -0,0 +1,830 @@ +/* + * SPCA506 chip based cameras function + * M Xhaard 15/04/2004 based on different work Mark Taylor and others + * and my own snoopy file on a pv-321c donate by a german compagny + * "Firma Frank Gmbh" from Saarbruecken + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "spca506" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int buflen; + unsigned char tmpbuf[640 * 480 * 3]; /* YYUV per line */ + unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char hue; + char norme; + char channel; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x80, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x47, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x40, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_HUE 3 + { + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0, + }, + .set = sd_sethue, + .get = sd_gethue, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_YUYV, 160, 120, 5}, + {V4L2_PIX_FMT_YUYV, 176, 144, 4}, + {V4L2_PIX_FMT_YUYV, 320, 240, 2}, + {V4L2_PIX_FMT_YUYV, 352, 288, 1}, + {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +}; + +#define SPCA50X_OFFSET_DATA 10 + +#define SAA7113_bright 0x0a /* defaults 0x80 */ +#define SAA7113_contrast 0x0b /* defaults 0x47 */ +#define SAA7113_saturation 0x0c /* defaults 0x40 */ +#define SAA7113_hue 0x0d /* defaults 0x00 */ +#define SAA7113_I2C_BASE_WRITE 0x4a + +static void reg_r(struct usb_device *dev, + __u16 req, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, + 500); +} + +static void reg_w(struct usb_device *dev, + __u16 req, + __u16 value, + __u16 index) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, + NULL, 0, 500); +} + +static void spca506_Initi2c(struct gspca_dev *gspca_dev) +{ + reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); +} + +static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, + __u16 reg) +{ + int retry = 60; + unsigned char Data[2]; + + reg_w(gspca_dev->dev, 0x07, reg, 0x0001); + reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); + while (retry--) { + reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); + if ((Data[0] | Data[1]) == 0x00) + break; + } +} + +static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) +{ + int retry = 60; + unsigned char Data[2]; + unsigned char value; + + reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); + reg_w(gspca_dev->dev, 0x07, reg, 0x0001); + reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); + while (--retry) { + reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); + if ((Data[0] | Data[1]) == 0x00) + break; + } + if (retry == 0) + return -1; + reg_r(gspca_dev->dev, 0x07, 0x0000, &value, 1); + return value; +} + +static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, + __u16 norme, + __u16 channel) +{ + struct sd *sd = (struct sd *) gspca_dev; +/* fixme: check if channel == 0..3 and 6..9 (8 values) */ + __u8 setbit0 = 0x00; + __u8 setbit1 = 0x00; + __u8 videomask = 0x00; + + PDEBUG(D_STREAM, "** Open Set Norme **"); + spca506_Initi2c(gspca_dev); + /* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */ + /* Composite channel bit1 -> 1 S-video bit 1 -> 0 */ + /* and exclude SAA7113 reserved channel set default 0 otherwise */ + if (norme & V4L2_STD_NTSC) + setbit0 = 0x01; + if (channel == 4 || channel == 5 || channel > 9) + channel = 0; + if (channel < 4) + setbit1 = 0x02; + videomask = (0x48 | setbit0 | setbit1); + reg_w(gspca_dev->dev, 0x08, videomask, 0x0000); + spca506_WriteI2c(gspca_dev, (0xc0 | (channel & 0x0F)), 0x02); + + if (norme & V4L2_STD_NTSC) + spca506_WriteI2c(gspca_dev, 0x33, 0x0e); + /* Chrominance Control NTSC N */ + else if (norme & V4L2_STD_SECAM) + spca506_WriteI2c(gspca_dev, 0x53, 0x0e); + /* Chrominance Control SECAM */ + else + spca506_WriteI2c(gspca_dev, 0x03, 0x0e); + /* Chrominance Control PAL BGHIV */ + + sd->norme = norme; + sd->channel = channel; + PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask); + PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel); +} + +static void spca506_GetNormeInput(struct gspca_dev *gspca_dev, + __u16 *norme, __u16 *channel) +{ + struct sd *sd = (struct sd *) gspca_dev; + + /* Read the register is not so good value change so + we use your own copy in spca50x struct */ + *norme = sd->norme; + *channel = sd->channel; + PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel); +} + +static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code, + __u16 xmult, __u16 ymult) +{ + struct usb_device *dev = gspca_dev->dev; + + PDEBUG(D_STREAM, "** SetSize **"); + reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000); + /* Soft snap 0x40 Hard 0x41 */ + reg_w(dev, 0x04, 0x41, 0x0001); + reg_w(dev, 0x04, 0x00, 0x0002); + /* reserved */ + reg_w(dev, 0x04, 0x00, 0x0003); + + /* reserved */ + reg_w(dev, 0x04, 0x00, 0x0004); + /* reserved */ + reg_w(dev, 0x04, 0x01, 0x0005); + /* reserced */ + reg_w(dev, 0x04, xmult, 0x0006); + /* reserved */ + reg_w(dev, 0x04, ymult, 0x0007); + /* compression 1 */ + reg_w(dev, 0x04, 0x00, 0x0008); + /* T=64 -> 2 */ + reg_w(dev, 0x04, 0x00, 0x0009); + /* threshold2D */ + reg_w(dev, 0x04, 0x21, 0x000a); + /* quantization */ + reg_w(dev, 0x04, 0x00, 0x000b); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->hue = sd_ctrls[SD_HUE].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0xFF, 0x0003); + reg_w(dev, 0x03, 0x00, 0x0000); + reg_w(dev, 0x03, 0x1c, 0x0001); + reg_w(dev, 0x03, 0x18, 0x0001); + /* Init on PAL and composite input0 */ + spca506_SetNormeInput(gspca_dev, 0, 0); + reg_w(dev, 0x03, 0x1c, 0x0001); + reg_w(dev, 0x03, 0x18, 0x0001); + reg_w(dev, 0x05, 0x00, 0x0000); + reg_w(dev, 0x05, 0xef, 0x0001); + reg_w(dev, 0x05, 0x00, 0x00c1); + reg_w(dev, 0x05, 0x00, 0x00c2); + reg_w(dev, 0x06, 0x18, 0x0002); + reg_w(dev, 0x06, 0xf5, 0x0011); + reg_w(dev, 0x06, 0x02, 0x0012); + reg_w(dev, 0x06, 0xfb, 0x0013); + reg_w(dev, 0x06, 0x00, 0x0014); + reg_w(dev, 0x06, 0xa4, 0x0051); + reg_w(dev, 0x06, 0x40, 0x0052); + reg_w(dev, 0x06, 0x71, 0x0053); + reg_w(dev, 0x06, 0x40, 0x0054); + /************************************************/ + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0x00, 0x0003); + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0xFF, 0x0003); + reg_w(dev, 0x02, 0x00, 0x0000); + reg_w(dev, 0x03, 0x60, 0x0000); + reg_w(dev, 0x03, 0x18, 0x0001); + /* for a better reading mx :) */ + /*sdca506_WriteI2c(value,register) */ + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, 0x08, 0x01); + spca506_WriteI2c(gspca_dev, 0xc0, 0x02); + /* input composite video */ + spca506_WriteI2c(gspca_dev, 0x33, 0x03); + spca506_WriteI2c(gspca_dev, 0x00, 0x04); + spca506_WriteI2c(gspca_dev, 0x00, 0x05); + spca506_WriteI2c(gspca_dev, 0x0d, 0x06); + spca506_WriteI2c(gspca_dev, 0xf0, 0x07); + spca506_WriteI2c(gspca_dev, 0x98, 0x08); + spca506_WriteI2c(gspca_dev, 0x03, 0x09); + spca506_WriteI2c(gspca_dev, 0x80, 0x0a); + spca506_WriteI2c(gspca_dev, 0x47, 0x0b); + spca506_WriteI2c(gspca_dev, 0x48, 0x0c); + spca506_WriteI2c(gspca_dev, 0x00, 0x0d); + spca506_WriteI2c(gspca_dev, 0x03, 0x0e); /* Chroma Pal adjust */ + spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); + spca506_WriteI2c(gspca_dev, 0x00, 0x10); + spca506_WriteI2c(gspca_dev, 0x0c, 0x11); + spca506_WriteI2c(gspca_dev, 0xb8, 0x12); + spca506_WriteI2c(gspca_dev, 0x01, 0x13); + spca506_WriteI2c(gspca_dev, 0x00, 0x14); + spca506_WriteI2c(gspca_dev, 0x00, 0x15); + spca506_WriteI2c(gspca_dev, 0x00, 0x16); + spca506_WriteI2c(gspca_dev, 0x00, 0x17); + spca506_WriteI2c(gspca_dev, 0x00, 0x18); + spca506_WriteI2c(gspca_dev, 0x00, 0x19); + spca506_WriteI2c(gspca_dev, 0x00, 0x1a); + spca506_WriteI2c(gspca_dev, 0x00, 0x1b); + spca506_WriteI2c(gspca_dev, 0x00, 0x1c); + spca506_WriteI2c(gspca_dev, 0x00, 0x1d); + spca506_WriteI2c(gspca_dev, 0x00, 0x1e); + spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); + spca506_WriteI2c(gspca_dev, 0x02, 0x40); + spca506_WriteI2c(gspca_dev, 0xff, 0x41); + spca506_WriteI2c(gspca_dev, 0xff, 0x42); + spca506_WriteI2c(gspca_dev, 0xff, 0x43); + spca506_WriteI2c(gspca_dev, 0xff, 0x44); + spca506_WriteI2c(gspca_dev, 0xff, 0x45); + spca506_WriteI2c(gspca_dev, 0xff, 0x46); + spca506_WriteI2c(gspca_dev, 0xff, 0x47); + spca506_WriteI2c(gspca_dev, 0xff, 0x48); + spca506_WriteI2c(gspca_dev, 0xff, 0x49); + spca506_WriteI2c(gspca_dev, 0xff, 0x4a); + spca506_WriteI2c(gspca_dev, 0xff, 0x4b); + spca506_WriteI2c(gspca_dev, 0xff, 0x4c); + spca506_WriteI2c(gspca_dev, 0xff, 0x4d); + spca506_WriteI2c(gspca_dev, 0xff, 0x4e); + spca506_WriteI2c(gspca_dev, 0xff, 0x4f); + spca506_WriteI2c(gspca_dev, 0xff, 0x50); + spca506_WriteI2c(gspca_dev, 0xff, 0x51); + spca506_WriteI2c(gspca_dev, 0xff, 0x52); + spca506_WriteI2c(gspca_dev, 0xff, 0x53); + spca506_WriteI2c(gspca_dev, 0xff, 0x54); + spca506_WriteI2c(gspca_dev, 0xff, 0x55); + spca506_WriteI2c(gspca_dev, 0xff, 0x56); + spca506_WriteI2c(gspca_dev, 0xff, 0x57); + spca506_WriteI2c(gspca_dev, 0x00, 0x58); + spca506_WriteI2c(gspca_dev, 0x54, 0x59); + spca506_WriteI2c(gspca_dev, 0x07, 0x5a); + spca506_WriteI2c(gspca_dev, 0x83, 0x5b); + spca506_WriteI2c(gspca_dev, 0x00, 0x5c); + spca506_WriteI2c(gspca_dev, 0x00, 0x5d); + spca506_WriteI2c(gspca_dev, 0x00, 0x5e); + spca506_WriteI2c(gspca_dev, 0x00, 0x5f); + spca506_WriteI2c(gspca_dev, 0x00, 0x60); + spca506_WriteI2c(gspca_dev, 0x05, 0x61); + spca506_WriteI2c(gspca_dev, 0x9f, 0x62); + PDEBUG(D_STREAM, "** Close Init *"); + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u16 norme; + __u16 channel; + __u8 Data[2]; + + /**************************************/ + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0x00, 0x0003); + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0xFF, 0x0003); + reg_w(dev, 0x02, 0x00, 0x0000); + reg_w(dev, 0x03, 0x60, 0x0000); + reg_w(dev, 0x03, 0x18, 0x0001); + + /*sdca506_WriteI2c(value,register) */ + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, 0x08, 0x01); /* Increment Delay */ +/* spca506_WriteI2c(gspca_dev, 0xc0, 0x02); * Analog Input Control 1 */ + spca506_WriteI2c(gspca_dev, 0x33, 0x03); + /* Analog Input Control 2 */ + spca506_WriteI2c(gspca_dev, 0x00, 0x04); + /* Analog Input Control 3 */ + spca506_WriteI2c(gspca_dev, 0x00, 0x05); + /* Analog Input Control 4 */ + spca506_WriteI2c(gspca_dev, 0x0d, 0x06); + /* Horizontal Sync Start 0xe9-0x0d */ + spca506_WriteI2c(gspca_dev, 0xf0, 0x07); + /* Horizontal Sync Stop 0x0d-0xf0 */ + + spca506_WriteI2c(gspca_dev, 0x98, 0x08); /* Sync Control */ +/* Defaults value */ + spca506_WriteI2c(gspca_dev, 0x03, 0x09); /* Luminance Control */ + spca506_WriteI2c(gspca_dev, 0x80, 0x0a); + /* Luminance Brightness */ + spca506_WriteI2c(gspca_dev, 0x47, 0x0b); /* Luminance Contrast */ + spca506_WriteI2c(gspca_dev, 0x48, 0x0c); + /* Chrominance Saturation */ + spca506_WriteI2c(gspca_dev, 0x00, 0x0d); + /* Chrominance Hue Control */ + spca506_WriteI2c(gspca_dev, 0x2a, 0x0f); + /* Chrominance Gain Control */ + /**************************************/ + spca506_WriteI2c(gspca_dev, 0x00, 0x10); + /* Format/Delay Control */ + spca506_WriteI2c(gspca_dev, 0x0c, 0x11); /* Output Control 1 */ + spca506_WriteI2c(gspca_dev, 0xb8, 0x12); /* Output Control 2 */ + spca506_WriteI2c(gspca_dev, 0x01, 0x13); /* Output Control 3 */ + spca506_WriteI2c(gspca_dev, 0x00, 0x14); /* reserved */ + spca506_WriteI2c(gspca_dev, 0x00, 0x15); /* VGATE START */ + spca506_WriteI2c(gspca_dev, 0x00, 0x16); /* VGATE STOP */ + spca506_WriteI2c(gspca_dev, 0x00, 0x17); /* VGATE Control (MSB) */ + spca506_WriteI2c(gspca_dev, 0x00, 0x18); + spca506_WriteI2c(gspca_dev, 0x00, 0x19); + spca506_WriteI2c(gspca_dev, 0x00, 0x1a); + spca506_WriteI2c(gspca_dev, 0x00, 0x1b); + spca506_WriteI2c(gspca_dev, 0x00, 0x1c); + spca506_WriteI2c(gspca_dev, 0x00, 0x1d); + spca506_WriteI2c(gspca_dev, 0x00, 0x1e); + spca506_WriteI2c(gspca_dev, 0xa1, 0x1f); + spca506_WriteI2c(gspca_dev, 0x02, 0x40); + spca506_WriteI2c(gspca_dev, 0xff, 0x41); + spca506_WriteI2c(gspca_dev, 0xff, 0x42); + spca506_WriteI2c(gspca_dev, 0xff, 0x43); + spca506_WriteI2c(gspca_dev, 0xff, 0x44); + spca506_WriteI2c(gspca_dev, 0xff, 0x45); + spca506_WriteI2c(gspca_dev, 0xff, 0x46); + spca506_WriteI2c(gspca_dev, 0xff, 0x47); + spca506_WriteI2c(gspca_dev, 0xff, 0x48); + spca506_WriteI2c(gspca_dev, 0xff, 0x49); + spca506_WriteI2c(gspca_dev, 0xff, 0x4a); + spca506_WriteI2c(gspca_dev, 0xff, 0x4b); + spca506_WriteI2c(gspca_dev, 0xff, 0x4c); + spca506_WriteI2c(gspca_dev, 0xff, 0x4d); + spca506_WriteI2c(gspca_dev, 0xff, 0x4e); + spca506_WriteI2c(gspca_dev, 0xff, 0x4f); + spca506_WriteI2c(gspca_dev, 0xff, 0x50); + spca506_WriteI2c(gspca_dev, 0xff, 0x51); + spca506_WriteI2c(gspca_dev, 0xff, 0x52); + spca506_WriteI2c(gspca_dev, 0xff, 0x53); + spca506_WriteI2c(gspca_dev, 0xff, 0x54); + spca506_WriteI2c(gspca_dev, 0xff, 0x55); + spca506_WriteI2c(gspca_dev, 0xff, 0x56); + spca506_WriteI2c(gspca_dev, 0xff, 0x57); + spca506_WriteI2c(gspca_dev, 0x00, 0x58); + spca506_WriteI2c(gspca_dev, 0x54, 0x59); + spca506_WriteI2c(gspca_dev, 0x07, 0x5a); + spca506_WriteI2c(gspca_dev, 0x83, 0x5b); + spca506_WriteI2c(gspca_dev, 0x00, 0x5c); + spca506_WriteI2c(gspca_dev, 0x00, 0x5d); + spca506_WriteI2c(gspca_dev, 0x00, 0x5e); + spca506_WriteI2c(gspca_dev, 0x00, 0x5f); + spca506_WriteI2c(gspca_dev, 0x00, 0x60); + spca506_WriteI2c(gspca_dev, 0x05, 0x61); + spca506_WriteI2c(gspca_dev, 0x9f, 0x62); + /**************************************/ + reg_w(dev, 0x05, 0x00, 0x0003); + reg_w(dev, 0x05, 0x00, 0x0004); + reg_w(dev, 0x03, 0x10, 0x0001); + reg_w(dev, 0x03, 0x78, 0x0000); + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + case 0: + spca506_Setsize(gspca_dev, 0, 0x10, 0x10); + break; + case 1: + spca506_Setsize(gspca_dev, 1, 0x1a, 0x1a); + break; + case 2: + spca506_Setsize(gspca_dev, 2, 0x1c, 0x1c); + break; + case 4: + spca506_Setsize(gspca_dev, 4, 0x34, 0x34); + break; + default: +/* case 5: */ + spca506_Setsize(gspca_dev, 5, 0x40, 0x40); + break; + } + + /* compress setting and size */ + /* set i2c luma */ + reg_w(dev, 0x02, 0x01, 0x0000); + reg_w(dev, 0x03, 0x12, 0x000); + reg_r(dev, 0x04, 0x0001, Data, 2); + PDEBUG(D_STREAM, "webcam started"); + spca506_GetNormeInput(gspca_dev, &norme, &channel); + spca506_SetNormeInput(gspca_dev, norme, channel); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + reg_w(dev, 0x02, 0x00, 0x0000); + reg_w(dev, 0x03, 0x00, 0x0004); + reg_w(dev, 0x03, 0x00, 0x0003); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +/* convert YYUV per line to YUYV (YUV 4:2:2) */ +static void yyuv_decode(unsigned char *out, + unsigned char *in, + int width, + int height) +{ + unsigned char *Ui, *Vi, *yi, *yi1; + unsigned char *out1; + int i, j; + + yi = in; + for (i = height / 2; --i >= 0; ) { + out1 = out + width * 2; /* next line */ + yi1 = yi + width; + Ui = yi1 + width; + Vi = Ui + width / 2; + for (j = width / 2; --j >= 0; ) { + *out++ = 128 + *yi++; + *out++ = 128 + *Ui; + *out++ = 128 + *yi++; + *out++ = 128 + *Vi; + + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Ui++; + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Vi++; + } + yi += width * 2; + out = out1; + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (data[0]) { + case 0: /* start of frame */ + if (gspca_dev->last_packet_type == FIRST_PACKET) { + yyuv_decode(sd->tmpbuf2, sd->tmpbuf, + gspca_dev->width, + gspca_dev->height); + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + sd->tmpbuf2, + gspca_dev->width + * gspca_dev->height + * 2); + } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, 0); + data += SPCA50X_OFFSET_DATA; + len -= SPCA50X_OFFSET_DATA; + if (len > 0) + memcpy(sd->tmpbuf, data, len); + else + len = 0; + sd->buflen = len; + return; + case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + data += 1; + len -= 1; + memcpy(&sd->tmpbuf[sd->buflen], data, len); + sd->buflen += len; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, sd->brightness, SAA7113_bright); + spca506_WriteI2c(gspca_dev, 0x01, 0x09); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, sd->contrast, SAA7113_contrast); + spca506_WriteI2c(gspca_dev, 0x01, 0x09); +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast); +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, sd->colors, SAA7113_saturation); + spca506_WriteI2c(gspca_dev, 0x01, 0x09); +} + +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation); +} + +static void sethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + spca506_Initi2c(gspca_dev); + spca506_WriteI2c(gspca_dev, sd->hue, SAA7113_hue); + spca506_WriteI2c(gspca_dev, 0x01, 0x09); +} + +static void gethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcolors(gspca_dev); + *val = sd->colors; + return 0; +} + +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hue = val; + if (gspca_dev->streaming) + sethue(gspca_dev); + return 0; +} + +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + gethue(gspca_dev); + *val = sd->hue; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")}, +/* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */ + {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")}, + {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c new file mode 100644 index 000000000000..566adf41f59f --- /dev/null +++ b/drivers/media/video/gspca/spca508.c @@ -0,0 +1,1774 @@ +/* + * SPCA508 chip based cameras subdriver + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "spca508" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int buflen; + unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */ + unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */ + + unsigned char brightness; + + char subtype; +#define CreativeVista 0 +#define HamaUSBSightcam 1 +#define HamaUSBSightcam2 2 +#define IntelEasyPCCamera 3 +#define MicroInnovationIC200 4 +#define ViewQuestVQ110 5 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x80, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_YUYV, 160, 120, 3}, + {V4L2_PIX_FMT_YUYV, 176, 144, 2}, + {V4L2_PIX_FMT_YUYV, 320, 240, 1}, + {V4L2_PIX_FMT_YUYV, 352, 288, 0}, +}; + +/* Frame packet header offsets for the spca508 */ +#define SPCA508_OFFSET_TYPE 1 +#define SPCA508_OFFSET_COMPRESS 2 +#define SPCA508_OFFSET_FRAMSEQ 8 +#define SPCA508_OFFSET_WIN1LUM 11 +#define SPCA508_OFFSET_DATA 37 + +#define SPCA508_SNAPBIT 0x20 +#define SPCA508_SNAPCTRL 0x40 +/*************** I2c ****************/ +#define SPCA508_INDEX_I2C_BASE 0x8800 + +/* + * Initialization data: this is the first set-up data written to the + * device (before the open data). + */ +static __u16 spca508_init_data[][3] = +#define IGN(x) /* nothing */ +{ + /* line URB value, index */ + /* 44274 1804 */ {0x0000, 0x870b}, + + /* 44299 1805 */ {0x0020, 0x8112}, + /* Video drop enable, ISO streaming disable */ + /* 44324 1806 */ {0x0003, 0x8111}, + /* Reset compression & memory */ + /* 44349 1807 */ {0x0000, 0x8110}, + /* Disable all outputs */ + /* 44372 1808 */ /* READ {0x0000, 0x8114} -> 0000: 00 */ + /* 44398 1809 */ {0x0000, 0x8114}, + /* SW GPIO data */ + /* 44423 1810 */ {0x0008, 0x8110}, + /* Enable charge pump output */ + /* 44527 1811 */ {0x0002, 0x8116}, + /* 200 kHz pump clock */ + /* 44555 1812 */ + /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE:) */ + /* 44590 1813 */ {0x0003, 0x8111}, + /* Reset compression & memory */ + /* 44615 1814 */ {0x0000, 0x8111}, + /* Normal mode (not reset) */ + /* 44640 1815 */ {0x0098, 0x8110}, + /* Enable charge pump output, sync.serial,external 2x clock */ + /* 44665 1816 */ {0x000d, 0x8114}, + /* SW GPIO data */ + /* 44690 1817 */ {0x0002, 0x8116}, + /* 200 kHz pump clock */ + /* 44715 1818 */ {0x0020, 0x8112}, + /* Video drop enable, ISO streaming disable */ +/* --------------------------------------- */ + /* 44740 1819 */ {0x000f, 0x8402}, + /* memory bank */ + /* 44765 1820 */ {0x0000, 0x8403}, + /* ... address */ +/* --------------------------------------- */ +/* 0x88__ is Synchronous Serial Interface. */ +/* TBD: This table could be expressed more compactly */ +/* using spca508_write_i2c_vector(). */ +/* TBD: Should see if the values in spca50x_i2c_data */ +/* would work with the VQ110 instead of the values */ +/* below. */ + /* 44790 1821 */ {0x00c0, 0x8804}, + /* SSI slave addr */ + /* 44815 1822 */ {0x0008, 0x8802}, + /* 375 Khz SSI clock */ + /* 44838 1823 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 44862 1824 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 44888 1825 */ {0x0008, 0x8802}, + /* 375 Khz SSI clock */ + /* 44913 1826 */ {0x0012, 0x8801}, + /* SSI reg addr */ + /* 44938 1827 */ {0x0080, 0x8800}, + /* SSI data to write */ + /* 44961 1828 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 44985 1829 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45009 1830 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45035 1831 */ {0x0008, 0x8802}, + /* 375 Khz SSI clock */ + /* 45060 1832 */ {0x0012, 0x8801}, + /* SSI reg addr */ + /* 45085 1833 */ {0x0000, 0x8800}, + /* SSI data to write */ + /* 45108 1834 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45132 1835 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45156 1836 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45182 1837 */ {0x0008, 0x8802}, + /* 375 Khz SSI clock */ + /* 45207 1838 */ {0x0011, 0x8801}, + /* SSI reg addr */ + /* 45232 1839 */ {0x0040, 0x8800}, + /* SSI data to write */ + /* 45255 1840 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45279 1841 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45303 1842 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45329 1843 */ {0x0008, 0x8802}, + /* 45354 1844 */ {0x0013, 0x8801}, + /* 45379 1845 */ {0x0000, 0x8800}, + /* 45402 1846 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45426 1847 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45450 1848 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45476 1849 */ {0x0008, 0x8802}, + /* 45501 1850 */ {0x0014, 0x8801}, + /* 45526 1851 */ {0x0000, 0x8800}, + /* 45549 1852 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45573 1853 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45597 1854 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45623 1855 */ {0x0008, 0x8802}, + /* 45648 1856 */ {0x0015, 0x8801}, + /* 45673 1857 */ {0x0001, 0x8800}, + /* 45696 1858 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45720 1859 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45744 1860 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45770 1861 */ {0x0008, 0x8802}, + /* 45795 1862 */ {0x0016, 0x8801}, + /* 45820 1863 */ {0x0003, 0x8800}, + /* 45843 1864 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45867 1865 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 45891 1866 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 45917 1867 */ {0x0008, 0x8802}, + /* 45942 1868 */ {0x0017, 0x8801}, + /* 45967 1869 */ {0x0036, 0x8800}, + /* 45990 1870 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46014 1871 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46038 1872 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46064 1873 */ {0x0008, 0x8802}, + /* 46089 1874 */ {0x0018, 0x8801}, + /* 46114 1875 */ {0x00ec, 0x8800}, + /* 46137 1876 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46161 1877 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46185 1878 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46211 1879 */ {0x0008, 0x8802}, + /* 46236 1880 */ {0x001a, 0x8801}, + /* 46261 1881 */ {0x0094, 0x8800}, + /* 46284 1882 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46308 1883 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46332 1884 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46358 1885 */ {0x0008, 0x8802}, + /* 46383 1886 */ {0x001b, 0x8801}, + /* 46408 1887 */ {0x0000, 0x8800}, + /* 46431 1888 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46455 1889 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46479 1890 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46505 1891 */ {0x0008, 0x8802}, + /* 46530 1892 */ {0x0027, 0x8801}, + /* 46555 1893 */ {0x00a2, 0x8800}, + /* 46578 1894 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46602 1895 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46626 1896 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46652 1897 */ {0x0008, 0x8802}, + /* 46677 1898 */ {0x0028, 0x8801}, + /* 46702 1899 */ {0x0040, 0x8800}, + /* 46725 1900 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46749 1901 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46773 1902 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46799 1903 */ {0x0008, 0x8802}, + /* 46824 1904 */ {0x002a, 0x8801}, + /* 46849 1905 */ {0x0084, 0x8800}, + /* 46872 1906 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46896 1907 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 46920 1908 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 46946 1909 */ {0x0008, 0x8802}, + /* 46971 1910 */ {0x002b, 0x8801}, + /* 46996 1911 */ {0x00a8, 0x8800}, + /* 47019 1912 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47043 1913 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47067 1914 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47093 1915 */ {0x0008, 0x8802}, + /* 47118 1916 */ {0x002c, 0x8801}, + /* 47143 1917 */ {0x00fe, 0x8800}, + /* 47166 1918 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47190 1919 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47214 1920 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47240 1921 */ {0x0008, 0x8802}, + /* 47265 1922 */ {0x002d, 0x8801}, + /* 47290 1923 */ {0x0003, 0x8800}, + /* 47313 1924 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47337 1925 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47361 1926 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47387 1927 */ {0x0008, 0x8802}, + /* 47412 1928 */ {0x0038, 0x8801}, + /* 47437 1929 */ {0x0083, 0x8800}, + /* 47460 1930 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47484 1931 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47508 1932 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47534 1933 */ {0x0008, 0x8802}, + /* 47559 1934 */ {0x0033, 0x8801}, + /* 47584 1935 */ {0x0081, 0x8800}, + /* 47607 1936 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47631 1937 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47655 1938 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47681 1939 */ {0x0008, 0x8802}, + /* 47706 1940 */ {0x0034, 0x8801}, + /* 47731 1941 */ {0x004a, 0x8800}, + /* 47754 1942 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47778 1943 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47802 1944 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47828 1945 */ {0x0008, 0x8802}, + /* 47853 1946 */ {0x0039, 0x8801}, + /* 47878 1947 */ {0x0000, 0x8800}, + /* 47901 1948 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47925 1949 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 47949 1950 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 47975 1951 */ {0x0008, 0x8802}, + /* 48000 1952 */ {0x0010, 0x8801}, + /* 48025 1953 */ {0x00a8, 0x8800}, + /* 48048 1954 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48072 1955 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48096 1956 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48122 1957 */ {0x0008, 0x8802}, + /* 48147 1958 */ {0x0006, 0x8801}, + /* 48172 1959 */ {0x0058, 0x8800}, + /* 48195 1960 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48219 1961 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48243 1962 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48269 1963 */ {0x0008, 0x8802}, + /* 48294 1964 */ {0x0000, 0x8801}, + /* 48319 1965 */ {0x0004, 0x8800}, + /* 48342 1966 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48366 1967 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48390 1968 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48416 1969 */ {0x0008, 0x8802}, + /* 48441 1970 */ {0x0040, 0x8801}, + /* 48466 1971 */ {0x0080, 0x8800}, + /* 48489 1972 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48513 1973 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48537 1974 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48563 1975 */ {0x0008, 0x8802}, + /* 48588 1976 */ {0x0041, 0x8801}, + /* 48613 1977 */ {0x000c, 0x8800}, + /* 48636 1978 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48660 1979 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48684 1980 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48710 1981 */ {0x0008, 0x8802}, + /* 48735 1982 */ {0x0042, 0x8801}, + /* 48760 1983 */ {0x000c, 0x8800}, + /* 48783 1984 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48807 1985 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48831 1986 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 48857 1987 */ {0x0008, 0x8802}, + /* 48882 1988 */ {0x0043, 0x8801}, + /* 48907 1989 */ {0x0028, 0x8800}, + /* 48930 1990 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48954 1991 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 48978 1992 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49004 1993 */ {0x0008, 0x8802}, + /* 49029 1994 */ {0x0044, 0x8801}, + /* 49054 1995 */ {0x0080, 0x8800}, + /* 49077 1996 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49101 1997 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49125 1998 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49151 1999 */ {0x0008, 0x8802}, + /* 49176 2000 */ {0x0045, 0x8801}, + /* 49201 2001 */ {0x0020, 0x8800}, + /* 49224 2002 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49248 2003 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49272 2004 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49298 2005 */ {0x0008, 0x8802}, + /* 49323 2006 */ {0x0046, 0x8801}, + /* 49348 2007 */ {0x0020, 0x8800}, + /* 49371 2008 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49395 2009 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49419 2010 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49445 2011 */ {0x0008, 0x8802}, + /* 49470 2012 */ {0x0047, 0x8801}, + /* 49495 2013 */ {0x0080, 0x8800}, + /* 49518 2014 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49542 2015 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49566 2016 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49592 2017 */ {0x0008, 0x8802}, + /* 49617 2018 */ {0x0048, 0x8801}, + /* 49642 2019 */ {0x004c, 0x8800}, + /* 49665 2020 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49689 2021 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49713 2022 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49739 2023 */ {0x0008, 0x8802}, + /* 49764 2024 */ {0x0049, 0x8801}, + /* 49789 2025 */ {0x0084, 0x8800}, + /* 49812 2026 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49836 2027 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49860 2028 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 49886 2029 */ {0x0008, 0x8802}, + /* 49911 2030 */ {0x004a, 0x8801}, + /* 49936 2031 */ {0x0084, 0x8800}, + /* 49959 2032 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 49983 2033 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 50007 2034 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 50033 2035 */ {0x0008, 0x8802}, + /* 50058 2036 */ {0x004b, 0x8801}, + /* 50083 2037 */ {0x0084, 0x8800}, + /* 50106 2038 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* --------------------------------------- */ + /* 50132 2039 */ {0x0012, 0x8700}, + /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ + /* 50157 2040 */ {0x0000, 0x8701}, + /* CKx1 clock delay adj */ + /* 50182 2041 */ {0x0000, 0x8701}, + /* CKx1 clock delay adj */ + /* 50207 2042 */ {0x0001, 0x870c}, + /* CKOx2 output */ + /* --------------------------------------- */ + /* 50232 2043 */ {0x0080, 0x8600}, + /* Line memory read counter (L) */ + /* 50257 2044 */ {0x0001, 0x8606}, + /* reserved */ + /* 50282 2045 */ {0x0064, 0x8607}, + /* Line memory read counter (H) 0x6480=25,728 */ + /* 50307 2046 */ {0x002a, 0x8601}, + /* CDSP sharp interpolation mode, + * line sel for color sep, edge enhance enab */ + /* 50332 2047 */ {0x0000, 0x8602}, + /* optical black level for user settng = 0 */ + /* 50357 2048 */ {0x0080, 0x8600}, + /* Line memory read counter (L) */ + /* 50382 2049 */ {0x000a, 0x8603}, + /* optical black level calc mode: auto; optical black offset = 10 */ + /* 50407 2050 */ {0x00df, 0x865b}, + /* Horiz offset for valid pixels (L)=0xdf */ + /* 50432 2051 */ {0x0012, 0x865c}, + /* Vert offset for valid lines (L)=0x12 */ + +/* The following two lines seem to be the "wrong" resolution. */ +/* But perhaps these indicate the actual size of the sensor */ +/* rather than the size of the current video mode. */ + /* 50457 2052 */ {0x0058, 0x865d}, + /* Horiz valid pixels (*4) (L) = 352 */ + /* 50482 2053 */ {0x0048, 0x865e}, + /* Vert valid lines (*4) (L) = 288 */ + + /* 50507 2054 */ {0x0015, 0x8608}, + /* A11 Coef ... */ + /* 50532 2055 */ {0x0030, 0x8609}, + /* 50557 2056 */ {0x00fb, 0x860a}, + /* 50582 2057 */ {0x003e, 0x860b}, + /* 50607 2058 */ {0x00ce, 0x860c}, + /* 50632 2059 */ {0x00f4, 0x860d}, + /* 50657 2060 */ {0x00eb, 0x860e}, + /* 50682 2061 */ {0x00dc, 0x860f}, + /* 50707 2062 */ {0x0039, 0x8610}, + /* 50732 2063 */ {0x0001, 0x8611}, + /* R offset for white balance ... */ + /* 50757 2064 */ {0x0000, 0x8612}, + /* 50782 2065 */ {0x0001, 0x8613}, + /* 50807 2066 */ {0x0000, 0x8614}, + /* 50832 2067 */ {0x005b, 0x8651}, + /* R gain for white balance ... */ + /* 50857 2068 */ {0x0040, 0x8652}, + /* 50882 2069 */ {0x0060, 0x8653}, + /* 50907 2070 */ {0x0040, 0x8654}, + /* 50932 2071 */ {0x0000, 0x8655}, + /* 50957 2072 */ {0x0001, 0x863f}, + /* Fixed gamma correction enable, USB control, + * lum filter disable, lum noise clip disable */ + /* 50982 2073 */ {0x00a1, 0x8656}, + /* Window1 size 256x256, Windows2 size 64x64, + * gamma look-up disable, new edge enhancement enable */ + /* 51007 2074 */ {0x0018, 0x8657}, + /* Edge gain high thresh */ + /* 51032 2075 */ {0x0020, 0x8658}, + /* Edge gain low thresh */ + /* 51057 2076 */ {0x000a, 0x8659}, + /* Edge bandwidth high threshold */ + /* 51082 2077 */ {0x0005, 0x865a}, + /* Edge bandwidth low threshold */ + /* -------------------------------- */ + /* 51107 2078 */ {0x0030, 0x8112}, + /* Video drop enable, ISO streaming enable */ + /* 51130 2079 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 51154 2080 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 51180 2081 */ {0xa908, 0x8802}, + /* 51205 2082 */ {0x0034, 0x8801}, + /* SSI reg addr */ + /* 51230 2083 */ {0x00ca, 0x8800}, + /* SSI data to write */ + /* 51253 2084 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 51277 2085 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 51301 2086 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 51327 2087 */ {0x1f08, 0x8802}, + /* 51352 2088 */ {0x0006, 0x8801}, + /* 51377 2089 */ {0x0080, 0x8800}, + /* 51400 2090 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + +/* ----- Read back coefs we wrote earlier. */ + /* 51424 2091 */ /* READ { 0, 0x0000, 0x8608 } -> 0000: 15 */ + /* 51448 2092 */ /* READ { 0, 0x0000, 0x8609 } -> 0000: 30 */ + /* 51472 2093 */ /* READ { 0, 0x0000, 0x860a } -> 0000: fb */ + /* 51496 2094 */ /* READ { 0, 0x0000, 0x860b } -> 0000: 3e */ + /* 51520 2095 */ /* READ { 0, 0x0000, 0x860c } -> 0000: ce */ + /* 51544 2096 */ /* READ { 0, 0x0000, 0x860d } -> 0000: f4 */ + /* 51568 2097 */ /* READ { 0, 0x0000, 0x860e } -> 0000: eb */ + /* 51592 2098 */ /* READ { 0, 0x0000, 0x860f } -> 0000: dc */ + /* 51616 2099 */ /* READ { 0, 0x0000, 0x8610 } -> 0000: 39 */ + /* 51640 2100 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 51664 2101 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 08 */ + /* 51690 2102 */ {0xb008, 0x8802}, + /* 51715 2103 */ {0x0006, 0x8801}, + /* 51740 2104 */ {0x007d, 0x8800}, + /* 51763 2105 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + + + /* This chunk is seemingly redundant with */ + /* earlier commands (A11 Coef...), but if I disable it, */ + /* the image appears too dark. Maybe there was some kind of */ + /* reset since the earlier commands, so this is necessary again. */ + /* 51789 2106 */ {0x0015, 0x8608}, + /* 51814 2107 */ {0x0030, 0x8609}, + /* 51839 2108 */ {0xfffb, 0x860a}, + /* 51864 2109 */ {0x003e, 0x860b}, + /* 51889 2110 */ {0xffce, 0x860c}, + /* 51914 2111 */ {0xfff4, 0x860d}, + /* 51939 2112 */ {0xffeb, 0x860e}, + /* 51964 2113 */ {0xffdc, 0x860f}, + /* 51989 2114 */ {0x0039, 0x8610}, + /* 52014 2115 */ {0x0018, 0x8657}, + + /* 52039 2116 */ {0x0000, 0x8508}, + /* Disable compression. */ + /* Previous line was: + * 52039 2116 * { 0, 0x0021, 0x8508 }, * Enable compression. */ + /* 52064 2117 */ {0x0032, 0x850b}, + /* compression stuff */ + /* 52089 2118 */ {0x0003, 0x8509}, + /* compression stuff */ + /* 52114 2119 */ {0x0011, 0x850a}, + /* compression stuff */ + /* 52139 2120 */ {0x0021, 0x850d}, + /* compression stuff */ + /* 52164 2121 */ {0x0010, 0x850c}, + /* compression stuff */ + /* 52189 2122 */ {0x0003, 0x8500}, + /* *** Video mode: 160x120 */ + /* 52214 2123 */ {0x0001, 0x8501}, + /* Hardware-dominated snap control */ + /* 52239 2124 */ {0x0061, 0x8656}, + /* Window1 size 128x128, Windows2 size 128x128, + * gamma look-up disable, new edge enhancement enable */ + /* 52264 2125 */ {0x0018, 0x8617}, + /* Window1 start X (*2) */ + /* 52289 2126 */ {0x0008, 0x8618}, + /* Window1 start Y (*2) */ + /* 52314 2127 */ {0x0061, 0x8656}, + /* Window1 size 128x128, Windows2 size 128x128, + * gamma look-up disable, new edge enhancement enable */ + /* 52339 2128 */ {0x0058, 0x8619}, + /* Window2 start X (*2) */ + /* 52364 2129 */ {0x0008, 0x861a}, + /* Window2 start Y (*2) */ + /* 52389 2130 */ {0x00ff, 0x8615}, + /* High lum thresh for white balance */ + /* 52414 2131 */ {0x0000, 0x8616}, + /* Low lum thresh for white balance */ + /* 52439 2132 */ {0x0012, 0x8700}, + /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ + /* 52464 2133 */ {0x0012, 0x8700}, + /* Clock speed 48Mhz/(2+2)/2= 6 Mhz */ + /* 52487 2134 */ /* READ { 0, 0x0000, 0x8656 } -> 0000: 61 */ + /* 52513 2135 */ {0x0028, 0x8802}, + /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ + /* 52536 2136 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 52560 2137 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ + /* 52586 2138 */ {0x1f28, 0x8802}, + /* 375 Khz SSI clock, SSI r/w sync with VSYNC */ + /* 52611 2139 */ {0x0010, 0x8801}, + /* SSI reg addr */ + /* 52636 2140 */ {0x003e, 0x8800}, + /* SSI data to write */ + /* 52659 2141 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 52685 2142 */ {0x0028, 0x8802}, + /* 52708 2143 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 52732 2144 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ + /* 52758 2145 */ {0x1f28, 0x8802}, + /* 52783 2146 */ {0x0000, 0x8801}, + /* 52808 2147 */ {0x001f, 0x8800}, + /* 52831 2148 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 52857 2149 */ {0x0001, 0x8602}, + /* optical black level for user settning = 1 */ + + /* Original: */ + /* 52882 2150 */ {0x0023, 0x8700}, + /* Clock speed 48Mhz/(3+2)/4= 2.4 Mhz */ + /* 52907 2151 */ {0x000f, 0x8602}, + /* optical black level for user settning = 15 */ + + /* 52932 2152 */ {0x0028, 0x8802}, + /* 52955 2153 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 52979 2154 */ /* READ { 0, 0x0001, 0x8802 } -> 0000: 28 */ + /* 53005 2155 */ {0x1f28, 0x8802}, + /* 53030 2156 */ {0x0010, 0x8801}, + /* 53055 2157 */ {0x007b, 0x8800}, + /* 53078 2158 */ /* READ { 0, 0x0001, 0x8803 } -> 0000: 00 */ + /* 53104 2159 */ {0x002f, 0x8651}, + /* R gain for white balance ... */ + /* 53129 2160 */ {0x0080, 0x8653}, + /* 53152 2161 */ /* READ { 0, 0x0000, 0x8655 } -> 0000: 00 */ + /* 53178 2162 */ {0x0000, 0x8655}, + + /* 53203 2163 */ {0x0030, 0x8112}, + /* Video drop enable, ISO streaming enable */ + /* 53228 2164 */ {0x0020, 0x8112}, + /* Video drop enable, ISO streaming disable */ + /* 53252 2165 */ + /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ + {0, 0} +}; + + +/* + * Initialization data for Intel EasyPC Camera CS110 + */ +static __u16 spca508cs110_init_data[][3] = { + {0x0000, 0x870b}, /* Reset CTL3 */ + {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ + {0x0000, 0x8111}, /* Normal operation on reset */ + {0x0090, 0x8110}, + /* External Clock 2x & Synchronous Serial Interface Output */ + {0x0020, 0x8112}, /* Video Drop packet enable */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0001, 0x8114}, + {0x0001, 0x8114}, + {0x0001, 0x8114}, + {0x0003, 0x8114}, + + /* Initial sequence Synchronous Serial Interface */ + {0x000f, 0x8402}, /* Memory bank Address */ + {0x0000, 0x8403}, /* Memory bank Address */ + {0x00ba, 0x8804}, /* SSI Slave address */ + {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ + {0x0010, 0x8802}, /* 93.75kHz SSI Clock two DataByte */ + + {0x0001, 0x8801}, + {0x000a, 0x8805},/* a - NWG: Dunno what this is about */ + {0x0000, 0x8800}, + {0x0010, 0x8802}, + + {0x0002, 0x8801}, + {0x0000, 0x8805}, + {0x0000, 0x8800}, + {0x0010, 0x8802}, + + {0x0003, 0x8801}, + {0x0027, 0x8805}, + {0x0001, 0x8800}, + {0x0010, 0x8802}, + + {0x0004, 0x8801}, + {0x0065, 0x8805}, + {0x0001, 0x8800}, + {0x0010, 0x8802}, + + {0x0005, 0x8801}, + {0x0003, 0x8805}, + {0x0000, 0x8800}, + {0x0010, 0x8802}, + + {0x0006, 0x8801}, + {0x001c, 0x8805}, + {0x0000, 0x8800}, + {0x0010, 0x8802}, + + {0x0007, 0x8801}, + {0x002a, 0x8805}, + {0x0000, 0x8800}, + {0x0010, 0x8802}, + + {0x0002, 0x8704}, /* External input CKIx1 */ + {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ + {0x009a, 0x8600}, /* Line memory Read Counter (L) */ + {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */ + {0x0003, 0x865c}, /* 3 Vertical Offset for Valid Lines(L) */ + {0x0058, 0x865d}, /* 58 Horizontal Valid Pixel Window(L) */ + + {0x0006, 0x8660}, /* Nibble data + input order */ + + {0x000a, 0x8602}, /* Optical black level set to 0x0a */ +/* 1945 */ {0x0000, 0x8603}, /* Optical black level Offset */ + +/* 1962 * {0, 0x0000, 0x8611}, * 0 R Offset for white Balance */ +/* 1963 * {0, 0x0000, 0x8612}, * 1 Gr Offset for white Balance */ +/* 1964 * {0, 0x0000, 0x8613}, * 1f B Offset for white Balance */ +/* 1965 * {0, 0x0000, 0x8614}, * f0 Gb Offset for white Balance */ + + {0x0040, 0x8651}, /* 2b BLUE gain for white balance good at all 60 */ + {0x0030, 0x8652}, /* 41 Gr Gain for white Balance (L) */ + {0x0035, 0x8653}, /* 26 RED gain for white balance */ + {0x0035, 0x8654}, /* 40Gb Gain for white Balance (L) */ + {0x0041, 0x863f}, + /* Fixed Gamma correction enabled (makes colours look better) */ + +/* 2422 */ {0x0000, 0x8655}, + /* High bits for white balance*****brightness control*** */ + {} +}; + +static __u16 spca508_sightcam_init_data[][3] = { +/* This line seems to setup the frame/canvas */ + /*368 */ {0x000f, 0x8402}, + +/* Theese 6 lines are needed to startup the webcam */ + /*398 */ {0x0090, 0x8110}, + /*399 */ {0x0001, 0x8114}, + /*400 */ {0x0001, 0x8114}, + /*401 */ {0x0001, 0x8114}, + /*402 */ {0x0003, 0x8114}, + /*403 */ {0x0080, 0x8804}, + +/* This part seems to make the pictures darker? (autobrightness?) */ + /*436 */ {0x0001, 0x8801}, + /*437 */ {0x0004, 0x8800}, + /*439 */ {0x0003, 0x8801}, + /*440 */ {0x00e0, 0x8800}, + /*442 */ {0x0004, 0x8801}, + /*443 */ {0x00b4, 0x8800}, + /*445 */ {0x0005, 0x8801}, + /*446 */ {0x0000, 0x8800}, + + /*448 */ {0x0006, 0x8801}, + /*449 */ {0x00e0, 0x8800}, + /*451 */ {0x0007, 0x8801}, + /*452 */ {0x000c, 0x8800}, + +/* This section is just needed, it probably + * does something like the previous section, + * but the cam won't start if it's not included. + */ + /*484 */ {0x0014, 0x8801}, + /*485 */ {0x0008, 0x8800}, + /*487 */ {0x0015, 0x8801}, + /*488 */ {0x0067, 0x8800}, + /*490 */ {0x0016, 0x8801}, + /*491 */ {0x0000, 0x8800}, + /*493 */ {0x0017, 0x8801}, + /*494 */ {0x0020, 0x8800}, + /*496 */ {0x0018, 0x8801}, + /*497 */ {0x0044, 0x8800}, + +/* Makes the picture darker - and the + * cam won't start if not included + */ + /*505 */ {0x001e, 0x8801}, + /*506 */ {0x00ea, 0x8800}, + /*508 */ {0x001f, 0x8801}, + /*509 */ {0x0001, 0x8800}, + /*511 */ {0x0003, 0x8801}, + /*512 */ {0x00e0, 0x8800}, + +/* seems to place the colors ontop of each other #1 */ + /*517 */ {0x0006, 0x8704}, + /*518 */ {0x0001, 0x870c}, + /*519 */ {0x0016, 0x8600}, + /*520 */ {0x0002, 0x8606}, + +/* if not included the pictures becomes _very_ dark */ + /*521 */ {0x0064, 0x8607}, + /*522 */ {0x003a, 0x8601}, + /*523 */ {0x0000, 0x8602}, + +/* seems to place the colors ontop of each other #2 */ + /*524 */ {0x0016, 0x8600}, + /*525 */ {0x0018, 0x8617}, + /*526 */ {0x0008, 0x8618}, + /*527 */ {0x00a1, 0x8656}, + +/* webcam won't start if not included */ + /*528 */ {0x0007, 0x865b}, + /*529 */ {0x0001, 0x865c}, + /*530 */ {0x0058, 0x865d}, + /*531 */ {0x0048, 0x865e}, + +/* adjusts the colors */ + /*541 */ {0x0049, 0x8651}, + /*542 */ {0x0040, 0x8652}, + /*543 */ {0x004c, 0x8653}, + /*544 */ {0x0040, 0x8654}, + + {0, 0} +}; + +static __u16 spca508_sightcam2_init_data[][3] = { +/* 35 */ {0x0020, 0x8112}, + +/* 36 */ {0x000f, 0x8402}, +/* 37 */ {0x0000, 0x8403}, + +/* 38 */ {0x0008, 0x8201}, +/* 39 */ {0x0008, 0x8200}, +/* 40 */ {0x0001, 0x8200}, +/* 43 */ {0x0009, 0x8201}, +/* 44 */ {0x0008, 0x8200}, +/* 45 */ {0x0001, 0x8200}, +/* 48 */ {0x000a, 0x8201}, +/* 49 */ {0x0008, 0x8200}, +/* 50 */ {0x0001, 0x8200}, +/* 53 */ {0x000b, 0x8201}, +/* 54 */ {0x0008, 0x8200}, +/* 55 */ {0x0001, 0x8200}, +/* 58 */ {0x000c, 0x8201}, +/* 59 */ {0x0008, 0x8200}, +/* 60 */ {0x0001, 0x8200}, +/* 63 */ {0x000d, 0x8201}, +/* 64 */ {0x0008, 0x8200}, +/* 65 */ {0x0001, 0x8200}, +/* 68 */ {0x000e, 0x8201}, +/* 69 */ {0x0008, 0x8200}, +/* 70 */ {0x0001, 0x8200}, +/* 73 */ {0x0007, 0x8201}, +/* 74 */ {0x0008, 0x8200}, +/* 75 */ {0x0001, 0x8200}, +/* 78 */ {0x000f, 0x8201}, +/* 79 */ {0x0008, 0x8200}, +/* 80 */ {0x0001, 0x8200}, + +/* 84 */ {0x0018, 0x8660}, +/* 85 */ {0x0010, 0x8201}, + +/* 86 */ {0x0008, 0x8200}, +/* 87 */ {0x0001, 0x8200}, +/* 90 */ {0x0011, 0x8201}, +/* 91 */ {0x0008, 0x8200}, +/* 92 */ {0x0001, 0x8200}, + +/* 95 */ {0x0000, 0x86b0}, +/* 96 */ {0x0034, 0x86b1}, +/* 97 */ {0x0000, 0x86b2}, +/* 98 */ {0x0049, 0x86b3}, +/* 99 */ {0x0000, 0x86b4}, +/* 100 */ {0x0000, 0x86b4}, + +/* 101 */ {0x0012, 0x8201}, +/* 102 */ {0x0008, 0x8200}, +/* 103 */ {0x0001, 0x8200}, +/* 106 */ {0x0013, 0x8201}, +/* 107 */ {0x0008, 0x8200}, +/* 108 */ {0x0001, 0x8200}, + +/* 111 */ {0x0001, 0x86b0}, +/* 112 */ {0x00aa, 0x86b1}, +/* 113 */ {0x0000, 0x86b2}, +/* 114 */ {0x00e4, 0x86b3}, +/* 115 */ {0x0000, 0x86b4}, +/* 116 */ {0x0000, 0x86b4}, + +/* 118 */ {0x0018, 0x8660}, + +/* 119 */ {0x0090, 0x8110}, +/* 120 */ {0x0001, 0x8114}, +/* 121 */ {0x0001, 0x8114}, +/* 122 */ {0x0001, 0x8114}, +/* 123 */ {0x0003, 0x8114}, + +/* 124 */ {0x0080, 0x8804}, +/* 157 */ {0x0003, 0x8801}, +/* 158 */ {0x0012, 0x8800}, +/* 160 */ {0x0004, 0x8801}, +/* 161 */ {0x0005, 0x8800}, +/* 163 */ {0x0005, 0x8801}, +/* 164 */ {0x0000, 0x8800}, +/* 166 */ {0x0006, 0x8801}, +/* 167 */ {0x0000, 0x8800}, +/* 169 */ {0x0007, 0x8801}, +/* 170 */ {0x0000, 0x8800}, +/* 172 */ {0x0008, 0x8801}, +/* 173 */ {0x0005, 0x8800}, +/* 175 */ {0x000a, 0x8700}, +/* 176 */ {0x000e, 0x8801}, +/* 177 */ {0x0004, 0x8800}, +/* 179 */ {0x0005, 0x8801}, +/* 180 */ {0x0047, 0x8800}, +/* 182 */ {0x0006, 0x8801}, +/* 183 */ {0x0000, 0x8800}, +/* 185 */ {0x0007, 0x8801}, +/* 186 */ {0x00c0, 0x8800}, +/* 188 */ {0x0008, 0x8801}, +/* 189 */ {0x0003, 0x8800}, +/* 191 */ {0x0013, 0x8801}, +/* 192 */ {0x0001, 0x8800}, +/* 194 */ {0x0009, 0x8801}, +/* 195 */ {0x0000, 0x8800}, +/* 197 */ {0x000a, 0x8801}, +/* 198 */ {0x0000, 0x8800}, +/* 200 */ {0x000b, 0x8801}, +/* 201 */ {0x0000, 0x8800}, +/* 203 */ {0x000c, 0x8801}, +/* 204 */ {0x0000, 0x8800}, +/* 206 */ {0x000e, 0x8801}, +/* 207 */ {0x0004, 0x8800}, +/* 209 */ {0x000f, 0x8801}, +/* 210 */ {0x0000, 0x8800}, +/* 212 */ {0x0010, 0x8801}, +/* 213 */ {0x0006, 0x8800}, +/* 215 */ {0x0011, 0x8801}, +/* 216 */ {0x0006, 0x8800}, +/* 218 */ {0x0012, 0x8801}, +/* 219 */ {0x0000, 0x8800}, +/* 221 */ {0x0013, 0x8801}, +/* 222 */ {0x0001, 0x8800}, + +/* 224 */ {0x000a, 0x8700}, +/* 225 */ {0x0000, 0x8702}, +/* 226 */ {0x0000, 0x8703}, +/* 227 */ {0x00c2, 0x8704}, +/* 228 */ {0x0001, 0x870c}, + +/* 229 */ {0x0044, 0x8600}, +/* 230 */ {0x0002, 0x8606}, +/* 231 */ {0x0064, 0x8607}, +/* 232 */ {0x003a, 0x8601}, +/* 233 */ {0x0008, 0x8602}, +/* 234 */ {0x0044, 0x8600}, +/* 235 */ {0x0018, 0x8617}, +/* 236 */ {0x0008, 0x8618}, +/* 237 */ {0x00a1, 0x8656}, +/* 238 */ {0x0004, 0x865b}, +/* 239 */ {0x0002, 0x865c}, +/* 240 */ {0x0058, 0x865d}, +/* 241 */ {0x0048, 0x865e}, +/* 242 */ {0x0012, 0x8608}, +/* 243 */ {0x002c, 0x8609}, +/* 244 */ {0x0002, 0x860a}, +/* 245 */ {0x002c, 0x860b}, +/* 246 */ {0x00db, 0x860c}, +/* 247 */ {0x00f9, 0x860d}, +/* 248 */ {0x00f1, 0x860e}, +/* 249 */ {0x00e3, 0x860f}, +/* 250 */ {0x002c, 0x8610}, +/* 251 */ {0x006c, 0x8651}, +/* 252 */ {0x0041, 0x8652}, +/* 253 */ {0x0059, 0x8653}, +/* 254 */ {0x0040, 0x8654}, +/* 255 */ {0x00fa, 0x8611}, +/* 256 */ {0x00ff, 0x8612}, +/* 257 */ {0x00f8, 0x8613}, +/* 258 */ {0x0000, 0x8614}, +/* 259 */ {0x0001, 0x863f}, +/* 260 */ {0x0000, 0x8640}, +/* 261 */ {0x0026, 0x8641}, +/* 262 */ {0x0045, 0x8642}, +/* 263 */ {0x0060, 0x8643}, +/* 264 */ {0x0075, 0x8644}, +/* 265 */ {0x0088, 0x8645}, +/* 266 */ {0x009b, 0x8646}, +/* 267 */ {0x00b0, 0x8647}, +/* 268 */ {0x00c5, 0x8648}, +/* 269 */ {0x00d2, 0x8649}, +/* 270 */ {0x00dc, 0x864a}, +/* 271 */ {0x00e5, 0x864b}, +/* 272 */ {0x00eb, 0x864c}, +/* 273 */ {0x00f0, 0x864d}, +/* 274 */ {0x00f6, 0x864e}, +/* 275 */ {0x00fa, 0x864f}, +/* 276 */ {0x00ff, 0x8650}, +/* 277 */ {0x0060, 0x8657}, +/* 278 */ {0x0010, 0x8658}, +/* 279 */ {0x0018, 0x8659}, +/* 280 */ {0x0005, 0x865a}, +/* 281 */ {0x0018, 0x8660}, +/* 282 */ {0x0003, 0x8509}, +/* 283 */ {0x0011, 0x850a}, +/* 284 */ {0x0032, 0x850b}, +/* 285 */ {0x0010, 0x850c}, +/* 286 */ {0x0021, 0x850d}, +/* 287 */ {0x0001, 0x8500}, +/* 288 */ {0x0000, 0x8508}, +/* 289 */ {0x0012, 0x8608}, +/* 290 */ {0x002c, 0x8609}, +/* 291 */ {0x0002, 0x860a}, +/* 292 */ {0x0039, 0x860b}, +/* 293 */ {0x00d0, 0x860c}, +/* 294 */ {0x00f7, 0x860d}, +/* 295 */ {0x00ed, 0x860e}, +/* 296 */ {0x00db, 0x860f}, +/* 297 */ {0x0039, 0x8610}, +/* 298 */ {0x0012, 0x8657}, +/* 299 */ {0x000c, 0x8619}, +/* 300 */ {0x0004, 0x861a}, +/* 301 */ {0x00a1, 0x8656}, +/* 302 */ {0x00c8, 0x8615}, +/* 303 */ {0x0032, 0x8616}, + +/* 306 */ {0x0030, 0x8112}, +/* 313 */ {0x0020, 0x8112}, +/* 314 */ {0x0020, 0x8112}, +/* 315 */ {0x000f, 0x8402}, +/* 316 */ {0x0000, 0x8403}, + +/* 317 */ {0x0090, 0x8110}, +/* 318 */ {0x0001, 0x8114}, +/* 319 */ {0x0001, 0x8114}, +/* 320 */ {0x0001, 0x8114}, +/* 321 */ {0x0003, 0x8114}, +/* 322 */ {0x0080, 0x8804}, + +/* 355 */ {0x0003, 0x8801}, +/* 356 */ {0x0012, 0x8800}, +/* 358 */ {0x0004, 0x8801}, +/* 359 */ {0x0005, 0x8800}, +/* 361 */ {0x0005, 0x8801}, +/* 362 */ {0x0047, 0x8800}, +/* 364 */ {0x0006, 0x8801}, +/* 365 */ {0x0000, 0x8800}, +/* 367 */ {0x0007, 0x8801}, +/* 368 */ {0x00c0, 0x8800}, +/* 370 */ {0x0008, 0x8801}, +/* 371 */ {0x0003, 0x8800}, +/* 373 */ {0x000a, 0x8700}, +/* 374 */ {0x000e, 0x8801}, +/* 375 */ {0x0004, 0x8800}, +/* 377 */ {0x0005, 0x8801}, +/* 378 */ {0x0047, 0x8800}, +/* 380 */ {0x0006, 0x8801}, +/* 381 */ {0x0000, 0x8800}, +/* 383 */ {0x0007, 0x8801}, +/* 384 */ {0x00c0, 0x8800}, +/* 386 */ {0x0008, 0x8801}, +/* 387 */ {0x0003, 0x8800}, +/* 389 */ {0x0013, 0x8801}, +/* 390 */ {0x0001, 0x8800}, +/* 392 */ {0x0009, 0x8801}, +/* 393 */ {0x0000, 0x8800}, +/* 395 */ {0x000a, 0x8801}, +/* 396 */ {0x0000, 0x8800}, +/* 398 */ {0x000b, 0x8801}, +/* 399 */ {0x0000, 0x8800}, +/* 401 */ {0x000c, 0x8801}, +/* 402 */ {0x0000, 0x8800}, +/* 404 */ {0x000e, 0x8801}, +/* 405 */ {0x0004, 0x8800}, +/* 407 */ {0x000f, 0x8801}, +/* 408 */ {0x0000, 0x8800}, +/* 410 */ {0x0010, 0x8801}, +/* 411 */ {0x0006, 0x8800}, +/* 413 */ {0x0011, 0x8801}, +/* 414 */ {0x0006, 0x8800}, +/* 416 */ {0x0012, 0x8801}, +/* 417 */ {0x0000, 0x8800}, +/* 419 */ {0x0013, 0x8801}, +/* 420 */ {0x0001, 0x8800}, +/* 422 */ {0x000a, 0x8700}, +/* 423 */ {0x0000, 0x8702}, +/* 424 */ {0x0000, 0x8703}, +/* 425 */ {0x00c2, 0x8704}, +/* 426 */ {0x0001, 0x870c}, +/* 427 */ {0x0044, 0x8600}, +/* 428 */ {0x0002, 0x8606}, +/* 429 */ {0x0064, 0x8607}, +/* 430 */ {0x003a, 0x8601}, +/* 431 */ {0x0008, 0x8602}, +/* 432 */ {0x0044, 0x8600}, +/* 433 */ {0x0018, 0x8617}, +/* 434 */ {0x0008, 0x8618}, +/* 435 */ {0x00a1, 0x8656}, +/* 436 */ {0x0004, 0x865b}, +/* 437 */ {0x0002, 0x865c}, +/* 438 */ {0x0058, 0x865d}, +/* 439 */ {0x0048, 0x865e}, +/* 440 */ {0x0012, 0x8608}, +/* 441 */ {0x002c, 0x8609}, +/* 442 */ {0x0002, 0x860a}, +/* 443 */ {0x002c, 0x860b}, +/* 444 */ {0x00db, 0x860c}, +/* 445 */ {0x00f9, 0x860d}, +/* 446 */ {0x00f1, 0x860e}, +/* 447 */ {0x00e3, 0x860f}, +/* 448 */ {0x002c, 0x8610}, +/* 449 */ {0x006c, 0x8651}, +/* 450 */ {0x0041, 0x8652}, +/* 451 */ {0x0059, 0x8653}, +/* 452 */ {0x0040, 0x8654}, +/* 453 */ {0x00fa, 0x8611}, +/* 454 */ {0x00ff, 0x8612}, +/* 455 */ {0x00f8, 0x8613}, +/* 456 */ {0x0000, 0x8614}, +/* 457 */ {0x0001, 0x863f}, +/* 458 */ {0x0000, 0x8640}, +/* 459 */ {0x0026, 0x8641}, +/* 460 */ {0x0045, 0x8642}, +/* 461 */ {0x0060, 0x8643}, +/* 462 */ {0x0075, 0x8644}, +/* 463 */ {0x0088, 0x8645}, +/* 464 */ {0x009b, 0x8646}, +/* 465 */ {0x00b0, 0x8647}, +/* 466 */ {0x00c5, 0x8648}, +/* 467 */ {0x00d2, 0x8649}, +/* 468 */ {0x00dc, 0x864a}, +/* 469 */ {0x00e5, 0x864b}, +/* 470 */ {0x00eb, 0x864c}, +/* 471 */ {0x00f0, 0x864d}, +/* 472 */ {0x00f6, 0x864e}, +/* 473 */ {0x00fa, 0x864f}, +/* 474 */ {0x00ff, 0x8650}, +/* 475 */ {0x0060, 0x8657}, +/* 476 */ {0x0010, 0x8658}, +/* 477 */ {0x0018, 0x8659}, +/* 478 */ {0x0005, 0x865a}, +/* 479 */ {0x0018, 0x8660}, +/* 480 */ {0x0003, 0x8509}, +/* 481 */ {0x0011, 0x850a}, +/* 482 */ {0x0032, 0x850b}, +/* 483 */ {0x0010, 0x850c}, +/* 484 */ {0x0021, 0x850d}, +/* 485 */ {0x0001, 0x8500}, +/* 486 */ {0x0000, 0x8508}, + +/* 487 */ {0x0012, 0x8608}, +/* 488 */ {0x002c, 0x8609}, +/* 489 */ {0x0002, 0x860a}, +/* 490 */ {0x0039, 0x860b}, +/* 491 */ {0x00d0, 0x860c}, +/* 492 */ {0x00f7, 0x860d}, +/* 493 */ {0x00ed, 0x860e}, +/* 494 */ {0x00db, 0x860f}, +/* 495 */ {0x0039, 0x8610}, +/* 496 */ {0x0012, 0x8657}, +/* 497 */ {0x0064, 0x8619}, + +/* This line starts it all, it is not needed here */ +/* since it has been build into the driver */ +/* jfm: don't start now */ +/* 590 * {0x0030, 0x8112}, */ + {} +}; + +/* + * Initialization data for Creative Webcam Vista + */ +static __u16 spca508_vista_init_data[][3] = { + {0x0008, 0x8200}, /* Clear register */ + {0x0000, 0x870b}, /* Reset CTL3 */ + {0x0020, 0x8112}, /* Video Drop packet enable */ + {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ + {0x0000, 0x8110}, /* Disable everything */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8114}, + + {0x0003, 0x8111}, + {0x0000, 0x8111}, + {0x0090, 0x8110}, /* Enable: SSI output, External 2X clock output */ + {0x0020, 0x8112}, + {0x0000, 0x8114}, + {0x0001, 0x8114}, + {0x0001, 0x8114}, + {0x0001, 0x8114}, + {0x0003, 0x8114}, + + {0x000f, 0x8402}, /* Memory bank Address */ + {0x0000, 0x8403}, /* Memory bank Address */ + {0x00ba, 0x8804}, /* SSI Slave address */ + {0x0010, 0x8802}, /* 93.75kHz SSI Clock Two DataByte */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, /* Will write 2 bytes (DATA1+DATA2) */ + {0x0020, 0x8801}, /* Register address for SSI read/write */ + {0x0044, 0x8805}, /* DATA2 */ + {0x0004, 0x8800}, /* DATA1 -> write triggered */ + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0009, 0x8801}, + {0x0042, 0x8805}, + {0x0001, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x003c, 0x8801}, + {0x0001, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0001, 0x8801}, + {0x000a, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0002, 0x8801}, + {0x0000, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0003, 0x8801}, + {0x0027, 0x8805}, + {0x0001, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0004, 0x8801}, + {0x0065, 0x8805}, + {0x0001, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0005, 0x8801}, + {0x0003, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0006, 0x8801}, + {0x001c, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0007, 0x8801}, + {0x002a, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x000e, 0x8801}, + {0x0000, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0028, 0x8801}, + {0x002e, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0039, 0x8801}, + {0x0013, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x003b, 0x8801}, + {0x000c, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0035, 0x8801}, + {0x0028, 0x8805}, + {0x0000, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + /* READ { 0, 0x0001, 0x8802 } -> + 0000: 10 */ + {0x0010, 0x8802}, + {0x0009, 0x8801}, + {0x0042, 0x8805}, + {0x0001, 0x8800}, + /* READ { 0, 0x0001, 0x8803 } -> + 0000: 00 */ + + {0x0050, 0x8703}, + {0x0002, 0x8704}, /* External input CKIx1 */ + {0x0001, 0x870C}, /* Select CKOx2 output */ + {0x009A, 0x8600}, /* Line memory Read Counter (L) */ + {0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */ + {0x0023, 0x8601}, + {0x0010, 0x8602}, + {0x000A, 0x8603}, + {0x009A, 0x8600}, + {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */ + {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */ + {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */ + {0x0048, 0x865E}, /* Vertical valid lines window (L) */ + {0x0000, 0x865F}, + + {0x0006, 0x8660}, + /* Enable nibble data input, select nibble input order */ + + {0x0013, 0x8608}, /* A11 Coeficients for color correction */ + {0x0028, 0x8609}, + /* Note: these values are confirmed at the end of array */ + {0x0005, 0x860A}, /* ... */ + {0x0025, 0x860B}, + {0x00E1, 0x860C}, + {0x00FA, 0x860D}, + {0x00F4, 0x860E}, + {0x00E8, 0x860F}, + {0x0025, 0x8610}, /* A33 Coef. */ + {0x00FC, 0x8611}, /* White balance offset: R */ + {0x0001, 0x8612}, /* White balance offset: Gr */ + {0x00FE, 0x8613}, /* White balance offset: B */ + {0x0000, 0x8614}, /* White balance offset: Gb */ + + {0x0064, 0x8651}, /* R gain for white balance (L) */ + {0x0040, 0x8652}, /* Gr gain for white balance (L) */ + {0x0066, 0x8653}, /* B gain for white balance (L) */ + {0x0040, 0x8654}, /* Gb gain for white balance (L) */ + {0x0001, 0x863F}, /* Enable fixed gamma correction */ + + {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */ + /* UV division: UV no change, Enable New edge enhancement */ + {0x0018, 0x8657}, /* Edge gain high threshold */ + {0x0020, 0x8658}, /* Edge gain low threshold */ + {0x000A, 0x8659}, /* Edge bandwidth high threshold */ + {0x0005, 0x865A}, /* Edge bandwidth low threshold */ + {0x0064, 0x8607}, /* UV filter enable */ + + {0x0016, 0x8660}, + {0x0000, 0x86B0}, /* Bad pixels compensation address */ + {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */ + {0x0000, 0x86B2}, + {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */ + {0x0000, 0x86B4}, + + {0x0001, 0x86B0}, + {0x00F5, 0x86B1}, + {0x0000, 0x86B2}, + {0x00C6, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0002, 0x86B0}, + {0x001C, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D7, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0003, 0x86B0}, + {0x001C, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D8, 0x86B3}, + {0x0000, 0x86B4}, + + {0x0004, 0x86B0}, + {0x001D, 0x86B1}, + {0x0001, 0x86B2}, + {0x00D8, 0x86B3}, + {0x0000, 0x86B4}, + {0x001E, 0x8660}, + + /* READ { 0, 0x0000, 0x8608 } -> + 0000: 13 */ + /* READ { 0, 0x0000, 0x8609 } -> + 0000: 28 */ + /* READ { 0, 0x0000, 0x8610 } -> + 0000: 05 */ + /* READ { 0, 0x0000, 0x8611 } -> + 0000: 25 */ + /* READ { 0, 0x0000, 0x8612 } -> + 0000: e1 */ + /* READ { 0, 0x0000, 0x8613 } -> + 0000: fa */ + /* READ { 0, 0x0000, 0x8614 } -> + 0000: f4 */ + /* READ { 0, 0x0000, 0x8615 } -> + 0000: e8 */ + /* READ { 0, 0x0000, 0x8616 } -> + 0000: 25 */ + {} +}; + +static int reg_write(struct usb_device *dev, + __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, /* request */ + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x", + index, value); + if (ret < 0) + PDEBUG(D_ERR|D_USBO, "reg write: error %d", ret); + return ret; +} + +/* read 1 byte */ +/* returns: negative is error, pos or zero is data */ +static int reg_read(struct usb_device *dev, + __u16 index) /* wIndex */ +{ + int ret; + __u8 data; + + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, /* register */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + (__u16) 0, /* value */ + index, + &data, 1, + 500); /* timeout */ + PDEBUG(D_USBI, "reg read i:%04x --> %02x", index, data); + if (ret < 0) { + PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); + return ret; + } + return data; +} + +static int write_vector(struct gspca_dev *gspca_dev, + __u16 data[][3]) +{ + struct usb_device *dev = gspca_dev->dev; + int ret, i = 0; + + while (data[i][1] != 0) { + ret = reg_write(dev, data[i][1], data[i][0]); + if (ret < 0) + return ret; + i++; + } + return 0; +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct cam *cam; + __u16 vendor; + __u16 product; + int data1, data2; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x041e: /* Creative cameras */ +/* switch (product) { */ +/* case 0x4018: */ + sd->subtype = CreativeVista; +/* break; */ +/* } */ + break; + case 0x0461: /* MicroInnovation */ +/* switch (product) { */ +/* case 0x0815: */ + sd->subtype = MicroInnovationIC200; +/* break; */ +/* } */ + break; + case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ +/* switch (product) { */ +/* case 0x110: */ + sd->subtype = ViewQuestVQ110; +/* break; */ +/* } */ + break; + case 0x0af9: /* Hama cameras */ + switch (product) { + case 0x0010: + sd->subtype = HamaUSBSightcam; + break; + case 0x0011: + sd->subtype = HamaUSBSightcam2; + break; + } + break; + case 0x8086: /* Intel */ +/* switch (product) { */ +/* case 0x0110: */ + sd->subtype = IntelEasyPCCamera; +/* break; */ +/* } */ + break; + } + + /* Read from global register the USB product and vendor IDs, just to */ + /* prove that we can communicate with the device. This works, which */ + /* confirms at we are communicating properly and that the device */ + /* is a 508. */ + data1 = reg_read(dev, 0x8104); + data2 = reg_read(dev, 0x8105); + PDEBUG(D_PROBE, + "Read from GLOBAL: USB Vendor ID 0x%02x%02x", data2, data1); + + data1 = reg_read(dev, 0x8106); + data2 = reg_read(dev, 0x8107); + PDEBUG(D_PROBE, + "Read from GLOBAL: USB Product ID 0x%02x%02x", data2, data1); + + data1 = reg_read(dev, 0x8621); + PDEBUG(D_PROBE, + "Read from GLOBAL: Window 1 average luminance %d", data1); + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + + switch (sd->subtype) { + case ViewQuestVQ110: + if (write_vector(gspca_dev, spca508_init_data)) + return -1; + break; + default: +/* case MicroInnovationIC200: */ +/* case IntelEasyPCCamera: */ + if (write_vector(gspca_dev, spca508cs110_init_data)) + return -1; + break; + case HamaUSBSightcam: + if (write_vector(gspca_dev, spca508_sightcam_init_data)) + return -1; + break; + case HamaUSBSightcam2: + if (write_vector(gspca_dev, spca508_sightcam2_init_data)) + return -1; + break; + case CreativeVista: + if (write_vector(gspca_dev, spca508_vista_init_data)) + return -1; + break; + } + return 0; /* success */ +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ +/* write_vector(gspca_dev, spca508_open_data); */ + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + int mode; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + reg_write(gspca_dev->dev, 0x8500, mode); + switch (mode) { + case 0: + case 1: + reg_write(gspca_dev->dev, 0x8700, 0x28); /* clock */ + break; + default: +/* case 2: */ +/* case 3: */ + reg_write(gspca_dev->dev, 0x8700, 0x23); /* clock */ + break; + } + reg_write(gspca_dev->dev, 0x8112, 0x10 | 0x20); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + /* Video ISO disable, Video Drop Packet enable: */ + reg_write(gspca_dev->dev, 0x8112, 0x20); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +/* convert YUVY per line to YUYV (YUV 4:2:2) */ +static void yuvy_decode(unsigned char *out, + unsigned char *in, + int width, + int height) +{ + unsigned char *Ui, *Vi, *yi, *yi1; + unsigned char *out1; + int i, j; + + yi = in; + for (i = height / 2; --i >= 0; ) { + out1 = out + width * 2; /* next line */ + Ui = yi + width; + Vi = Ui + width / 2; + yi1 = Vi + width / 2; + for (j = width / 2; --j >= 0; ) { + *out++ = 128 + *yi++; + *out++ = 128 + *Ui; + *out++ = 128 + *yi++; + *out++ = 128 + *Vi; + + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Ui++; + *out1++ = 128 + *yi1++; + *out1++ = 128 + *Vi++; + } + yi += width * 2; + out = out1; + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (data[0]) { + case 0: /* start of frame */ + if (gspca_dev->last_packet_type == FIRST_PACKET) { + yuvy_decode(sd->tmpbuf2, sd->tmpbuf, + gspca_dev->width, + gspca_dev->height); + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, + sd->tmpbuf2, + gspca_dev->width + * gspca_dev->height + * 2); + } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, 0); + data += SPCA508_OFFSET_DATA; + len -= SPCA508_OFFSET_DATA; + if (len > 0) + memcpy(sd->tmpbuf, data, len); + else + len = 0; + sd->buflen = len; + return; + case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + data += 1; + len -= 1; + memcpy(&sd->tmpbuf[sd->buflen], data, len); + sd->buflen += len; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 brightness = sd->brightness; + +/* MX seem contrast */ + reg_write(gspca_dev->dev, 0x8651, brightness); + reg_write(gspca_dev->dev, 0x8652, brightness); + reg_write(gspca_dev->dev, 0x8653, brightness); + reg_write(gspca_dev->dev, 0x8654, brightness); +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = reg_read(gspca_dev->dev, 0x8651); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, + {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, + {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, + {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, + {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, + {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c new file mode 100644 index 000000000000..a94e6270115e --- /dev/null +++ b/drivers/media/video/gspca/spca561.c @@ -0,0 +1,1025 @@ +/* + * Sunplus spca561 subdriver + * + * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "spca561" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned short contrast; + __u8 brightness; + __u8 autogain; + + __u8 chip_revision; + signed char ag_cnt; +#define AG_CNT_START 13 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 63, + .step = 1, + .default_value = 32, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0x3fff, + .step = 1, + .default_value = 0x2000, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_AUTOGAIN 2 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_SPCA561, 160, 120, 3}, + {V4L2_PIX_FMT_SPCA561, 176, 144, 2}, + {V4L2_PIX_FMT_SPCA561, 320, 240, 1}, + {V4L2_PIX_FMT_SPCA561, 352, 288, 0}, +}; + +/* + * Initialization data + * I'm not very sure how to split initialization from open data + * chunks. For now, we'll consider everything as initialization + */ +/* Frame packet header offsets for the spca561 */ +#define SPCA561_OFFSET_SNAP 1 +#define SPCA561_OFFSET_TYPE 2 +#define SPCA561_OFFSET_COMPRESS 3 +#define SPCA561_OFFSET_FRAMSEQ 4 +#define SPCA561_OFFSET_GPIO 5 +#define SPCA561_OFFSET_USBBUFF 6 +#define SPCA561_OFFSET_WIN2GRAVE 7 +#define SPCA561_OFFSET_WIN2RAVE 8 +#define SPCA561_OFFSET_WIN2BAVE 9 +#define SPCA561_OFFSET_WIN2GBAVE 10 +#define SPCA561_OFFSET_WIN1GRAVE 11 +#define SPCA561_OFFSET_WIN1RAVE 12 +#define SPCA561_OFFSET_WIN1BAVE 13 +#define SPCA561_OFFSET_WIN1GBAVE 14 +#define SPCA561_OFFSET_FREQ 15 +#define SPCA561_OFFSET_VSYNC 16 +#define SPCA561_OFFSET_DATA 1 +#define SPCA561_INDEX_I2C_BASE 0x8800 +#define SPCA561_SNAPBIT 0x20 +#define SPCA561_SNAPCTRL 0x40 +enum { + Rev072A = 0, + Rev012A, +}; + +static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0, /* request */ + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value); + if (ret < 0) + PDEBUG(D_ERR, "reg write: error %d", ret); +} + +static void write_vector(struct gspca_dev *gspca_dev, __u16 data[][2]) +{ + struct usb_device *dev = gspca_dev->dev; + int i; + + i = 0; + while (data[i][1] != 0) { + reg_w_val(dev, data[i][1], data[i][0]); + i++; + } +} + +static void reg_r(struct usb_device *dev, + __u16 index, __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, 500); +} + +static void reg_w_buf(struct usb_device *dev, + __u16 index, __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, 500); +} + +static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) +{ + reg_w_val(gspca_dev->dev, 0x92, 0x8804); + reg_w_val(gspca_dev->dev, mode, 0x8802); +} + +static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) +{ + int retry = 60; + __u8 DataLow; + __u8 DataHight; + __u8 Data; + + DataLow = valeur; + DataHight = valeur >> 8; + reg_w_val(gspca_dev->dev, reg, 0x8801); + reg_w_val(gspca_dev->dev, DataLow, 0x8805); + reg_w_val(gspca_dev->dev, DataHight, 0x8800); + while (retry--) { + reg_r(gspca_dev->dev, 0x8803, &Data, 1); + if (!Data) + break; + } +} + +static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) +{ + int retry = 60; + __u8 value; + __u8 vallsb; + __u8 Data; + + reg_w_val(gspca_dev->dev, 0x92, 0x8804); + reg_w_val(gspca_dev->dev, reg, 0x8801); + reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); + while (retry--) { + reg_r(gspca_dev->dev, 0x8803, &Data, 1); + if (!Data) + break; + } + if (retry == 0) + return -1; + reg_r(gspca_dev->dev, 0x8800, &value, 1); + reg_r(gspca_dev->dev, 0x8805, &vallsb, 1); + return ((int) value << 8) | vallsb; +} + +static __u16 spca561_init_data[][2] = { + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0001, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8112}, /* Some kind of reset */ + {0x0003, 0x8701}, /* PCLK clock delay adjustment */ + {0x0001, 0x8703}, /* HSYNC from cmos inverted */ + {0x0011, 0x8118}, /* Enable and conf sensor */ + {0x0001, 0x8118}, /* Conf sensor */ + {0x0092, 0x8804}, /* I know nothing about these */ + {0x0010, 0x8802}, /* 0x88xx registers, so I won't */ + /***************/ + {0x000d, 0x8805}, /* sensor default setting */ + {0x0001, 0x8801}, /* 1 <- 0x0d */ + {0x0000, 0x8800}, + {0x0018, 0x8805}, + {0x0002, 0x8801}, /* 2 <- 0x18 */ + {0x0000, 0x8800}, + {0x0065, 0x8805}, + {0x0004, 0x8801}, /* 4 <- 0x01 0x65 */ + {0x0001, 0x8800}, + {0x0021, 0x8805}, + {0x0005, 0x8801}, /* 5 <- 0x21 */ + {0x0000, 0x8800}, + {0x00aa, 0x8805}, + {0x0007, 0x8801}, /* 7 <- 0xaa */ + {0x0000, 0x8800}, + {0x0004, 0x8805}, + {0x0020, 0x8801}, /* 0x20 <- 0x15 0x04 */ + {0x0015, 0x8800}, + {0x0002, 0x8805}, + {0x0039, 0x8801}, /* 0x39 <- 0x02 */ + {0x0000, 0x8800}, + {0x0010, 0x8805}, + {0x0035, 0x8801}, /* 0x35 <- 0x10 */ + {0x0000, 0x8800}, + {0x0049, 0x8805}, + {0x0009, 0x8801}, /* 0x09 <- 0x10 0x49 */ + {0x0010, 0x8800}, + {0x000b, 0x8805}, + {0x0028, 0x8801}, /* 0x28 <- 0x0b */ + {0x0000, 0x8800}, + {0x000f, 0x8805}, + {0x003b, 0x8801}, /* 0x3b <- 0x0f */ + {0x0000, 0x8800}, + {0x0000, 0x8805}, + {0x003c, 0x8801}, /* 0x3c <- 0x00 */ + {0x0000, 0x8800}, + /***************/ + {0x0018, 0x8601}, /* Pixel/line selection for color separation */ + {0x0000, 0x8602}, /* Optical black level for user setting */ + {0x0060, 0x8604}, /* Optical black horizontal offset */ + {0x0002, 0x8605}, /* Optical black vertical offset */ + {0x0000, 0x8603}, /* Non-automatic optical black level */ + {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ + {0x0000, 0x865f}, /* Vertical valid pixels window (x2) */ + {0x00b0, 0x865d}, /* Horizontal valid pixels window (x2) */ + {0x0090, 0x865e}, /* Vertical valid lines window (x2) */ + {0x00e0, 0x8406}, /* Memory buffer threshold */ + {0x0000, 0x8660}, /* Compensation memory stuff */ + {0x0002, 0x8201}, /* Output address for r/w serial EEPROM */ + {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ + {0x0001, 0x8200}, /* OprMode to be executed by hardware */ + {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */ + {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */ + {0x0001, 0x8200}, /* OprMode to be executed by hardware */ + {0x0010, 0x8660}, /* Compensation memory stuff */ + {0x0018, 0x8660}, /* Compensation memory stuff */ + + {0x0004, 0x8611}, /* R offset for white balance */ + {0x0004, 0x8612}, /* Gr offset for white balance */ + {0x0007, 0x8613}, /* B offset for white balance */ + {0x0000, 0x8614}, /* Gb offset for white balance */ + {0x008c, 0x8651}, /* R gain for white balance */ + {0x008c, 0x8652}, /* Gr gain for white balance */ + {0x00b5, 0x8653}, /* B gain for white balance */ + {0x008c, 0x8654}, /* Gb gain for white balance */ + {0x0002, 0x8502}, /* Maximum average bit rate stuff */ + + {0x0011, 0x8802}, + {0x0087, 0x8700}, /* Set master clock (96Mhz????) */ + {0x0081, 0x8702}, /* Master clock output enable */ + + {0x0000, 0x8500}, /* Set image type (352x288 no compression) */ + /* Originally was 0x0010 (352x288 compression) */ + + {0x0002, 0x865b}, /* Horizontal offset for valid pixels */ + {0x0003, 0x865c}, /* Vertical offset for valid lines */ + /***************//* sensor active */ + {0x0003, 0x8801}, /* 0x03 <- 0x01 0x21 //289 */ + {0x0021, 0x8805}, + {0x0001, 0x8800}, + {0x0004, 0x8801}, /* 0x04 <- 0x01 0x65 //357 */ + {0x0065, 0x8805}, + {0x0001, 0x8800}, + {0x0005, 0x8801}, /* 0x05 <- 0x2f */ + {0x002f, 0x8805}, + {0x0000, 0x8800}, + {0x0006, 0x8801}, /* 0x06 <- 0 */ + {0x0000, 0x8805}, + {0x0000, 0x8800}, + {0x000a, 0x8801}, /* 0x0a <- 2 */ + {0x0002, 0x8805}, + {0x0000, 0x8800}, + {0x0009, 0x8801}, /* 0x09 <- 0x1061 */ + {0x0061, 0x8805}, + {0x0010, 0x8800}, + {0x0035, 0x8801}, /* 0x35 <-0x14 */ + {0x0014, 0x8805}, + {0x0000, 0x8800}, + {0x0030, 0x8112}, /* ISO and drop packet enable */ + {0x0000, 0x8112}, /* Some kind of reset ???? */ + {0x0009, 0x8118}, /* Enable sensor and set standby */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8114}, /* Software GPIO output data */ + {0x0001, 0x8114}, /* Software GPIO output data */ + {0x0000, 0x8112}, /* Some kind of reset ??? */ + {0x0003, 0x8701}, + {0x0001, 0x8703}, + {0x0011, 0x8118}, + {0x0001, 0x8118}, + /***************/ + {0x0092, 0x8804}, + {0x0010, 0x8802}, + {0x000d, 0x8805}, + {0x0001, 0x8801}, + {0x0000, 0x8800}, + {0x0018, 0x8805}, + {0x0002, 0x8801}, + {0x0000, 0x8800}, + {0x0065, 0x8805}, + {0x0004, 0x8801}, + {0x0001, 0x8800}, + {0x0021, 0x8805}, + {0x0005, 0x8801}, + {0x0000, 0x8800}, + {0x00aa, 0x8805}, + {0x0007, 0x8801}, /* mode 0xaa */ + {0x0000, 0x8800}, + {0x0004, 0x8805}, + {0x0020, 0x8801}, + {0x0015, 0x8800}, /* mode 0x0415 */ + {0x0002, 0x8805}, + {0x0039, 0x8801}, + {0x0000, 0x8800}, + {0x0010, 0x8805}, + {0x0035, 0x8801}, + {0x0000, 0x8800}, + {0x0049, 0x8805}, + {0x0009, 0x8801}, + {0x0010, 0x8800}, + {0x000b, 0x8805}, + {0x0028, 0x8801}, + {0x0000, 0x8800}, + {0x000f, 0x8805}, + {0x003b, 0x8801}, + {0x0000, 0x8800}, + {0x0000, 0x8805}, + {0x003c, 0x8801}, + {0x0000, 0x8800}, + {0x0002, 0x8502}, + {0x0039, 0x8801}, + {0x0000, 0x8805}, + {0x0000, 0x8800}, + + {0x0087, 0x8700}, /* overwrite by start */ + {0x0081, 0x8702}, + {0x0000, 0x8500}, +/* {0x0010, 0x8500}, -- Previous line was this */ + {0x0002, 0x865b}, + {0x0003, 0x865c}, + /***************/ + {0x0003, 0x8801}, /* 0x121-> 289 */ + {0x0021, 0x8805}, + {0x0001, 0x8800}, + {0x0004, 0x8801}, /* 0x165 -> 357 */ + {0x0065, 0x8805}, + {0x0001, 0x8800}, + {0x0005, 0x8801}, /* 0x2f //blanking control colonne */ + {0x002f, 0x8805}, + {0x0000, 0x8800}, + {0x0006, 0x8801}, /* 0x00 //blanking mode row */ + {0x0000, 0x8805}, + {0x0000, 0x8800}, + {0x000a, 0x8801}, /* 0x01 //0x02 */ + {0x0001, 0x8805}, + {0x0000, 0x8800}, + {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock + * 0001 0 | 000 0110 0001 */ + {0x0061, 0x8805}, /* 61 31 */ + {0x0008, 0x8800}, /* 08 */ + {0x0035, 0x8801}, /* 0x14 - set gain general */ + {0x001f, 0x8805}, /* 0x14 */ + {0x0000, 0x8800}, + {0x0030, 0x8112}, + {} +}; + +static void sensor_reset(struct gspca_dev *gspca_dev) +{ + reg_w_val(gspca_dev->dev, 0x8631, 0xc8); + reg_w_val(gspca_dev->dev, 0x8634, 0xc8); + reg_w_val(gspca_dev->dev, 0x8112, 0x00); + reg_w_val(gspca_dev->dev, 0x8114, 0x00); + reg_w_val(gspca_dev->dev, 0x8118, 0x21); + i2c_init(gspca_dev, 0x14); + i2c_write(gspca_dev, 1, 0x0d); + i2c_write(gspca_dev, 0, 0x0d); +} + +/******************** QC Express etch2 stuff ********************/ +static __u16 Pb100_1map8300[][2] = { + /* reg, value */ + {0x8320, 0x3304}, + + {0x8303, 0x0125}, /* image area */ + {0x8304, 0x0169}, + {0x8328, 0x000b}, + {0x833c, 0x0001}, + + {0x832f, 0x0419}, + {0x8307, 0x00aa}, + {0x8301, 0x0003}, + {0x8302, 0x000e}, + {} +}; +static __u16 Pb100_2map8300[][2] = { + /* reg, value */ + {0x8339, 0x0000}, + {0x8307, 0x00aa}, + {} +}; + +static __u16 spca561_161rev12A_data1[][2] = { + {0x21, 0x8118}, + {0x01, 0x8114}, + {0x00, 0x8112}, + {0x92, 0x8804}, + {0x04, 0x8802}, /* windows uses 08 */ + {} +}; +static __u16 spca561_161rev12A_data2[][2] = { + {0x21, 0x8118}, + {0x10, 0x8500}, + {0x07, 0x8601}, + {0x07, 0x8602}, + {0x04, 0x8501}, + {0x21, 0x8118}, + + {0x07, 0x8201}, /* windows uses 02 */ + {0x08, 0x8200}, + {0x01, 0x8200}, + + {0x00, 0x8114}, + {0x01, 0x8114}, /* windows uses 00 */ + + {0x90, 0x8604}, + {0x00, 0x8605}, + {0xb0, 0x8603}, + + /* sensor gains */ + {0x00, 0x8610}, /* *red */ + {0x00, 0x8611}, /* 3f *green */ + {0x00, 0x8612}, /* green *blue */ + {0x00, 0x8613}, /* blue *green */ + {0x35, 0x8614}, /* green *red */ + {0x35, 0x8615}, /* 40 *green */ + {0x35, 0x8616}, /* 7a *blue */ + {0x35, 0x8617}, /* 40 *green */ + + {0x0c, 0x8620}, /* 0c */ + {0xc8, 0x8631}, /* c8 */ + {0xc8, 0x8634}, /* c8 */ + {0x23, 0x8635}, /* 23 */ + {0x1f, 0x8636}, /* 1f */ + {0xdd, 0x8637}, /* dd */ + {0xe1, 0x8638}, /* e1 */ + {0x1d, 0x8639}, /* 1d */ + {0x21, 0x863a}, /* 21 */ + {0xe3, 0x863b}, /* e3 */ + {0xdf, 0x863c}, /* df */ + {0xf0, 0x8505}, + {0x32, 0x850a}, + {} +}; + +static void sensor_mapwrite(struct gspca_dev *gspca_dev, + __u16 sensormap[][2]) +{ + int i = 0; + __u8 usbval[2]; + + while (sensormap[i][0]) { + usbval[0] = sensormap[i][1]; + usbval[1] = sensormap[i][1] >> 8; + reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2); + i++; + } +} +static void init_161rev12A(struct gspca_dev *gspca_dev) +{ + sensor_reset(gspca_dev); + write_vector(gspca_dev, spca561_161rev12A_data1); + sensor_mapwrite(gspca_dev, Pb100_1map8300); + write_vector(gspca_dev, spca561_161rev12A_data2); + sensor_mapwrite(gspca_dev, Pb100_2map8300); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct cam *cam; + __u16 vendor, product; + __u8 data1, data2; + + /* Read frm global register the USB product and vendor IDs, just to + * prove that we can communicate with the device. This works, which + * confirms at we are communicating properly and that the device + * is a 561. */ + reg_r(dev, 0x8104, &data1, 1); + reg_r(dev, 0x8105, &data2, 1); + vendor = (data2 << 8) | data1; + reg_r(dev, 0x8106, &data1, 1); + reg_r(dev, 0x8107, &data2, 1); + product = (data2 << 8) | data1; + if (vendor != id->idVendor || product != id->idProduct) { + PDEBUG(D_PROBE, "Bad vendor / product from device"); + return -EINVAL; + } + switch (product) { + case 0x0928: + case 0x0929: + case 0x092a: + case 0x092b: + case 0x092c: + case 0x092d: + case 0x092e: + case 0x092f: + case 0x403b: + sd->chip_revision = Rev012A; + break; + default: +/* case 0x0561: + case 0x0815: * ?? in spca508.c + case 0x401a: + case 0x7004: + case 0x7e50: + case 0xa001: + case 0xcdee: */ + sd->chip_revision = Rev072A; + break; + } + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->chip_revision) { + case Rev072A: + PDEBUG(D_STREAM, "Chip revision id: 072a"); + write_vector(gspca_dev, spca561_init_data); + break; + default: +/* case Rev012A: */ + PDEBUG(D_STREAM, "Chip revision id: 012a"); + init_161rev12A(gspca_dev); + break; + } + return 0; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 lowb; + int expotimes; + + switch (sd->chip_revision) { + case Rev072A: + lowb = sd->contrast >> 8; + reg_w_val(dev, lowb, 0x8651); + reg_w_val(dev, lowb, 0x8652); + reg_w_val(dev, lowb, 0x8653); + reg_w_val(dev, lowb, 0x8654); + break; + case Rev012A: { + __u8 Reg8391[] = + { 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00 }; + + /* Write camera sensor settings */ + expotimes = (sd->contrast >> 5) & 0x07ff; + Reg8391[0] = expotimes & 0xff; /* exposure */ + Reg8391[1] = 0x18 | (expotimes >> 8); + Reg8391[2] = sd->brightness; /* gain */ + reg_w_buf(dev, 0x8391, Reg8391, 8); + reg_w_buf(dev, 0x8390, Reg8391, 8); + break; + } + } +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int Clck; + __u8 Reg8307[] = { 0xaa, 0x00 }; + int mode; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + switch (sd->chip_revision) { + case Rev072A: + switch (mode) { + default: +/* case 0: + case 1: */ + Clck = 0x25; + break; + case 2: + Clck = 0x22; + break; + case 3: + Clck = 0x21; + break; + } + reg_w_val(dev, 0x8500, mode); /* mode */ + reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */ + reg_w_val(dev, 0x8112, 0x10 | 0x20); + break; + default: +/* case Rev012A: */ + switch (mode) { + case 0: + case 1: + Clck = 0x8a; + break; + case 2: + Clck = 0x85; + break; + default: + Clck = 0x83; + break; + } + if (mode <= 1) { + /* Use compression on 320x240 and above */ + reg_w_val(dev, 0x8500, 0x10 | mode); + } else { + /* I couldn't get the compression to work below 320x240 + * Fortunately at these resolutions the bandwidth + * is sufficient to push raw frames at ~20fps */ + reg_w_val(dev, 0x8500, mode); + } /* -- qq@kuku.eu.org */ + reg_w_buf(dev, 0x8307, Reg8307, 2); + reg_w_val(dev, 0x8700, Clck); /* 0x8f 0x85 0x27 clock */ + reg_w_val(dev, 0x8112, 0x1e | 0x20); + reg_w_val(dev, 0x850b, 0x03); + setcontrast(gspca_dev); + break; + } +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + reg_w_val(gspca_dev->dev, 0x8112, 0x20); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ + reg_w_val(gspca_dev->dev, 0x8114, 0); +} + +static void setautogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int expotimes = 0; + int pixelclk = 0; + int gainG = 0; + __u8 R, Gr, Gb, B; + int y; + __u8 luma_mean = 110; + __u8 luma_delta = 20; + __u8 spring = 4; + + switch (sd->chip_revision) { + case Rev072A: + reg_r(gspca_dev->dev, 0x8621, &Gr, 1); + reg_r(gspca_dev->dev, 0x8622, &R, 1); + reg_r(gspca_dev->dev, 0x8623, &B, 1); + reg_r(gspca_dev->dev, 0x8624, &Gb, 1); + y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; + /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ + /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ + /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */ + + if (y < luma_mean - luma_delta || + y > luma_mean + luma_delta) { + expotimes = i2c_read(gspca_dev, 0x09, 0x10); + pixelclk = 0x0800; + expotimes = expotimes & 0x07ff; + /* PDEBUG(D_PACK, + "Exposition Times 0x%03X Clock 0x%04X ", + expotimes,pixelclk); */ + gainG = i2c_read(gspca_dev, 0x35, 0x10); + /* PDEBUG(D_PACK, + "reading Gain register %d", gainG); */ + + expotimes += (luma_mean - y) >> spring; + gainG += (luma_mean - y) / 50; + /* PDEBUG(D_PACK, + "compute expotimes %d gain %d", + expotimes,gainG); */ + + if (gainG > 0x3f) + gainG = 0x3f; + else if (gainG < 4) + gainG = 3; + i2c_write(gspca_dev, gainG, 0x35); + + if (expotimes >= 0x0256) + expotimes = 0x0256; + else if (expotimes < 4) + expotimes = 3; + i2c_write(gspca_dev, expotimes | pixelclk, 0x09); + } + break; + case Rev012A: + /* sensor registers is access and memory mapped to 0x8300 */ + /* readind all 0x83xx block the sensor */ + /* + * The data from the header seem wrong where is the luma + * and chroma mean value + * at the moment set exposure in contrast set + */ + break; + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (data[0]) { + case 0: /* start of frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + if (sd->ag_cnt >= 0) { + if (--sd->ag_cnt < 0) { + sd->ag_cnt = AG_CNT_START; + setautogain(gspca_dev); + } + } + data += SPCA561_OFFSET_DATA; + len -= SPCA561_OFFSET_DATA; + if (data[1] & 0x10) { + /* compressed bayer */ + gspca_frame_add(gspca_dev, FIRST_PACKET, + frame, data, len); + } else { + /*fixme: which format?*/ + data += 20; + len -= 20; + gspca_frame_add(gspca_dev, FIRST_PACKET, + frame, data, len); + } + return; + case 0xff: /* drop */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + data++; + len--; + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value; + + switch (sd->chip_revision) { + case Rev072A: + value = sd->brightness; + reg_w_val(gspca_dev->dev, value, 0x8611); + reg_w_val(gspca_dev->dev, value, 0x8612); + reg_w_val(gspca_dev->dev, value, 0x8613); + reg_w_val(gspca_dev->dev, value, 0x8614); + break; + default: +/* case Rev012A: */ + setcontrast(gspca_dev); + break; + } +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value; + __u16 tot; + + switch (sd->chip_revision) { + case Rev072A: + tot = 0; + reg_r(gspca_dev->dev, 0x8611, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8612, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8613, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8614, &value, 1); + tot += value; + sd->brightness = tot >> 2; + break; + default: +/* case Rev012A: */ + /* no way to read sensor settings */ + break; + } +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value; + __u16 tot; + + switch (sd->chip_revision) { + case Rev072A: + tot = 0; + reg_r(gspca_dev->dev, 0x8651, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8652, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8653, &value, 1); + tot += value; + reg_r(gspca_dev->dev, 0x8654, &value, 1); + tot += value; + sd->contrast = tot << 6; + break; + default: +/* case Rev012A: */ + /* no way to read sensor settings */ + break; + } + PDEBUG(D_CONF, "get contrast %d", sd->contrast); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (val) + sd->ag_cnt = AG_CNT_START; + else + sd->ag_cnt = -1; + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, + {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, + {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, + {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")}, + {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")}, + {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")}, + {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")}, + {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")}, + {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")}, + {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")}, + {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")}, + {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")}, + {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")}, + {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")}, + {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index d8c203e99cd3..6832fe0f3403 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -23,8 +23,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 7) -static const char version[] = "0.2.7"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -37,10 +37,10 @@ struct sd { unsigned char brightness; unsigned char contrast; unsigned char colors; + unsigned char lightfreq; }; /* global parameters */ -static int lightfreq = 50; static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */ /* V4L2 controls supported by the driver */ @@ -50,6 +50,8 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { #define SD_BRIGHTNESS 0 @@ -94,6 +96,20 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcolors, .get = sd_getcolors, }, +#define SD_FREQ 3 + { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light frequency filter", + .minimum = 1, + .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .step = 1, + .default_value = 1, + }, + .set = sd_setfreq, + .get = sd_getfreq, + }, }; static struct cam_mode vga_mode[] = { @@ -102,11 +118,11 @@ static struct cam_mode vga_mode[] = { }; /* -- read a register -- */ -static int reg_read(struct gspca_dev *gspca_dev, +static int reg_r(struct gspca_dev *gspca_dev, __u16 index, __u8 *buf) { - int ret; struct usb_device *dev = gspca_dev->dev; + int ret; ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0x00, @@ -116,12 +132,12 @@ static int reg_read(struct gspca_dev *gspca_dev, buf, 1, 500); if (ret < 0) - PDEBUG(D_ERR, "reg_read err %d", ret); + PDEBUG(D_ERR, "reg_r err %d", ret); return ret; } /* -- write a register -- */ -static int reg_write(struct gspca_dev *gspca_dev, +static int reg_w(struct gspca_dev *gspca_dev, __u16 index, __u16 value) { struct usb_device *dev = gspca_dev->dev; @@ -136,7 +152,7 @@ static int reg_write(struct gspca_dev *gspca_dev, 0, 500); if (ret < 0) - PDEBUG(D_ERR, "reg_write err %d", ret); + PDEBUG(D_ERR, "reg_w err %d", ret); return ret; } @@ -149,15 +165,15 @@ static int rcv_val(struct gspca_dev *gspca_dev, int alen, ret; unsigned char bulk_buf[4]; - reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff); - reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff); - reg_write(gspca_dev, 0x636, ads & 0xff); - reg_write(gspca_dev, 0x637, 0); - reg_write(gspca_dev, 0x638, len & 0xff); - reg_write(gspca_dev, 0x639, len >> 8); - reg_write(gspca_dev, 0x63a, 0); - reg_write(gspca_dev, 0x63b, 0); - reg_write(gspca_dev, 0x630, 5); + reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); + reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); + reg_w(gspca_dev, 0x636, ads & 0xff); + reg_w(gspca_dev, 0x637, 0); + reg_w(gspca_dev, 0x638, len & 0xff); + reg_w(gspca_dev, 0x639, len >> 8); + reg_w(gspca_dev, 0x63a, 0); + reg_w(gspca_dev, 0x63b, 0); + reg_w(gspca_dev, 0x630, 5); if (len > sizeof bulk_buf) return -1; ret = usb_bulk_msg(dev, @@ -180,26 +196,26 @@ static int snd_val(struct gspca_dev *gspca_dev, unsigned char bulk_buf[4]; if (ads == 0x003f08) { - ret = reg_read(gspca_dev, 0x0704, &value); + ret = reg_r(gspca_dev, 0x0704, &value); if (ret < 0) goto ko; - ret = reg_read(gspca_dev, 0x0705, &seq); + ret = reg_r(gspca_dev, 0x0705, &seq); if (ret < 0) goto ko; - ret = reg_read(gspca_dev, 0x0650, &value); + ret = reg_r(gspca_dev, 0x0650, &value); if (ret < 0) goto ko; - reg_write(gspca_dev, 0x654, seq); + reg_w(gspca_dev, 0x654, seq); } else - reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff); - reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff); - reg_write(gspca_dev, 0x656, ads & 0xff); - reg_write(gspca_dev, 0x657, 0); - reg_write(gspca_dev, 0x658, 0x04); /* size */ - reg_write(gspca_dev, 0x659, 0); - reg_write(gspca_dev, 0x65a, 0); - reg_write(gspca_dev, 0x65b, 0); - reg_write(gspca_dev, 0x650, 5); + reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); + reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); + reg_w(gspca_dev, 0x656, ads & 0xff); + reg_w(gspca_dev, 0x657, 0); + reg_w(gspca_dev, 0x658, 0x04); /* size */ + reg_w(gspca_dev, 0x659, 0); + reg_w(gspca_dev, 0x65a, 0); + reg_w(gspca_dev, 0x65b, 0); + reg_w(gspca_dev, 0x650, 5); bulk_buf[0] = (val >> 24) & 0xff; bulk_buf[1] = (val >> 16) & 0xff; bulk_buf[2] = (val >> 8) & 0xff; @@ -215,7 +231,7 @@ static int snd_val(struct gspca_dev *gspca_dev, if (ads == 0x003f08) { seq += 4; seq &= 0x3f; - reg_write(gspca_dev, 0x705, seq); + reg_w(gspca_dev, 0x705, seq); } return ret; ko: @@ -235,7 +251,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int parval; - PDEBUG(D_CONF, "brightness: %d", sd->brightness); parval = 0x06000000 /* whiteness */ + (sd->brightness << 16); set_par(gspca_dev, parval); @@ -246,7 +261,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int parval; - PDEBUG(D_CONF, "contrast: %d", sd->contrast); parval = 0x07000000 /* contrast */ + (sd->contrast << 16); set_par(gspca_dev, parval); @@ -257,13 +271,20 @@ static void setcolors(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int parval; - PDEBUG(D_CONF, "saturation: %d", - sd->colors); parval = 0x08000000 /* saturation */ + (sd->colors << 16); set_par(gspca_dev, parval); } +static void setfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + set_par(gspca_dev, sd->lightfreq == 1 + ? 0x33640000 /* 50 Hz */ + : 0x33780000); /* 60 Hz */ +} + /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) @@ -278,6 +299,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; return 0; } @@ -289,7 +311,7 @@ static int sd_open(struct gspca_dev *gspca_dev) /* check if the device responds */ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - ret = reg_read(gspca_dev, 0x0740, &value); + ret = reg_r(gspca_dev, 0x0740, &value); if (ret < 0) return ret; if (value != 0xff) { @@ -320,21 +342,24 @@ static void sd_start(struct gspca_dev *gspca_dev) ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, gspca_dev->alt); - if (ret < 0) + if (ret < 0) { + PDEBUG(D_ERR|D_STREAM, "set intf %d %d failed", + gspca_dev->iface, gspca_dev->alt); goto out; - ret = reg_read(gspca_dev, 0x0630, &dum); + } + ret = reg_r(gspca_dev, 0x0630, &dum); if (ret < 0) goto out; rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ - ret = reg_read(gspca_dev, 0x0650, &dum); + ret = reg_r(gspca_dev, 0x0650, &dum); if (ret < 0) goto out; snd_val(gspca_dev, 0x000020, 0xffffffff); - reg_write(gspca_dev, 0x0620, 0); - reg_write(gspca_dev, 0x0630, 0); - reg_write(gspca_dev, 0x0640, 0); - reg_write(gspca_dev, 0x0650, 0); - reg_write(gspca_dev, 0x0660, 0); + reg_w(gspca_dev, 0x0620, 0); + reg_w(gspca_dev, 0x0630, 0); + reg_w(gspca_dev, 0x0640, 0); + reg_w(gspca_dev, 0x0650, 0); + reg_w(gspca_dev, 0x0660, 0); setbrightness(gspca_dev); /* whiteness */ setcontrast(gspca_dev); /* contrast */ setcolors(gspca_dev); /* saturation */ @@ -342,9 +367,7 @@ static void sd_start(struct gspca_dev *gspca_dev) set_par(gspca_dev, 0x0a800000); /* Green ? */ set_par(gspca_dev, 0x0b800000); /* Blue ? */ set_par(gspca_dev, 0x0d030000); /* Gamma ? */ - set_par(gspca_dev, lightfreq == 60 - ? 0x33780000 /* 60 Hz */ - : 0x33640000); /* 50 Hz */ + setfreq(gspca_dev); /* light frequency */ /* start the video flow */ set_par(gspca_dev, 0x01000000); @@ -363,15 +386,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev) set_par(gspca_dev, 0x02000000); set_par(gspca_dev, 0x02000000); usb_set_interface(dev, gspca_dev->iface, 1); - reg_read(gspca_dev, 0x0630, &value); + reg_r(gspca_dev, 0x0630, &value); rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ - reg_read(gspca_dev, 0x0650, &value); + reg_r(gspca_dev, 0x0650, &value); snd_val(gspca_dev, 0x000020, 0xffffffff); - reg_write(gspca_dev, 0x0620, 0); - reg_write(gspca_dev, 0x0630, 0); - reg_write(gspca_dev, 0x0640, 0); - reg_write(gspca_dev, 0x0650, 0); - reg_write(gspca_dev, 0x0660, 0); + reg_w(gspca_dev, 0x0620, 0); + reg_w(gspca_dev, 0x0630, 0); + reg_w(gspca_dev, 0x0640, 0); + reg_w(gspca_dev, 0x0650, 0); + reg_w(gspca_dev, 0x0660, 0); PDEBUG(D_STREAM, "camera stopped"); } @@ -470,6 +493,42 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->lightfreq = val; + if (gspca_dev->streaming) + setfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->lightfreq; + return 0; +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy(menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy(menu->name, "60 Hz"); + return 0; + } + break; + } + return -EINVAL; +} + /* sub-driver description */ static struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -482,6 +541,7 @@ static struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .querymenu = sd_querymenu, }; /* -- module initialisation -- */ @@ -524,7 +584,5 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); -module_param(lightfreq, int, 0644); -MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz"); module_param_named(quant, sd_quant, int, 0644); MODULE_PARM_DESC(quant, "Quantization index (0..8)"); diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c new file mode 100644 index 000000000000..52d1b32523b1 --- /dev/null +++ b/drivers/media/video/gspca/sunplus.c @@ -0,0 +1,1638 @@ +/* + * Sunplus spca504(abc) spca533 spca536 library + * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "sunplus" + +#include "gspca.h" +#include "jpeg.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char packet[ISO_MAX_SIZE + 128]; + /* !! no more than 128 ff in an ISO packet */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + + char qindex; + char bridge; +#define BRIDGE_SPCA504 0 +#define BRIDGE_SPCA504B 1 +#define BRIDGE_SPCA504C 2 +#define BRIDGE_SPCA533 3 +#define BRIDGE_SPCA536 4 + char subtype; +#define AiptekMiniPenCam13 1 +#define LogitechClickSmart420 2 +#define LogitechClickSmart820 3 +#define MegapixV4 4 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x20, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 0xff, + .step = 1, + .default_value = 0x1a, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_AUTOGAIN 3 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +}; + +static struct cam_mode vga_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 2}, + {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +}; + +static struct cam_mode custom_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 2}, + {V4L2_PIX_FMT_JPEG, 464, 480, 1}, +}; + +static struct cam_mode vga_mode2[] = { + {V4L2_PIX_FMT_JPEG, 176, 144, 4}, + {V4L2_PIX_FMT_JPEG, 320, 240, 3}, + {V4L2_PIX_FMT_JPEG, 352, 288, 2}, + {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +}; + +#define SPCA50X_OFFSET_DATA 10 +#define SPCA504_PCCAM600_OFFSET_SNAPSHOT 3 +#define SPCA504_PCCAM600_OFFSET_COMPRESS 4 +#define SPCA504_PCCAM600_OFFSET_MODE 5 +#define SPCA504_PCCAM600_OFFSET_DATA 14 + /* Frame packet header offsets for the spca533 */ +#define SPCA533_OFFSET_DATA 16 +#define SPCA533_OFFSET_FRAMSEQ 15 +/* Frame packet header offsets for the spca536 */ +#define SPCA536_OFFSET_DATA 4 +#define SPCA536_OFFSET_FRAMSEQ 1 + +/* Initialisation data for the Creative PC-CAM 600 */ +static __u16 spca504_pccam600_init_data[][3] = { +/* {0xa0, 0x0000, 0x0503}, * capture mode */ + {0x00, 0x0000, 0x2000}, + {0x00, 0x0013, 0x2301}, + {0x00, 0x0003, 0x2000}, + {0x00, 0x0001, 0x21ac}, + {0x00, 0x0001, 0x21a6}, + {0x00, 0x0000, 0x21a7}, /* brightness */ + {0x00, 0x0020, 0x21a8}, /* contrast */ + {0x00, 0x0001, 0x21ac}, /* sat/hue */ + {0x00, 0x0000, 0x21ad}, /* hue */ + {0x00, 0x001a, 0x21ae}, /* saturation */ + {0x00, 0x0002, 0x21a3}, /* gamma */ + {0x30, 0x0154, 0x0008}, + {0x30, 0x0004, 0x0006}, + {0x30, 0x0258, 0x0009}, + {0x30, 0x0004, 0x0000}, + {0x30, 0x0093, 0x0004}, + {0x30, 0x0066, 0x0005}, + {0x00, 0x0000, 0x2000}, + {0x00, 0x0013, 0x2301}, + {0x00, 0x0003, 0x2000}, + {0x00, 0x0013, 0x2301}, + {0x00, 0x0003, 0x2000}, + {} +}; + +/* Creative PC-CAM 600 specific open data, sent before using the + * generic initialisation data from spca504_open_data. + */ +static __u16 spca504_pccam600_open_data[][3] = { + {0x00, 0x0001, 0x2501}, + {0x20, 0x0500, 0x0001}, /* snapshot mode */ + {0x00, 0x0003, 0x2880}, + {0x00, 0x0001, 0x2881}, + {} +}; + +/* Initialisation data for the logitech clicksmart 420 */ +static __u16 spca504A_clicksmart420_init_data[][3] = { +/* {0xa0, 0x0000, 0x0503}, * capture mode */ + {0x00, 0x0000, 0x2000}, + {0x00, 0x0013, 0x2301}, + {0x00, 0x0003, 0x2000}, + {0x00, 0x0001, 0x21ac}, + {0x00, 0x0001, 0x21a6}, + {0x00, 0x0000, 0x21a7}, /* brightness */ + {0x00, 0x0020, 0x21a8}, /* contrast */ + {0x00, 0x0001, 0x21ac}, /* sat/hue */ + {0x00, 0x0000, 0x21ad}, /* hue */ + {0x00, 0x001a, 0x21ae}, /* saturation */ + {0x00, 0x0002, 0x21a3}, /* gamma */ + {0x30, 0x0004, 0x000a}, + {0xb0, 0x0001, 0x0000}, + + + {0x0a1, 0x0080, 0x0001}, + {0x30, 0x0049, 0x0000}, + {0x30, 0x0060, 0x0005}, + {0x0c, 0x0004, 0x0000}, + {0x00, 0x0000, 0x0000}, + {0x00, 0x0000, 0x2000}, + {0x00, 0x0013, 0x2301}, + {0x00, 0x0003, 0x2000}, + {0x00, 0x0000, 0x2000}, + + {} +}; + +/* clicksmart 420 open data ? */ +static __u16 spca504A_clicksmart420_open_data[][3] = { + {0x00, 0x0001, 0x2501}, + {0x20, 0x0502, 0x0000}, + {0x06, 0x0000, 0x0000}, + {0x00, 0x0004, 0x2880}, + {0x00, 0x0001, 0x2881}, +/* look like setting a qTable */ + {0x00, 0x0006, 0x2800}, + {0x00, 0x0004, 0x2801}, + {0x00, 0x0004, 0x2802}, + {0x00, 0x0006, 0x2803}, + {0x00, 0x000a, 0x2804}, + {0x00, 0x0010, 0x2805}, + {0x00, 0x0014, 0x2806}, + {0x00, 0x0018, 0x2807}, + {0x00, 0x0005, 0x2808}, + {0x00, 0x0005, 0x2809}, + {0x00, 0x0006, 0x280a}, + {0x00, 0x0008, 0x280b}, + {0x00, 0x000a, 0x280c}, + {0x00, 0x0017, 0x280d}, + {0x00, 0x0018, 0x280e}, + {0x00, 0x0016, 0x280f}, + + {0x00, 0x0006, 0x2810}, + {0x00, 0x0005, 0x2811}, + {0x00, 0x0006, 0x2812}, + {0x00, 0x000a, 0x2813}, + {0x00, 0x0010, 0x2814}, + {0x00, 0x0017, 0x2815}, + {0x00, 0x001c, 0x2816}, + {0x00, 0x0016, 0x2817}, + {0x00, 0x0006, 0x2818}, + {0x00, 0x0007, 0x2819}, + {0x00, 0x0009, 0x281a}, + {0x00, 0x000c, 0x281b}, + {0x00, 0x0014, 0x281c}, + {0x00, 0x0023, 0x281d}, + {0x00, 0x0020, 0x281e}, + {0x00, 0x0019, 0x281f}, + + {0x00, 0x0007, 0x2820}, + {0x00, 0x0009, 0x2821}, + {0x00, 0x000f, 0x2822}, + {0x00, 0x0016, 0x2823}, + {0x00, 0x001b, 0x2824}, + {0x00, 0x002c, 0x2825}, + {0x00, 0x0029, 0x2826}, + {0x00, 0x001f, 0x2827}, + {0x00, 0x000a, 0x2828}, + {0x00, 0x000e, 0x2829}, + {0x00, 0x0016, 0x282a}, + {0x00, 0x001a, 0x282b}, + {0x00, 0x0020, 0x282c}, + {0x00, 0x002a, 0x282d}, + {0x00, 0x002d, 0x282e}, + {0x00, 0x0025, 0x282f}, + + {0x00, 0x0014, 0x2830}, + {0x00, 0x001a, 0x2831}, + {0x00, 0x001f, 0x2832}, + {0x00, 0x0023, 0x2833}, + {0x00, 0x0029, 0x2834}, + {0x00, 0x0030, 0x2835}, + {0x00, 0x0030, 0x2836}, + {0x00, 0x0028, 0x2837}, + {0x00, 0x001d, 0x2838}, + {0x00, 0x0025, 0x2839}, + {0x00, 0x0026, 0x283a}, + {0x00, 0x0027, 0x283b}, + {0x00, 0x002d, 0x283c}, + {0x00, 0x0028, 0x283d}, + {0x00, 0x0029, 0x283e}, + {0x00, 0x0028, 0x283f}, + + {0x00, 0x0007, 0x2840}, + {0x00, 0x0007, 0x2841}, + {0x00, 0x000a, 0x2842}, + {0x00, 0x0013, 0x2843}, + {0x00, 0x0028, 0x2844}, + {0x00, 0x0028, 0x2845}, + {0x00, 0x0028, 0x2846}, + {0x00, 0x0028, 0x2847}, + {0x00, 0x0007, 0x2848}, + {0x00, 0x0008, 0x2849}, + {0x00, 0x000a, 0x284a}, + {0x00, 0x001a, 0x284b}, + {0x00, 0x0028, 0x284c}, + {0x00, 0x0028, 0x284d}, + {0x00, 0x0028, 0x284e}, + {0x00, 0x0028, 0x284f}, + + {0x00, 0x000a, 0x2850}, + {0x00, 0x000a, 0x2851}, + {0x00, 0x0016, 0x2852}, + {0x00, 0x0028, 0x2853}, + {0x00, 0x0028, 0x2854}, + {0x00, 0x0028, 0x2855}, + {0x00, 0x0028, 0x2856}, + {0x00, 0x0028, 0x2857}, + {0x00, 0x0013, 0x2858}, + {0x00, 0x001a, 0x2859}, + {0x00, 0x0028, 0x285a}, + {0x00, 0x0028, 0x285b}, + {0x00, 0x0028, 0x285c}, + {0x00, 0x0028, 0x285d}, + {0x00, 0x0028, 0x285e}, + {0x00, 0x0028, 0x285f}, + + {0x00, 0x0028, 0x2860}, + {0x00, 0x0028, 0x2861}, + {0x00, 0x0028, 0x2862}, + {0x00, 0x0028, 0x2863}, + {0x00, 0x0028, 0x2864}, + {0x00, 0x0028, 0x2865}, + {0x00, 0x0028, 0x2866}, + {0x00, 0x0028, 0x2867}, + {0x00, 0x0028, 0x2868}, + {0x00, 0x0028, 0x2869}, + {0x00, 0x0028, 0x286a}, + {0x00, 0x0028, 0x286b}, + {0x00, 0x0028, 0x286c}, + {0x00, 0x0028, 0x286d}, + {0x00, 0x0028, 0x286e}, + {0x00, 0x0028, 0x286f}, + + {0x00, 0x0028, 0x2870}, + {0x00, 0x0028, 0x2871}, + {0x00, 0x0028, 0x2872}, + {0x00, 0x0028, 0x2873}, + {0x00, 0x0028, 0x2874}, + {0x00, 0x0028, 0x2875}, + {0x00, 0x0028, 0x2876}, + {0x00, 0x0028, 0x2877}, + {0x00, 0x0028, 0x2878}, + {0x00, 0x0028, 0x2879}, + {0x00, 0x0028, 0x287a}, + {0x00, 0x0028, 0x287b}, + {0x00, 0x0028, 0x287c}, + {0x00, 0x0028, 0x287d}, + {0x00, 0x0028, 0x287e}, + {0x00, 0x0028, 0x287f}, + + {0xa0, 0x0000, 0x0503}, + {} +}; + +static unsigned char qtable_creative_pccam[2][64] = { + { /* Q-table Y-components */ + 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, + 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, + 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, + 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, + 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, + 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, + 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, + 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e}, + { /* Q-table C-components */ + 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, + 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} +}; + +/* FIXME: This Q-table is identical to the Creative PC-CAM one, + * except for one byte. Possibly a typo? + * NWG: 18/05/2003. + */ +static unsigned char qtable_spca504_default[2][64] = { + { /* Q-table Y-components */ + 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, + 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, + 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11, + 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13, + 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17, + 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c, + 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e, + 0x16, 0x1c, 0x1d, 0x1d, 0x1d /* 0x22 */ , 0x1e, 0x1f, 0x1e, + }, + { /* Q-table C-components */ + 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, + 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} +}; + +static void spca5xxRegRead(struct usb_device *dev, + __u16 req, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, + 500); +} + +static void spca5xxRegWrite(struct usb_device *dev, + __u16 req, + __u16 value, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, buffer, length, + 500); +} + +static int reg_write(struct usb_device *dev, + __u16 req, __u16 index, __u16 value) +{ + int ret; + + ret = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, 500); + PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", + reg, index, value, ret); + if (ret < 0) + PDEBUG(D_ERR, "reg write: error %d", ret); + return ret; +} + +static int reg_read_info(struct usb_device *dev, + __u16 value) /* wValue */ +{ + int ret; + __u8 data; + + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0x20, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, + 0, /* index */ + &data, 1, + 500); /* timeout */ + if (ret < 0) { + PDEBUG(D_ERR, "reg_read_info err %d", ret); + return 0; + } + return data; +} + +/* returns: negative is error, pos or zero is data */ +static int reg_read(struct usb_device *dev, + __u16 req, /* bRequest */ + __u16 index, /* wIndex */ + __u16 length) /* wLength (1 or 2 only) */ +{ + int ret; + __u8 buf[2]; + + buf[1] = 0; + ret = usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, + buf, length, + 500); + if (ret < 0) { + PDEBUG(D_ERR, "reg_read err %d", ret); + return -1; + } + return (buf[1] << 8) + buf[0]; +} + +static int write_vector(struct gspca_dev *gspca_dev, + __u16 data[][3]) +{ + struct usb_device *dev = gspca_dev->dev; + int ret, i = 0; + + while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { + ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + if (ret < 0) { + PDEBUG(D_ERR, + "Register write failed for 0x%x,0x%x,0x%x", + data[i][0], data[i][1], data[i][2]); + return ret; + } + i++; + } + return 0; +} + +static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, + unsigned int request, + unsigned int ybase, + unsigned int cbase, + unsigned char qtable[2][64]) +{ + struct usb_device *dev = gspca_dev->dev; + int i, err; + + /* loop over y components */ + for (i = 0; i < 64; i++) { + err = reg_write(dev, request, ybase + i, qtable[0][i]); + if (err < 0) + return err; + } + + /* loop over c components */ + for (i = 0; i < 64; i++) { + err = reg_write(dev, request, cbase + i, qtable[1][i]); + if (err < 0) + return err; + } + return 0; +} + +static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, + __u16 req, __u16 idx, __u16 val) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 notdone; + + reg_write(dev, req, idx, val); + notdone = reg_read(dev, 0x01, 0x0001, 1); + reg_write(dev, req, idx, val); + + PDEBUG(D_FRAM, "before wait 0x%x", notdone); + + msleep(200); + notdone = reg_read(dev, 0x01, 0x0001, 1); + PDEBUG(D_FRAM, "after wait 0x%x", notdone); +} + +static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, + __u16 req, + __u16 idx, __u16 val, __u8 stat, __u8 count) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 status; + __u8 endcode; + + reg_write(dev, req, idx, val); + status = reg_read(dev, 0x01, 0x0001, 1); + endcode = stat; + PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); + if (!count) + return; + count = 200; + while (--count > 0) { + msleep(10); + /* gsmart mini2 write a each wait setting 1 ms is enought */ +/* reg_write(dev, req, idx, val); */ + status = reg_read(dev, 0x01, 0x0001, 1); + if (status == endcode) { + PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", + status, 200 - count); + break; + } + } +} + +static int spca504B_PollingDataReady(struct usb_device *dev) +{ + __u8 DataReady; + int count = 10; + + while (--count > 0) { + spca5xxRegRead(dev, 0x21, 0, &DataReady, 1); + if ((DataReady & 0x01) == 0) + break; + msleep(10); + } + return DataReady; +} + +static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 DataReady; + int count = 50; + + while (--count > 0) { + spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); + + if (DataReady) { + DataReady = 0; + spca5xxRegWrite(dev, 0x21, 0, 1, &DataReady, 1); + spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); + spca504B_PollingDataReady(dev); + break; + } + msleep(10); + } +} + +static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 FW[5]; + __u8 ProductInfo[64]; + + spca5xxRegRead(dev, 0x20, 0, FW, 5); + PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", + FW[0], FW[1], FW[2], FW[3], FW[4]); + spca5xxRegRead(dev, 0x23, 0, ProductInfo, 64); + spca5xxRegRead(dev, 0x23, 1, ProductInfo, 64); +} + +static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 Size; + __u8 Type; + int rc; + + Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + Type = 0; + switch (sd->bridge) { + case BRIDGE_SPCA533: + spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + rc = spca504B_PollingDataReady(dev); + spca50x_GetFirmware(gspca_dev); + Type = 2; + spca5xxRegWrite(dev, 0x24, 0, 8, &Type, 1); + spca5xxRegRead(dev, 0x24, 8, &Type, 1); + + spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); + spca5xxRegRead(dev, 0x25, 4, &Size, 1); + rc = spca504B_PollingDataReady(dev); + + /* Init the cam width height with some values get on init ? */ + spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + rc = spca504B_PollingDataReady(dev); + break; + default: +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA536: */ + Type = 6; + spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); + spca5xxRegRead(dev, 0x25, 4, &Size, 1); + spca5xxRegWrite(dev, 0x27, 0, 0, &Type, 1); + spca5xxRegRead(dev, 0x27, 0, &Type, 1); + rc = spca504B_PollingDataReady(dev); + break; + case BRIDGE_SPCA504: + Size += 3; + if (sd->subtype == AiptekMiniPenCam13) { + /* spca504a aiptek */ + spca504A_acknowledged_command(gspca_dev, + 0x08, Size, 0, + 0x80 | (Size & 0x0f), 1); + spca504A_acknowledged_command(gspca_dev, + 1, 3, 0, 0x9f, 0); + } else { + spca504_acknowledged_command(gspca_dev, 0x08, Size, 0); + } + break; + case BRIDGE_SPCA504C: + /* capture mode */ + reg_write(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x0); + reg_write(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); + break; + } +} + +static void spca504_wait_status(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int cnt; + + cnt = 256; + while (--cnt > 0) { + /* With this we get the status, when return 0 it's all ok */ + if (reg_read(dev, 0x06, 0x00, 1) == 0) + return; + msleep(10); + } +} + +static void spca504B_setQtable(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 Data = 3; + + spca5xxRegWrite(dev, 0x26, 0, 0, &Data, 1); + spca5xxRegRead(dev, 0x26, 0, &Data, 1); + spca504B_PollingDataReady(dev); +} + +static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int pollreg = 1; + + switch (sd->bridge) { + case BRIDGE_SPCA504: + case BRIDGE_SPCA504C: + pollreg = 0; + /* fall thru */ + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ + spca5xxRegWrite(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ + spca5xxRegWrite(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ + spca5xxRegWrite(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ + spca5xxRegWrite(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ + spca5xxRegWrite(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ + spca5xxRegWrite(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ + break; + case BRIDGE_SPCA536: + spca5xxRegWrite(dev, 0, 0, 0x20f0, NULL, 0); + spca5xxRegWrite(dev, 0, 0x21, 0x20f1, NULL, 0); + spca5xxRegWrite(dev, 0, 0x40, 0x20f5, NULL, 0); + spca5xxRegWrite(dev, 0, 1, 0x20f4, NULL, 0); + spca5xxRegWrite(dev, 0, 0x40, 0x20f6, NULL, 0); + spca5xxRegWrite(dev, 0, 0, 0x2089, NULL, 0); + break; + } + if (pollreg) + spca504B_PollingDataReady(dev); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct cam *cam; + __u16 vendor; + __u16 product; + __u8 fw; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x041e: /* Creative cameras */ +/* switch (product) { */ +/* case 0x400b: */ +/* case 0x4012: */ +/* case 0x4013: */ +/* sd->bridge = BRIDGE_SPCA504C; */ +/* break; */ +/* } */ + break; + case 0x0458: /* Genius KYE cameras */ +/* switch (product) { */ +/* case 0x7006: */ + sd->bridge = BRIDGE_SPCA504B; +/* break; */ +/* } */ + break; + case 0x046d: /* Logitech Labtec */ + switch (product) { + case 0x0905: + sd->subtype = LogitechClickSmart820; + sd->bridge = BRIDGE_SPCA533; + break; + case 0x0960: + sd->subtype = LogitechClickSmart420; + sd->bridge = BRIDGE_SPCA504C; + break; + } + break; + case 0x0471: /* Philips */ +/* switch (product) { */ +/* case 0x0322: */ + sd->bridge = BRIDGE_SPCA504B; +/* break; */ +/* } */ + break; + case 0x04a5: /* Benq */ + switch (product) { + case 0x3003: + sd->bridge = BRIDGE_SPCA504B; + break; + case 0x3008: + case 0x300a: + sd->bridge = BRIDGE_SPCA533; + break; + } + break; + case 0x04f1: /* JVC */ +/* switch (product) { */ +/* case 0x1001: */ + sd->bridge = BRIDGE_SPCA504B; +/* break; */ +/* } */ + break; + case 0x04fc: /* SunPlus */ + switch (product) { + case 0x500c: + sd->bridge = BRIDGE_SPCA504B; + break; + case 0x504a: +/* try to get the firmware as some cam answer 2.0.1.2.2 + * and should be a spca504b then overwrite that setting */ + spca5xxRegRead(dev, 0x20, 0, &fw, 1); + if (fw == 1) { + sd->subtype = AiptekMiniPenCam13; + sd->bridge = BRIDGE_SPCA504; + } else if (fw == 2) { + sd->bridge = BRIDGE_SPCA504B; + } else + return -ENODEV; + break; + case 0x504b: + sd->bridge = BRIDGE_SPCA504B; + break; + case 0x5330: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x5360: + sd->bridge = BRIDGE_SPCA536; + break; + case 0xffff: + sd->bridge = BRIDGE_SPCA504B; + break; + } + break; + case 0x052b: /* ?? Megapix */ +/* switch (product) { */ +/* case 0x1513: */ + sd->subtype = MegapixV4; + sd->bridge = BRIDGE_SPCA533; +/* break; */ +/* } */ + break; + case 0x0546: /* Polaroid */ + switch (product) { + case 0x3155: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x3191: + case 0x3273: + sd->bridge = BRIDGE_SPCA504B; + break; + } + break; + case 0x055f: /* Mustek cameras */ + switch (product) { + case 0xc211: + sd->bridge = BRIDGE_SPCA536; + break; + case 0xc230: + case 0xc232: + sd->bridge = BRIDGE_SPCA533; + break; + case 0xc360: + sd->bridge = BRIDGE_SPCA536; + break; + case 0xc420: + sd->bridge = BRIDGE_SPCA504; + break; + case 0xc430: + case 0xc440: + sd->bridge = BRIDGE_SPCA533; + break; + case 0xc520: + sd->bridge = BRIDGE_SPCA504; + break; + case 0xc530: + case 0xc540: + case 0xc630: + case 0xc650: + sd->bridge = BRIDGE_SPCA533; + break; + } + break; + case 0x05da: /* Digital Dream cameras */ +/* switch (product) { */ +/* case 0x1018: */ + sd->bridge = BRIDGE_SPCA504B; +/* break; */ +/* } */ + break; + case 0x06d6: /* Trust */ +/* switch (product) { */ +/* case 0x0031: */ + sd->bridge = BRIDGE_SPCA533; /* SPCA533A */ +/* break; */ +/* } */ + break; + case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ + switch (product) { + case 0x1311: + case 0x1314: + case 0x2211: + case 0x2221: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x3261: + case 0x3281: + sd->bridge = BRIDGE_SPCA536; + break; + } + break; + case 0x08ca: /* Aiptek */ + switch (product) { + case 0x0104: + case 0x0106: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x2008: + sd->bridge = BRIDGE_SPCA504B; + break; + case 0x2010: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x2016: + case 0x2018: + sd->bridge = BRIDGE_SPCA504B; + break; + case 0x2020: + case 0x2022: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x2024: + sd->bridge = BRIDGE_SPCA536; + break; + case 0x2028: + sd->bridge = BRIDGE_SPCA533; + break; + case 0x2040: + case 0x2042: + case 0x2060: + sd->bridge = BRIDGE_SPCA536; + break; + } + break; + case 0x0d64: /* SunPlus */ +/* switch (product) { */ +/* case 0x0303: */ + sd->bridge = BRIDGE_SPCA536; +/* break; */ +/* } */ + break; + } + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA536: */ + cam->cam_mode = vga_mode; + cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + break; + case BRIDGE_SPCA533: + cam->cam_mode = custom_mode; + cam->nmodes = sizeof custom_mode / sizeof custom_mode[0]; + break; + case BRIDGE_SPCA504C: + cam->cam_mode = vga_mode2; + cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0]; + break; + } + sd->qindex = 5; /* set the quantization table */ + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int rc; + __u8 Data; + __u8 i; + __u8 info[6]; + int err_code; + + switch (sd->bridge) { + case BRIDGE_SPCA504B: + spca5xxRegWrite(dev, 0x1d, 0, 0, NULL, 0); + spca5xxRegWrite(dev, 0, 1, 0x2306, NULL, 0); + spca5xxRegWrite(dev, 0, 0, 0x0d04, NULL, 0); + spca5xxRegWrite(dev, 0, 0, 0x2000, NULL, 0); + spca5xxRegWrite(dev, 0, 0x13, 0x2301, NULL, 0); + spca5xxRegWrite(dev, 0, 0, 0x2306, NULL, 0); + /* fall thru */ + case BRIDGE_SPCA533: + rc = spca504B_PollingDataReady(dev); + spca50x_GetFirmware(gspca_dev); + break; + case BRIDGE_SPCA536: + spca50x_GetFirmware(gspca_dev); + spca5xxRegRead(dev, 0x00, 0x5002, &Data, 1); + Data = 0; + spca5xxRegWrite(dev, 0x24, 0, 0, &Data, 1); + spca5xxRegRead(dev, 0x24, 0, &Data, 1); + rc = spca504B_PollingDataReady(dev); + spca5xxRegWrite(dev, 0x34, 0, 0, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + break; + case BRIDGE_SPCA504C: /* pccam600 */ + PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); + reg_write(dev, 0xe0, 0x0000, 0x0000); + reg_write(dev, 0xe0, 0x0000, 0x0001); /* reset */ + spca504_wait_status(gspca_dev); + if (sd->subtype == LogitechClickSmart420) + write_vector(gspca_dev, + spca504A_clicksmart420_open_data); + else + write_vector(gspca_dev, spca504_pccam600_open_data); + err_code = spca50x_setup_qtable(gspca_dev, + 0x00, 0x2800, + 0x2840, qtable_creative_pccam); + if (err_code < 0) { + PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed"); + return err_code; + } + break; + default: +/* case BRIDGE_SPCA504: */ + PDEBUG(D_STREAM, "Opening SPCA504"); + if (sd->subtype == AiptekMiniPenCam13) { + /*****************************/ + for (i = 0; i < 6; i++) + info[i] = reg_read_info(dev, i); + PDEBUG(D_STREAM, + "Read info: %d %d %d %d %d %d." + " Should be 1,0,2,2,0,0", + info[0], info[1], info[2], + info[3], info[4], info[5]); + /* spca504a aiptek */ + /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ + spca504A_acknowledged_command(gspca_dev, 0x24, + 8, 3, 0x9e, 1); + /* Twice sequencial need status 0xff->0x9e->0x9d */ + spca504A_acknowledged_command(gspca_dev, 0x24, + 8, 3, 0x9e, 0); + + spca504A_acknowledged_command(gspca_dev, 0x24, + 0, 0, 0x9d, 1); + /******************************/ + /* spca504a aiptek */ + spca504A_acknowledged_command(gspca_dev, 0x08, + 6, 0, 0x86, 1); +/* reg_write (dev, 0, 0x2000, 0); */ +/* reg_write (dev, 0, 0x2883, 1); */ +/* spca504A_acknowledged_command (gspca_dev, 0x08, + 6, 0, 0x86, 1); */ +/* spca504A_acknowledged_command (gspca_dev, 0x24, + 0, 0, 0x9D, 1); */ + reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ + reg_write(dev, 0x0, 0x2310, 0x5); + spca504A_acknowledged_command(gspca_dev, 0x01, + 0x0f, 0, 0xff, 0); + } + /* setup qtable */ + reg_write(dev, 0, 0x2000, 0); + reg_write(dev, 0, 0x2883, 1); + err_code = spca50x_setup_qtable(gspca_dev, + 0x00, 0x2800, + 0x2840, + qtable_spca504_default); + if (err_code < 0) { + PDEBUG(D_ERR, "spca50x_setup_qtable failed"); + return err_code; + } + break; + } + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + int rc; + int enable; + __u8 i; + __u8 info[6]; + + if (sd->bridge == BRIDGE_SPCA504B) + spca504B_setQtable(gspca_dev); + spca504B_SetSizeType(gspca_dev); + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA536: */ + if (sd->subtype == MegapixV4 || + sd->subtype == LogitechClickSmart820) { + spca5xxRegWrite(dev, 0xf0, 0, 0, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + spca5xxRegRead(dev, 0xf0, 4, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + } else { + spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + rc = spca504B_PollingDataReady(dev); + } + break; + case BRIDGE_SPCA504: + if (sd->subtype == AiptekMiniPenCam13) { + for (i = 0; i < 6; i++) + info[i] = reg_read_info(dev, i); + PDEBUG(D_STREAM, + "Read info: %d %d %d %d %d %d." + " Should be 1,0,2,2,0,0", + info[0], info[1], info[2], + info[3], info[4], info[5]); + /* spca504a aiptek */ + /* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */ + spca504A_acknowledged_command(gspca_dev, 0x24, + 8, 3, 0x9e, 1); + /* Twice sequencial need status 0xff->0x9e->0x9d */ + spca504A_acknowledged_command(gspca_dev, 0x24, + 8, 3, 0x9e, 0); + spca504A_acknowledged_command(gspca_dev, 0x24, + 0, 0, 0x9d, 1); + } else { + spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); + for (i = 0; i < 6; i++) + info[i] = reg_read_info(dev, i); + PDEBUG(D_STREAM, + "Read info: %d %d %d %d %d %d." + " Should be 1,0,2,2,0,0", + info[0], info[1], info[2], + info[3], info[4], info[5]); + spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); + spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); + } + spca504B_SetSizeType(gspca_dev); + reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ + reg_write(dev, 0x0, 0x2310, 0x5); + break; + case BRIDGE_SPCA504C: + if (sd->subtype == LogitechClickSmart420) { + write_vector(gspca_dev, + spca504A_clicksmart420_init_data); + } else { + write_vector(gspca_dev, spca504_pccam600_init_data); + } + enable = (sd->autogain ? 0x4 : 0x1); + reg_write(dev, 0x0c, 0x0000, enable); /* auto exposure */ + reg_write(dev, 0xb0, 0x0000, enable); /* auto whiteness */ + + /* set default exposure compensation and whiteness balance */ + reg_write(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ + reg_write(dev, 0x30, 0x0002, 1600); + spca504B_SetSizeType(gspca_dev); + break; + } + sp5xx_initContBrigHueRegisters(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA536: */ +/* case BRIDGE_SPCA504B: */ + spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); + spca504B_WaitCmdStatus(gspca_dev); + spca504B_PollingDataReady(dev); + break; + case BRIDGE_SPCA504: + case BRIDGE_SPCA504C: + reg_write(dev, 0x00, 0x2000, 0x0000); + + if (sd->subtype == AiptekMiniPenCam13) { + /* spca504a aiptek */ +/* spca504A_acknowledged_command(gspca_dev, 0x08, + 6, 0, 0x86, 1); */ + spca504A_acknowledged_command(gspca_dev, 0x24, + 0x00, 0x00, 0x9d, 1); + spca504A_acknowledged_command(gspca_dev, 0x01, + 0x0f, 0x00, 0xff, 1); + } else { + spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); + reg_write(dev, 0x01, 0x000f, 0x0); + } + break; + } +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + int i, sof = 0; + unsigned char *s, *d; + static unsigned char ffd9[] = {0xff, 0xd9}; + +/* frames are jpeg 4.1.1 without 0xff escape */ + switch (sd->bridge) { + case BRIDGE_SPCA533: + if (data[0] == 0xff) { + if (data[1] != 0x01) { /* drop packet */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + } + sof = 1; + data += SPCA533_OFFSET_DATA; + len -= SPCA533_OFFSET_DATA; + } else { + data += 1; + len -= 1; + } + break; + case BRIDGE_SPCA536: + if (data[0] == 0xff) { + sof = 1; + data += SPCA536_OFFSET_DATA; + len -= SPCA536_OFFSET_DATA; + } else { + data += 2; + len -= 2; + } + break; + default: +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504B: */ + switch (data[0]) { + case 0xfe: /* start of frame */ + sof = 1; + data += SPCA50X_OFFSET_DATA; + len -= SPCA50X_OFFSET_DATA; + break; + case 0xff: /* drop packet */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + default: + data += 1; + len -= 1; + break; + } + break; + case BRIDGE_SPCA504C: + switch (data[0]) { + case 0xfe: /* start of frame */ + sof = 1; + data += SPCA504_PCCAM600_OFFSET_DATA; + len -= SPCA504_PCCAM600_OFFSET_DATA; + break; + case 0xff: /* drop packet */ +/* gspca_dev->last_packet_type = DISCARD_PACKET; */ + return; + default: + data += 1; + len -= 1; + break; + } + break; + } + if (sof) { /* start of frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + ffd9, 2); + + /* put the JPEG header in the new frame */ + jpeg_put_header(gspca_dev, frame, + ((struct sd *) gspca_dev)->qindex, + 0x22); + } + + /* add 0x00 after 0xff */ + for (i = len; --i >= 0; ) + if (data[i] == 0xff) + break; + if (i < 0) { /* no 0xff */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + return; + } + s = data; + d = sd->packet; + for (i = 0; i < len; i++) { + *d++ = *s++; + if (s[-1] == 0xff) + *d++ = 0x00; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + sd->packet, d - sd->packet); +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + reg_write(dev, 0x0, 0x21a7, sd->brightness); + break; + case BRIDGE_SPCA536: + reg_write(dev, 0x0, 0x20f0, sd->brightness); + break; + } +} + +static void getbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u16 brightness = 0; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + brightness = reg_read(dev, 0x0, 0x21a7, 2); + break; + case BRIDGE_SPCA536: + brightness = reg_read(dev, 0x0, 0x20f0, 2); + break; + } + sd->brightness = ((brightness & 0xff) - 128) % 255; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + reg_write(dev, 0x0, 0x21a8, sd->contrast); + break; + case BRIDGE_SPCA536: + reg_write(dev, 0x0, 0x20f1, sd->contrast); + break; + } +} + +static void getcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + sd->contrast = reg_read(dev, 0x0, 0x21a8, 2); + break; + case BRIDGE_SPCA536: + sd->contrast = reg_read(dev, 0x0, 0x20f1, 2); + break; + } +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + reg_write(dev, 0x0, 0x21ae, sd->colors); + break; + case BRIDGE_SPCA536: + reg_write(dev, 0x0, 0x20f6, sd->colors); + break; + } +} + +static void getcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + switch (sd->bridge) { + default: +/* case BRIDGE_SPCA533: */ +/* case BRIDGE_SPCA504B: */ +/* case BRIDGE_SPCA504: */ +/* case BRIDGE_SPCA504C: */ + sd->colors = reg_read(dev, 0x0, 0x21ae, 2) >> 1; + break; + case BRIDGE_SPCA536: + sd->colors = reg_read(dev, 0x0, 0x20f6, 2) >> 1; + break; + } +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getbrightness(gspca_dev); + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcontrast(gspca_dev); + *val = sd->contrast; + return 0; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + getcolors(gspca_dev); + *val = sd->colors; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, + {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, + {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, + {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, + {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, + {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, + {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, + {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")}, + {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")}, + {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")}, + {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")}, + {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")}, + {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")}, + {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")}, + {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")}, + {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")}, + {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")}, + {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")}, + {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")}, + {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")}, + {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")}, + {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")}, + {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")}, + {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")}, + {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")}, + {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")}, + {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")}, + {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")}, + {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")}, + {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")}, + {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")}, + {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")}, + {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")}, + {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")}, + {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")}, + {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")}, + {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")}, + {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")}, + {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")}, + {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")}, + {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")}, + {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")}, + {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")}, + {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")}, + {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")}, + {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")}, + {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")}, + {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")}, + {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")}, + {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")}, + {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, + {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, + {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, + {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, + {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c new file mode 100644 index 000000000000..c22b301ebae0 --- /dev/null +++ b/drivers/media/video/gspca/t613.c @@ -0,0 +1,1013 @@ +/* + *Notes: * t613 + tas5130A + * * Focus to light do not balance well as in win. + * Quality in win is not good, but its kinda better. + * * Fix some "extraneous bytes", most of apps will show the image anyway + * * Gamma table, is there, but its really doing something? + * * 7~8 Fps, its ok, max on win its 10. + * Costantino Leandro + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "t613" +#include "gspca.h" +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +struct control_menu_info { + int value; + char name[32]; +}; + +#define MAX_GAMMA 0x10 /* 0 to 15 */ + +/* From LUVCVIEW */ +#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) + +MODULE_AUTHOR("Leandro Costantino "); +MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver"); +MODULE_LICENSE("GPL"); + +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char brightness; + unsigned char contrast; + unsigned char colors; + unsigned char autogain; + unsigned char gamma; + unsigned char sharpness; + unsigned char freq; + unsigned char whitebalance; + unsigned char mirror; + unsigned char effect; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val); +static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 0x0f, + .step = 1, + .default_value = 0x09, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0x0d, + .step = 1, + .default_value = 0x07, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +#define SD_COLOR 2 + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Color", + .minimum = 0, + .maximum = 0x0f, + .step = 1, + .default_value = 0x05, + }, + .set = sd_setcolors, + .get = sd_getcolors, + }, +#define SD_GAMMA 3 + { + { + .id = V4L2_CID_GAMMA, /* (gamma on win) */ + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma (Untested)", + .minimum = 0, + .maximum = MAX_GAMMA, + .step = 1, + .default_value = 0x09, + }, + .set = sd_setgamma, + .get = sd_getgamma, + }, +#define SD_AUTOGAIN 4 + { + { + .id = V4L2_CID_GAIN, /* here, i activate only the lowlight, + * some apps dont bring up the + * backligth_compensation control) */ + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Low Light", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0x01, + }, + .set = sd_setlowlight, + .get = sd_getlowlight, + }, +#define SD_MIRROR 5 + { + { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mirror Image", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, + .set = sd_setflip, + .get = sd_getflip + }, +#define SD_LIGHTFREQ 6 + { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light Frequency Filter", + .minimum = 1, /* 1 -> 0x50, 2->0x60 */ + .maximum = 2, + .step = 1, + .default_value = 1, + }, + .set = sd_setfreq, + .get = sd_getfreq}, + +#define SD_WHITE_BALANCE 7 + { + { + .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "White Balance", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setwhitebalance, + .get = sd_getwhitebalance + }, +#define SD_SHARPNESS 8 /* (aka definition on win) */ + { + { + .id = V4L2_CID_SHARPNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Sharpness", + .minimum = 0, + .maximum = MAX_GAMMA, /* 0 to 16 */ + .step = 1, + .default_value = 0x06, + }, + .set = sd_setsharpness, + .get = sd_getsharpness, + }, +#define SD_EFFECTS 9 + { + { + .id = V4L2_CID_EFFECTS, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Webcam Effects", + .minimum = 0, + .maximum = 4, + .step = 1, + .default_value = 0, + }, + .set = sd_seteffect, + .get = sd_geteffect + }, +}; + +static struct control_menu_info effects_control[] = { + {0, "Normal"}, + {1, "Emboss"}, /* disabled */ + {2, "Monochrome"}, + {3, "Sepia"}, + {4, "Sketch"}, + {5, "Sun Effect"}, /* disabled */ + {6, "Negative"}, +}; + +#define NUM_EFFECTS_CONTROL \ + (sizeof(effects_control)/sizeof(effects_control[0])) + +static struct cam_mode vga_mode_t16[] = { + {V4L2_PIX_FMT_JPEG, 160, 120, 4}, + {V4L2_PIX_FMT_JPEG, 176, 144, 3}, + {V4L2_PIX_FMT_JPEG, 320, 240, 2}, + {V4L2_PIX_FMT_JPEG, 352, 288, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +#define T16_OFFSET_DATA 631 +#define MAX_EFFECTS 7 +/* easily done by soft, this table could be removed, + * i keep it here just in case */ +unsigned char effects_table[MAX_EFFECTS][6] = { + {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ + {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ + {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ + {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80}, /* Sepia */ + {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02}, /* Croquis */ + {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10}, /* Sun Effect */ + {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ +}; + +unsigned char gamma_table[MAX_GAMMA][34] = { + {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, + 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, + 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, + 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x33, 0x92, 0x5A, 0x93, 0x75, + 0x94, 0x85, 0x95, 0x93, 0x96, 0xA1, 0x97, 0xAD, + 0x98, 0xB7, 0x99, 0xC2, 0x9A, 0xCB, 0x9B, 0xD4, + 0x9C, 0xDE, 0x9D, 0xE7, 0x9E, 0xF0, 0x9F, 0xF7, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x2F, 0x92, 0x51, 0x93, 0x6B, + 0x94, 0x7C, 0x95, 0x8A, 0x96, 0x99, 0x97, 0xA6, + 0x98, 0xB1, 0x99, 0xBC, 0x9A, 0xC6, 0x9B, 0xD0, + 0x9C, 0xDB, 0x9D, 0xE4, 0x9E, 0xED, 0x9F, 0xF6, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, + 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9E, + 0x98, 0xAA, 0x99, 0xB5, 0x9A, 0xBF, 0x9B, 0xCB, + 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x23, 0x92, 0x3F, 0x93, 0x55, + 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95, + 0x98, 0xA2, 0x99, 0xAD, 0x9A, 0xB9, 0x9B, 0xC6, + 0x9C, 0xD2, 0x9D, 0xDE, 0x9E, 0xE9, 0x9F, 0xF4, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x1B, 0x92, 0x33, 0x93, 0x48, + 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87, + 0x98, 0x96, 0x99, 0xA3, 0x9A, 0xB1, 0x9B, 0xBE, + 0x9C, 0xCC, 0x9D, 0xDA, 0x9E, 0xE7, 0x9F, 0xF3, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, + 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67, + 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa, + 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, + 0x94, 0x38, 0x95, 0x4A, 0x96, 0x60, 0x97, 0x70, + 0x98, 0x80, 0x99, 0x90, 0x9A, 0xA0, 0x9B, 0xB0, + 0x9C, 0xC0, 0x9D, 0xD0, 0x9E, 0xE0, 0x9F, 0xF0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, + 0x94, 0x47, 0x95, 0x5A, 0x96, 0x69, 0x97, 0x79, + 0x98, 0x88, 0x99, 0x97, 0x9A, 0xA7, 0x9B, 0xB6, + 0x9C, 0xC4, 0x9D, 0xD3, 0x9E, 0xE0, 0x9F, 0xF0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, + 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, + 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, + 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x18, 0x92, 0x2B, 0x93, 0x44, + 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8E, + 0x98, 0x9C, 0x99, 0xAA, 0x9A, 0xB7, 0x9B, 0xC4, + 0x9C, 0xD0, 0x9D, 0xD8, 0x9E, 0xE2, 0x9F, 0xF0, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x1A, 0x92, 0x34, 0x93, 0x52, + 0x94, 0x66, 0x95, 0x7E, 0x96, 0x8D, 0x97, 0x9B, + 0x98, 0xA8, 0x99, 0xB4, 0x9A, 0xC0, 0x9B, 0xCB, + 0x9C, 0xD6, 0x9D, 0xE1, 0x9E, 0xEB, 0x9F, 0xF5, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x3F, 0x92, 0x5A, 0x93, 0x6E, + 0x94, 0x7F, 0x95, 0x8E, 0x96, 0x9C, 0x97, 0xA8, + 0x98, 0xB4, 0x99, 0xBF, 0x9A, 0xC9, 0x9B, 0xD3, + 0x9C, 0xDC, 0x9D, 0xE5, 0x9E, 0xEE, 0x9F, 0xF6, + 0xA0, 0xFF}, + {0x90, 0x00, 0x91, 0x54, 0x92, 0x6F, 0x93, 0x83, + 0x94, 0x93, 0x95, 0xA0, 0x96, 0xAD, 0x97, 0xB7, + 0x98, 0xC2, 0x99, 0xCB, 0x9A, 0xD4, 0x9B, 0xDC, + 0x9C, 0xE4, 0x9D, 0xEB, 0x9E, 0xF2, 0x9F, 0xF9, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x6E, 0x92, 0x88, 0x93, 0x9A, + 0x94, 0xA8, 0x95, 0xB3, 0x96, 0xBD, 0x97, 0xC6, + 0x98, 0xCF, 0x99, 0xD6, 0x9A, 0xDD, 0x9B, 0xE3, + 0x9C, 0xE9, 0x9D, 0xEF, 0x9E, 0xF4, 0x9F, 0xFA, + 0xa0, 0xff}, + {0x90, 0x00, 0x91, 0x93, 0x92, 0xA8, 0x93, 0xB7, + 0x94, 0xC1, 0x95, 0xCA, 0x96, 0xD2, 0x97, 0xD8, + 0x98, 0xDE, 0x99, 0xE3, 0x9A, 0xE8, 0x9B, 0xED, + 0x9C, 0xF1, 0x9D, 0xF5, 0x9E, 0xF8, 0x9F, 0xFC, + 0xA0, 0xFF} +}; + +static __u8 tas5130a_sensor_init[][8] = { + {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, + {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, + {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, + {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, + {}, +}; + +static void t16RegRead(struct usb_device *dev, + __u16 index, __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, 500); +} + +static void t16RegWrite(struct usb_device *dev, + __u16 value, + __u16 index, __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, buffer, length, 500); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x01; + + cam->cam_mode = vga_mode_t16; + cam->nmodes = ARRAY_SIZE(vga_mode_t16); + + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->gamma = sd_ctrls[SD_GAMMA].qctrl.default_value; + sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value; + sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value; + sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value; + sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; + sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value; + return 0; +} + +static int init_default_parameters(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + /* some of this registers are not really neded, because + * they are overriden by setbrigthness, setcontrast, etc, + * but wont hurt anyway, and can help someone with similar webcam + * to see the initial parameters.*/ + int i = 0; + __u8 test_byte; + + static unsigned char read_indexs[] = + { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, + 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; + static unsigned char n1[6] = + {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; + static unsigned char n2[2] = + {0x08, 0x00}; + static unsigned char nset[6] = + { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; + static unsigned char n3[6] = + {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; + static unsigned char n4[0x46] = + {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, + 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, + 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, + 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8, + 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48, + 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0, + 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, + 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, + 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; + static unsigned char nset4[18] = { + 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, + 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, + 0xe8, 0xe0 + }; + /* ojo puede ser 0xe6 en vez de 0xe9 */ + static unsigned char nset2[20] = { + 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, + 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, + 0xd8, 0xc8, 0xd9, 0xfc + }; + static unsigned char missing[8] = + { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; + static unsigned char nset3[18] = { + 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, + 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, + 0xcf, 0xe0 + }; + static unsigned char nset5[4] = + { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ + static unsigned char nset6[34] = { + 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54, + 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, + 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, + 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2, + 0xa0, 0xff + }; /* Gamma */ + static unsigned char nset7[4] = + { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ + static unsigned char nset9[4] = + { 0x0b, 0x04, 0x0a, 0x78 }; + static unsigned char nset8[6] = + { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; + static unsigned char nset10[6] = + { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; + + t16RegWrite(dev, 0x01, 0x0000, n1, 0x06); + t16RegWrite(dev, 0x01, 0x0000, nset, 0x06); + t16RegRead(dev, 0x0063, &test_byte, 1); + t16RegWrite(dev, 0x01, 0x0000, n2, 0x02); + + while (read_indexs[i] != 0x00) { + t16RegRead(dev, read_indexs[i], &test_byte, 1); + PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i], + test_byte); + i++; + } + + t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); + t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); + t16RegRead(dev, 0x0080, &test_byte, 1); + t16RegWrite(dev, 0x00, 0x2c80, 0x00, 0x0); + t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); + t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); + t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); + t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x338e, 0x00, 0x0); + t16RegWrite(dev, 0x01, 00, nset5, 0x04); + t16RegWrite(dev, 0x00, 0x00a9, 0x00, 0x0); + t16RegWrite(dev, 0x01, 00, nset6, 0x22); + t16RegWrite(dev, 0x00, 0x86bb, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x0); + + t16RegWrite(dev, 0x01, 00, missing, 0x08); + + t16RegWrite(dev, 0x00, 0x2087, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x2088, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x2089, 0x00, 0x0); + + t16RegWrite(dev, 0x01, 00, nset7, 0x4); + t16RegWrite(dev, 0x01, 00, nset10, 0x06); + t16RegWrite(dev, 0x01, 00, nset8, 0x06); + t16RegWrite(dev, 0x01, 00, nset9, 0x04); + + t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x0); + t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); + t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); + t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); + + return 0; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + unsigned int brightness; + unsigned char set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; + brightness = sd->brightness; + + if (brightness < 7) { + set6[3] = 0x70 - (brightness * 0xa); + } else { + set6[1] = 0x24; + set6[3] = 0x00 + ((brightness - 7) * 0xa); + } + + t16RegWrite(dev, 0x01, 0x0000, set6, 4); +} + +static void setflip(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + unsigned char flipcmd[8] = + { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; + + if (sd->mirror == 1) + flipcmd[3] = 0x01; + + t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8); +} + +static void seteffect(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); + if (sd->effect == 1 || sd->effect == 5) { + PDEBUG(D_CONF, + "This effect have been disabled for webcam \"safety\""); + return; + } + + if (sd->effect == 1 || sd->effect == 4) + t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x00); + else + t16RegWrite(dev, 0x00, 0xfaa6, 0x00, 0x00); +} + +static void setwhitebalance(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + unsigned char white_balance[8] = + { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; + + if (sd->whitebalance == 1) + white_balance[7] = 0x3c; + + t16RegWrite(dev, 0x01, 0x0000, white_balance, 8); +} + +static void setlightfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; + + if (sd->freq == 2) /* 60hz */ + freq[1] = 0x00; + + t16RegWrite(dev, 0x1, 0x0000, freq, 0x4); +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + unsigned int contrast = sd->contrast; + __u16 reg_to_write = 0x00; + + if (contrast < 7) + reg_to_write = 0x8ea9 - (0x200 * contrast); + else + reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); + + t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); + +} + +static void setcolors(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u16 reg_to_write = 0x00; + + reg_to_write = 0xc0bb + sd->colors * 0x100; + t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); +} + +static void setgamma(struct gspca_dev *gspca_dev) +{ +} + +static void setsharpness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + __u16 reg_to_write = 0x00; + + reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; + + t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0x00); +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + *val = sd->brightness; + return *val; +} + +static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->whitebalance = val; + if (gspca_dev->streaming) + setwhitebalance(gspca_dev); + return 0; +} + +static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->whitebalance; + return *val; +} + + +static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->mirror = val; + if (gspca_dev->streaming) + setflip(gspca_dev); + return 0; +} + +static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->mirror; + return *val; +} + +static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->effect = val; + if (gspca_dev->streaming) + seteffect(gspca_dev); + return 0; +} + +static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->effect; + return *val; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return *val; +} + +static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->colors = val; + if (gspca_dev->streaming) + setcolors(gspca_dev); + return 0; +} + +static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->colors; + return 0; +} + +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gamma = val; + if (gspca_dev->streaming) + setgamma(gspca_dev); + return 0; +} + +static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + *val = sd->gamma; + return 0; +} + +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->freq = val; + if (gspca_dev->streaming) + setlightfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->freq; + return 0; +} + +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->sharpness = val; + if (gspca_dev->streaming) + setsharpness(gspca_dev); + return 0; +} + +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->sharpness; + return 0; +} + +/* Low Light set here......*/ +static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + + sd->autogain = val; + if (val != 0) + t16RegWrite(dev, 0x00, 0xf48e, 0x00, 0); + else + t16RegWrite(dev, 0x00, 0xb48e, 0x00, 0); + return 0; +} + +static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int mode; + __u8 test_byte; + + static __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; + __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; + static __u8 t3[] = + { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, + 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; + static __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode; + switch (mode) { + case 1: /* 352x288 */ + t2[1] = 0x40; + break; + case 2: /* 320x240 */ + t2[1] = 0x10; + break; + case 3: /* 176x144 */ + t2[1] = 0x50; + break; + case 4: /* 160x120 */ + t2[1] = 0x20; + break; + default: /* 640x480 (0x00) */ + break; + } + + t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); + t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); + t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); + t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); + /* just in case and to keep sync with logs (for mine) */ + t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); + /* just in case and to keep sync with logs (for mine) */ + t16RegWrite(dev, 0x01, 0x0000, t1, 4); + t16RegWrite(dev, 0x01, 0x0000, t2, 6); + t16RegRead(dev, 0x0012, &test_byte, 0x1); + t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); + t16RegWrite(dev, 0x00, 0x0013, 0x00, 0x00); + t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); + /* restart on each start, just in case, sometimes regs goes wrong + * when using controls from app */ + setbrightness(gspca_dev); + setcontrast(gspca_dev); + setcolors(gspca_dev); +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso packet length */ +{ + int sof = 0; + static unsigned char ffd9[] = { 0xff, 0xd9 }; + + if (data[0] == 0x5a) { + /* Control Packet, after this came the header again, + * but extra bytes came in the packet before this, + * sometimes an EOF arrives, sometimes not... */ + return; + } + + if (data[len - 1] == 0xff && data[len] == 0xd9) { + /* Just in case, i have seen packets with the marker, + * other's do not include it... */ + data += 2; + len -= 4; + } else if (data[2] == 0xff && data[3] == 0xd8) { + sof = 1; + data += 2; + len -= 2; + } else { + data += 2; + len -= 2; + } + + if (sof) { + /* extra bytes....., could be processed too but would be + * a waste of time, right now leave the application and + * libjpeg do it for ourserlves.. */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + ffd9, 2); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + return; + } + + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + memset(menu->name, 0, sizeof menu->name); + + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy(menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy(menu->name, "60 Hz"); + return 0; + } + break; + case V4L2_CID_EFFECTS: + if (menu->index < 0 || menu->index >= NUM_EFFECTS_CONTROL) + return -EINVAL; + strncpy((char *) menu->name, + effects_control[menu->index].name, 32); + break; + } + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + init_default_parameters(gspca_dev); + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, + .querymenu = sd_querymenu, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c new file mode 100644 index 000000000000..6218441ba1f0 --- /dev/null +++ b/drivers/media/video/gspca/tv8532.c @@ -0,0 +1,709 @@ +/* + * Quickcam cameras initialization data + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#define MODULE_NAME "tv8532" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("TV8532 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + int buflen; /* current length of tmpbuf */ + __u8 tmpbuf[352 * 288 + 10 * 288]; /* no protection... */ + __u8 tmpbuf2[352 * 288]; /* no protection... */ + + unsigned short brightness; + unsigned short contrast; + + char packet; + char synchro; +}; + +/* V4L2 controls supported by the driver */ +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_BRIGHTNESS 0 + { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 1, + .maximum = 0x2ff, + .step = 1, + .default_value = 0x18f, + }, + .set = sd_setbrightness, + .get = sd_getbrightness, + }, +#define SD_CONTRAST 1 + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 0xffff, + .step = 1, + .default_value = 0x7fff, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, +}; + +static struct cam_mode sif_mode[] = { + {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, + {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, +}; + +/* + * Initialization data: this is the first set-up data written to the + * device (before the open data). + */ +#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */ +#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */ +#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */ +#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */ +#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */ +#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */ +#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */ +#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */ +#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */ +#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */ +#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */ +#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */ +#define EXPOL 0x8f /* reg 0x1c -> 0x8f */ +#define EXPOH 0x01 /* reg 0x1d -> 0x01 */ +#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */ +#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */ +#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */ +#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */ +#define TV8532_CMD_UPDATE 0x84 + +#define TV8532_EEprom_Add 0x03 +#define TV8532_EEprom_DataL 0x04 +#define TV8532_EEprom_DataM 0x05 +#define TV8532_EEprom_DataH 0x06 +#define TV8532_EEprom_TableLength 0x07 +#define TV8532_EEprom_Write 0x08 +#define TV8532_PART_CTRL 0x00 +#define TV8532_CTRL 0x01 +#define TV8532_CMD_EEprom_Open 0x30 +#define TV8532_CMD_EEprom_Close 0x29 +#define TV8532_UDP_UPDATE 0x31 +#define TV8532_GPIO 0x39 +#define TV8532_GPIO_OE 0x3B +#define TV8532_REQ_RegWrite 0x02 +#define TV8532_REQ_RegRead 0x03 + +#define TV8532_ADWIDTH_L 0x0C +#define TV8532_ADWIDTH_H 0x0D +#define TV8532_ADHEIGHT_L 0x0E +#define TV8532_ADHEIGHT_H 0x0F +#define TV8532_EXPOSURE 0x1C +#define TV8532_QUANT_COMP 0x28 +#define TV8532_MODE_PACKET 0x29 +#define TV8532_SETCLK 0x2C +#define TV8532_POINT_L 0x2D +#define TV8532_POINT_H 0x2E +#define TV8532_POINTB_L 0x2F +#define TV8532_POINTB_H 0x30 +#define TV8532_BUDGET_L 0x2A +#define TV8532_BUDGET_H 0x2B +#define TV8532_VID_L 0x34 +#define TV8532_VID_H 0x35 +#define TV8532_PID_L 0x36 +#define TV8532_PID_H 0x37 +#define TV8532_DeviceID 0x83 +#define TV8532_AD_SLOPE 0x91 +#define TV8532_AD_BITCTRL 0x94 +#define TV8532_AD_COLBEGIN_L 0x10 +#define TV8532_AD_COLBEGIN_H 0x11 +#define TV8532_AD_ROWBEGIN_L 0x14 +#define TV8532_AD_ROWBEGIN_H 0x15 + +static __u32 tv_8532_eeprom_data[] = { +/* add dataL dataM dataH */ + 0x00010001, 0x01018011, 0x02050014, 0x0305001c, + 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, + 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9, + 0x0c0509f1, 0 +}; + +static void reg_r(struct usb_device *dev, + __u16 index, __u8 *buffer) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + TV8532_REQ_RegRead, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, sizeof(__u8), + 500); +} + +static void reg_w(struct usb_device *dev, + __u16 index, __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + TV8532_REQ_RegWrite, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, buffer, length, 500); +} + +static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) +{ + int i = 0; + __u8 reg, data0, data1, data2, datacmd; + struct usb_device *dev = gspca_dev->dev; + + datacmd = 0xb0;; + reg_w(dev, TV8532_GPIO, &datacmd, 1); + datacmd = TV8532_CMD_EEprom_Open; + reg_w(dev, TV8532_CTRL, &datacmd, + 1); +/* msleep(1); */ + while (tv_8532_eeprom_data[i]) { + reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; + reg_w(dev, TV8532_EEprom_Add, ®, 1); + /* msleep(1); */ + data0 = (tv_8532_eeprom_data[i] & 0x000000ff); + reg_w(dev, TV8532_EEprom_DataL, &data0, 1); + /* msleep(1); */ + data1 = (tv_8532_eeprom_data[i] & 0x0000FF00) >> 8; + reg_w(dev, TV8532_EEprom_DataM, &data1, 1); + /* msleep(1); */ + data2 = (tv_8532_eeprom_data[i] & 0x00FF0000) >> 16; + reg_w(dev, TV8532_EEprom_DataH, &data2, 1); + /* msleep(1); */ + datacmd = 0; + reg_w(dev, TV8532_EEprom_Write, &datacmd, 1); + /* msleep(10); */ + i++; + } + datacmd = i; + reg_w(dev, TV8532_EEprom_TableLength, &datacmd, 1); +/* msleep(1); */ + datacmd = TV8532_CMD_EEprom_Close; + reg_w(dev, TV8532_CTRL, &datacmd, 1); + msleep(10); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct cam *cam; + + tv_8532WriteEEprom(gspca_dev); + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 1; + cam->cam_mode = sif_mode; + cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + + sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + return 0; +} + +static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data = 0; +/* __u16 vid, pid; */ + + reg_r(dev, 0x0001, &data); + PDEBUG(D_USBI, "register 0x01-> %x", data); + reg_r(dev, 0x0002, &data); + PDEBUG(D_USBI, "register 0x02-> %x", data); + reg_r(dev, TV8532_ADWIDTH_L, &data); + reg_r(dev, TV8532_ADWIDTH_H, &data); + reg_r(dev, TV8532_QUANT_COMP, &data); + reg_r(dev, TV8532_MODE_PACKET, &data); + reg_r(dev, TV8532_SETCLK, &data); + reg_r(dev, TV8532_POINT_L, &data); + reg_r(dev, TV8532_POINT_H, &data); + reg_r(dev, TV8532_POINTB_L, &data); + reg_r(dev, TV8532_POINTB_H, &data); + reg_r(dev, TV8532_BUDGET_L, &data); + reg_r(dev, TV8532_BUDGET_H, &data); + reg_r(dev, TV8532_VID_L, &data); + reg_r(dev, TV8532_VID_H, &data); + reg_r(dev, TV8532_PID_L, &data); + reg_r(dev, TV8532_PID_H, &data); + reg_r(dev, TV8532_DeviceID, &data); + reg_r(dev, TV8532_AD_COLBEGIN_L, &data); + reg_r(dev, TV8532_AD_COLBEGIN_H, &data); + reg_r(dev, TV8532_AD_ROWBEGIN_L, &data); + reg_r(dev, TV8532_AD_ROWBEGIN_H, &data); +} + +static void tv_8532_setReg(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data = 0; + __u8 value[2] = { 0, 0 }; + + data = ADCBEGINL; + reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ + data = ADCBEGINH; /* also digital gain */ + reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); + data = TV8532_CMD_UPDATE; + reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + + data = 0x0a; + reg_w(dev, TV8532_GPIO_OE, &data, 1); + /******************************************************/ + data = ADHEIGHL; + reg_w(dev, TV8532_ADHEIGHT_L, &data, 1); /* 0e */ + data = ADHEIGHH; + reg_w(dev, TV8532_ADHEIGHT_H, &data, 1); /* 0f */ + value[0] = EXPOL; + value[1] = EXPOH; /* 350d 0x014c; */ + reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ + data = ADCBEGINL; + reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ + data = ADCBEGINH; /* also digital gain */ + reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); + data = ADRBEGINL; + reg_w(dev, TV8532_AD_ROWBEGIN_L, &data, 1); /* 0x14 */ + + data = 0x00; + reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ + data = 0x02; + reg_w(dev, TV8532_AD_BITCTRL, &data, 1); /* 0x94 */ + + + data = TV8532_CMD_EEprom_Close; + reg_w(dev, TV8532_CTRL, &data, 1); /* 0x01 */ + + data = 0x00; + reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ + data = TV8532_CMD_UPDATE; + reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ +} + +static void tv_8532_PollReg(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data = 0; + int i; + + /* strange polling from tgc */ + for (i = 0; i < 10; i++) { + data = TESTCLK; /* 0x48; //0x08; */ + reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ + data = TV8532_CMD_UPDATE; + reg_w(dev, TV8532_PART_CTRL, &data, 1); + data = 0x01; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + } +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data = 0; + __u8 dataStart = 0; + __u8 value[2] = { 0, 0 }; + + data = 0x32; + reg_w(dev, TV8532_AD_SLOPE, &data, 1); + data = 0; + reg_w(dev, TV8532_AD_BITCTRL, &data, 1); + tv_8532ReadRegisters(gspca_dev); + data = 0x0b; + reg_w(dev, TV8532_GPIO_OE, &data, 1); + value[0] = ADHEIGHL; + value[1] = ADHEIGHH; /* 401d 0x0169; */ + reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ + value[0] = EXPOL; + value[1] = EXPOH; /* 350d 0x014c; */ + reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ + data = ADWIDTHL; /* 0x20; */ + reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ + data = ADWIDTHH; + reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ + + /*******************************************************************/ + data = TESTCOMP; /* 0x72 compressed mode */ + reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ + data = TESTLINE; /* 0x84; // CIF | 4 packet */ + reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + + /************************************************/ + data = TESTCLK; /* 0x48; //0x08; */ + reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ + data = TESTPTL; /* 0x38; */ + reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ + data = TESTPTH; /* 0x04; */ + reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ + dataStart = TESTPTBL; /* 0x04; */ + reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ + data = TESTPTBH; /* 0x04; */ + reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ + data = TV8532_CMD_UPDATE; + reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + /*************************************************/ + data = 0x01; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + msleep(200); + data = 0x00; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + /*************************************************/ + tv_8532_setReg(gspca_dev); + /*************************************************/ + data = 0x0b; + reg_w(dev, TV8532_GPIO_OE, &data, + 1); + /*************************************************/ + tv_8532_setReg(gspca_dev); + /*************************************************/ + tv_8532_PollReg(gspca_dev); + return 0; +} + +static void setbrightness(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + __u8 value[2]; + __u8 data; + int brightness = sd->brightness; + + value[1] = (brightness >> 8) & 0xff; + value[0] = (brightness) & 0xff; + reg_w(gspca_dev->dev, TV8532_EXPOSURE, value, 2); /* 1c */ + data = TV8532_CMD_UPDATE; + reg_w(gspca_dev->dev, TV8532_PART_CTRL, &data, 1); +} + +/* -- start the camera -- */ +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data = 0; + __u8 dataStart = 0; + __u8 value[2]; + + data = 0x32; + reg_w(dev, TV8532_AD_SLOPE, &data, 1); + data = 0; + reg_w(dev, TV8532_AD_BITCTRL, &data, 1); + tv_8532ReadRegisters(gspca_dev); + data = 0x0b; + reg_w(dev, TV8532_GPIO_OE, &data, 1); + value[0] = ADHEIGHL; + value[1] = ADHEIGHH; /* 401d 0x0169; */ + reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ +/* value[0] = EXPOL; value[1] =EXPOH; * 350d 0x014c; */ +/* reg_w(dev,TV8532_REQ_RegWrite,0,TV8532_EXPOSURE,value,2); * 1c */ + setbrightness(gspca_dev); + + data = ADWIDTHL; /* 0x20; */ + reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ + data = ADWIDTHH; + reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ + + /************************************************/ + data = TESTCOMP; /* 0x72 compressed mode */ + reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + /* 176x144 */ + data = QCIFLINE; /* 0x84; // CIF | 4 packet */ + reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + } else { + /* 352x288 */ + data = TESTLINE; /* 0x84; // CIF | 4 packet */ + reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + } + /************************************************/ + data = TESTCLK; /* 0x48; //0x08; */ + reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ + data = TESTPTL; /* 0x38; */ + reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ + data = TESTPTH; /* 0x04; */ + reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ + dataStart = TESTPTBL; /* 0x04; */ + reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ + data = TESTPTBH; /* 0x04; */ + reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ + data = TV8532_CMD_UPDATE; + reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + /************************************************/ + data = 0x01; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + msleep(200); + data = 0x00; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + /************************************************/ + tv_8532_setReg(gspca_dev); + /************************************************/ + data = 0x0b; + reg_w(dev, TV8532_GPIO_OE, &data, 1); + /************************************************/ + tv_8532_setReg(gspca_dev); + /************************************************/ + tv_8532_PollReg(gspca_dev); + data = 0x00; + reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + __u8 data; + + data = 0x0b; + reg_w(dev, TV8532_GPIO_OE, &data, 1); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ +} + +static void sd_close(struct gspca_dev *gspca_dev) +{ +} + +static void tv8532_preprocess(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; +/* we should received a whole frame with header and EOL marker + * in gspca_dev->tmpbuf and return a GBRG pattern in gspca_dev->tmpbuf2 + * sequence 2bytes header the Alternate pixels bayer GB 4 bytes + * Alternate pixels bayer RG 4 bytes EOL */ + int width = gspca_dev->width; + int height = gspca_dev->height; + unsigned char *dst = sd->tmpbuf2; + unsigned char *data = sd->tmpbuf; + int i; + + /* precompute where is the good bayer line */ + if (((data[3] + data[width + 7]) >> 1) + + (data[4] >> 2) + + (data[width + 6] >> 1) >= ((data[2] + data[width + 6]) >> 1) + + (data[3] >> 2) + + (data[width + 5] >> 1)) + data += 3; + else + data += 2; + for (i = 0; i < height / 2; i++) { + memcpy(dst, data, width); + data += width + 3; + dst += width; + memcpy(dst, data, width); + data += width + 7; + dst += width; + } +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + __u8 *data, /* isoc packet */ + int len) /* iso packet length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (data[0] != 0x80) { + sd->packet++; + if (sd->buflen + len > sizeof sd->tmpbuf) { + if (gspca_dev->last_packet_type != DISCARD_PACKET) { + PDEBUG(D_PACK, "buffer overflow"); + gspca_dev->last_packet_type = DISCARD_PACKET; + } + return; + } + memcpy(&sd->tmpbuf[sd->buflen], data, len); + sd->buflen += len; + return; + } + + /* here we detect 0x80 */ + /* counter is limited so we need few header for a frame :) */ + + /* header 0x80 0x80 0x80 0x80 0x80 */ + /* packet 00 63 127 145 00 */ + /* sof 0 1 1 0 0 */ + + /* update sequence */ + if (sd->packet == 63 || sd->packet == 127) + sd->synchro = 1; + + /* is there a frame start ? */ + if (sd->packet >= (gspca_dev->height >> 1) - 1) { + PDEBUG(D_PACK, "SOF > %d packet %d", sd->synchro, + sd->packet); + if (!sd->synchro) { /* start of frame */ + if (gspca_dev->last_packet_type == FIRST_PACKET) { + tv8532_preprocess(gspca_dev); + frame = gspca_frame_add(gspca_dev, + LAST_PACKET, + frame, sd->tmpbuf2, + gspca_dev->width * + gspca_dev->width); + } + gspca_frame_add(gspca_dev, FIRST_PACKET, + frame, data, 0); + memcpy(sd->tmpbuf, data, len); + sd->buflen = len; + sd->packet = 0; + return; + } + if (gspca_dev->last_packet_type != DISCARD_PACKET) { + PDEBUG(D_PACK, + "Warning wrong TV8532 frame detection %d", + sd->packet); + gspca_dev->last_packet_type = DISCARD_PACKET; + } + return; + } + + if (!sd->synchro) { + /* Drop packet frame corrupt */ + PDEBUG(D_PACK, "DROP SOF %d packet %d", + sd->synchro, sd->packet); + sd->packet = 0; + gspca_dev->last_packet_type = DISCARD_PACKET; + return; + } + sd->synchro = 1; + sd->packet++; + memcpy(&sd->tmpbuf[sd->buflen], data, len); + sd->buflen += len; +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ +} + +static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->brightness = val; + if (gspca_dev->streaming) + setbrightness(gspca_dev); + return 0; +} + +static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->brightness; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, + {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, + {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, + {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")}, + {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")}, + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} + +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c new file mode 100644 index 000000000000..8b5f6d17d2a5 --- /dev/null +++ b/drivers/media/video/gspca/vc032x.c @@ -0,0 +1,1816 @@ +/* + * Z-star vc0321 library + * Copyright (C) 2006 Koninski Artur takeshi87@o2.pl + * Copyright (C) 2006 Michel Xhaard + * + * V4L2 by Jean-Francois Moine + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "vc032x" + +#include "gspca.h" + +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; + +MODULE_AUTHOR("Michel Xhaard "); +MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + + unsigned char autogain; + unsigned char lightfreq; + + char qindex; + char bridge; +#define BRIDGE_VC0321 0 +#define BRIDGE_VC0323 1 + char sensor; +#define SENSOR_HV7131R 0 +#define SENSOR_MI1320 1 +#define SENSOR_MI1310_SOC 2 +#define SENSOR_OV7660 3 +#define SENSOR_OV7670 4 +#define SENSOR_PO3130NC 5 +}; + +/* V4L2 controls supported by the driver */ +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); + +static struct ctrl sd_ctrls[] = { +#define SD_AUTOGAIN 0 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Gain", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + }, + .set = sd_setautogain, + .get = sd_getautogain, + }, +#define SD_FREQ 1 + { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light frequency filter", + .minimum = 0, + .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .step = 1, + .default_value = 1, + }, + .set = sd_setfreq, + .get = sd_getfreq, + }, +}; + +static struct cam_mode vc0321_mode[] = { + {V4L2_PIX_FMT_YUYV, 320, 240, 1}, + {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +}; +static struct cam_mode vc0323_mode[] = { + {V4L2_PIX_FMT_JPEG, 320, 240, 1}, + {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +}; + +static __u8 mi1310_socinitVGA_JPG[][4] = { + {0xb0, 0x03, 0x19, 0xcc}, + {0xb0, 0x04, 0x02, 0xcc}, + {0xb3, 0x00, 0x64, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x00, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x02, 0x00, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x03, 0xcc}, + {0xb3, 0x23, 0xc0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x04, 0xcc}, + {0xb3, 0x17, 0xff, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, + {0xb8, 0x00, 0x00, 0xcc}, + {0xbc, 0x00, 0xd0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, + {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x9f, 0x0b, 0xbb}, + {0x5b, 0x00, 0x01, 0xbb}, + {0x2f, 0xde, 0x20, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x20, 0x03, 0x02, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x05, 0x00, 0x07, 0xbb}, + {0x34, 0x00, 0x00, 0xbb}, + {0x35, 0xff, 0x00, 0xbb}, + {0xdc, 0x07, 0x02, 0xbb}, + {0xdd, 0x3c, 0x18, 0xbb}, + {0xde, 0x92, 0x6d, 0xbb}, + {0xdf, 0xcd, 0xb1, 0xbb}, + {0xe0, 0xff, 0xe7, 0xbb}, + {0x06, 0xf0, 0x0d, 0xbb}, + {0x06, 0x70, 0x0e, 0xbb}, + {0x4c, 0x00, 0x01, 0xbb}, + {0x4d, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x2e, 0x0c, 0x55, 0xbb}, + {0x21, 0xb6, 0x6e, 0xbb}, + {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc1, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x07, 0x00, 0x84, 0xbb}, + {0x08, 0x02, 0x4a, 0xbb}, + {0x05, 0x01, 0x10, 0xbb}, + {0x06, 0x00, 0x39, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x58, 0x02, 0x67, 0xbb}, + {0x57, 0x02, 0x00, 0xbb}, + {0x5a, 0x02, 0x67, 0xbb}, + {0x59, 0x02, 0x00, 0xbb}, + {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, + {0x39, 0x06, 0x18, 0xbb}, + {0x3a, 0x06, 0x18, 0xbb}, + {0x3b, 0x06, 0x18, 0xbb}, + {0x3c, 0x06, 0x18, 0xbb}, + {0x64, 0x7b, 0x5b, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc0, 0xbb}, + {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, + {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, + {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x02, 0xcc}, + {0xb6, 0x02, 0x80, 0xcc}, + {0xb6, 0x05, 0x01, 0xcc}, + {0xb6, 0x04, 0xe0, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, + {0xb6, 0x13, 0x25, 0xcc}, + {0xb6, 0x18, 0x02, 0xcc}, + {0xb6, 0x17, 0x58, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, + {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, + {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, + {0xbf, 0xcc, 0x00, 0xcc}, + {0xbc, 0x02, 0x18, 0xcc}, + {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, + {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, + {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, + {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, + {0xbc, 0x0c, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x80, 0x00, 0x03, 0xbb}, + {0x81, 0xc7, 0x14, 0xbb}, + {0x82, 0xeb, 0xe8, 0xbb}, + {0x83, 0xfe, 0xf4, 0xbb}, + {0x84, 0xcd, 0x10, 0xbb}, + {0x85, 0xf3, 0xee, 0xbb}, + {0x86, 0xff, 0xf1, 0xbb}, + {0x87, 0xcd, 0x10, 0xbb}, + {0x88, 0xf3, 0xee, 0xbb}, + {0x89, 0x01, 0xf1, 0xbb}, + {0x8a, 0xe5, 0x17, 0xbb}, + {0x8b, 0xe8, 0xe2, 0xbb}, + {0x8c, 0xf7, 0xed, 0xbb}, + {0x8d, 0x00, 0xff, 0xbb}, + {0x8e, 0xec, 0x10, 0xbb}, + {0x8f, 0xf0, 0xed, 0xbb}, + {0x90, 0xf9, 0xf2, 0xbb}, + {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xe9, 0x0d, 0xbb}, + {0x93, 0xf4, 0xf2, 0xbb}, + {0x94, 0xfb, 0xf5, 0xbb}, + {0x95, 0x00, 0xff, 0xbb}, + {0xb6, 0x0f, 0x08, 0xbb}, + {0xb7, 0x3d, 0x16, 0xbb}, + {0xb8, 0x0c, 0x04, 0xbb}, + {0xb9, 0x1c, 0x07, 0xbb}, + {0xba, 0x0a, 0x03, 0xbb}, + {0xbb, 0x1b, 0x09, 0xbb}, + {0xbc, 0x17, 0x0d, 0xbb}, + {0xbd, 0x23, 0x1d, 0xbb}, + {0xbe, 0x00, 0x28, 0xbb}, + {0xbf, 0x11, 0x09, 0xbb}, + {0xc0, 0x16, 0x15, 0xbb}, + {0xc1, 0x00, 0x1b, 0xbb}, + {0xc2, 0x0e, 0x07, 0xbb}, + {0xc3, 0x14, 0x10, 0xbb}, + {0xc4, 0x00, 0x17, 0xbb}, + {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, + {0x06, 0xf4, 0x8e, 0xbb}, + {0x00, 0x00, 0x50, 0xdd}, + {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x24, 0x50, 0x20, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, + {0x34, 0x0c, 0x50, 0xbb}, + {0xb3, 0x01, 0x41, 0xcc}, + {0xf0, 0x00, 0x00, 0xbb}, + {0x03, 0x03, 0xc0, 0xbb}, + {}, +}; +static __u8 mi1310_socinitQVGA_JPG[][4] = { + {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc}, + {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc}, + {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc}, + {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, + {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb}, + {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb}, + {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb}, + {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb}, + {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb}, + {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb}, + {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb}, + {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb}, + {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb}, + {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb}, + {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb}, + {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb}, + {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, + {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc}, + {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb}, + {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb}, + {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb}, + {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb}, + {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb}, + {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb}, + {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb}, + {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb}, + {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb}, + {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb}, + {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb}, + {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb}, + {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb}, + {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb}, + {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb}, + {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb}, + {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb}, + {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb}, + {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb}, + {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb}, + {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, + {0x03, 0x03, 0xc0, 0xbb}, + {}, +}; + +static __u8 mi1320_gamma[17] = { + 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff +}; +static __u8 mi1320_matrix[9] = { + 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 +}; +static __u8 mi1320_initVGA_data[][4] = { + {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x00, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x03, 0xcc}, {0xb3, 0x23, 0xc0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x04, 0xcc}, {0xb3, 0x17, 0xff, 0xcc}, + {0xb3, 0x00, 0x67, 0xcc}, {0xbc, 0x00, 0xd0, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x00, 0xbb}, + {0x0d, 0x00, 0x09, 0xbb}, {0x00, 0x01, 0x00, 0xdd}, + {0x0d, 0x00, 0x08, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0xa1, 0x05, 0x00, 0xbb}, {0xa4, 0x03, 0xc0, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xc8, 0x9f, 0x0b, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0x20, 0x01, 0x00, 0xbb}, {0x00, 0x00, 0x10, 0xdd}, + {0xf0, 0x00, 0x01, 0xbb}, {0x9d, 0x3c, 0xa0, 0xbb}, + {0x47, 0x30, 0x30, 0xbb}, {0xf0, 0x00, 0x00, 0xbb}, + {0x0a, 0x80, 0x11, 0xbb}, {0x35, 0x00, 0x22, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x9d, 0xc5, 0x05, 0xbb}, + {0xdc, 0x0f, 0xfc, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x06, 0x74, 0x0e, 0xbb}, {0x80, 0x00, 0x06, 0xbb}, + {0x81, 0x04, 0x00, 0xbb}, {0x82, 0x01, 0x02, 0xbb}, + {0x83, 0x03, 0x02, 0xbb}, {0x84, 0x05, 0x00, 0xbb}, + {0x85, 0x01, 0x00, 0xbb}, {0x86, 0x03, 0x02, 0xbb}, + {0x87, 0x05, 0x00, 0xbb}, {0x88, 0x01, 0x00, 0xbb}, + {0x89, 0x02, 0x02, 0xbb}, {0x8a, 0xfd, 0x04, 0xbb}, + {0x8b, 0xfc, 0xfd, 0xbb}, {0x8c, 0xff, 0xfd, 0xbb}, + {0x8d, 0x00, 0x00, 0xbb}, {0x8e, 0xfe, 0x05, 0xbb}, + {0x8f, 0xfc, 0xfd, 0xbb}, {0x90, 0xfe, 0xfd, 0xbb}, + {0x91, 0x00, 0x00, 0xbb}, {0x92, 0xfe, 0x03, 0xbb}, + {0x93, 0xfd, 0xfe, 0xbb}, {0x94, 0xff, 0xfd, 0xbb}, + {0x95, 0x00, 0x00, 0xbb}, {0xb6, 0x07, 0x05, 0xbb}, + {0xb7, 0x13, 0x06, 0xbb}, {0xb8, 0x08, 0x06, 0xbb}, + {0xb9, 0x14, 0x08, 0xbb}, {0xba, 0x06, 0x05, 0xbb}, + {0xbb, 0x13, 0x06, 0xbb}, {0xbc, 0x03, 0x01, 0xbb}, + {0xbd, 0x03, 0x04, 0xbb}, {0xbe, 0x00, 0x02, 0xbb}, + {0xbf, 0x03, 0x01, 0xbb}, {0xc0, 0x02, 0x04, 0xbb}, + {0xc1, 0x00, 0x04, 0xbb}, {0xc2, 0x02, 0x01, 0xbb}, + {0xc3, 0x01, 0x03, 0xbb}, {0xc4, 0x00, 0x04, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x05, 0x01, 0x13, 0xbb}, + {0x06, 0x00, 0x11, 0xbb}, {0x07, 0x00, 0x85, 0xbb}, + {0x08, 0x00, 0x27, 0xbb}, {0x20, 0x01, 0x03, 0xbb}, + {0x21, 0x80, 0x00, 0xbb}, {0x22, 0x0d, 0x0f, 0xbb}, + {0x24, 0x80, 0x00, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x39, 0x03, 0x0d, 0xbb}, + {0x3a, 0x06, 0x1b, 0xbb}, {0x3b, 0x00, 0x95, 0xbb}, + {0x3c, 0x04, 0xdb, 0xbb}, {0x57, 0x02, 0x00, 0xbb}, + {0x58, 0x02, 0x66, 0xbb}, {0x59, 0x00, 0xff, 0xbb}, + {0x5a, 0x01, 0x33, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb}, + {0x5d, 0x16, 0x11, 0xbb}, {0x64, 0x5e, 0x1c, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, + {0x5b, 0x00, 0x01, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0x36, 0x68, 0x10, 0xbb}, {0x00, 0x00, 0x30, 0xdd}, + {0x37, 0x82, 0x00, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc}, + {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc}, + {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x05, 0xcc}, {0xb6, 0x02, 0x00, 0xcc}, + {0xb6, 0x05, 0x04, 0xcc}, {0xb6, 0x04, 0x00, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x29, 0xcc}, + {0xb6, 0x18, 0x0a, 0xcc}, {0xb6, 0x17, 0x00, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x26, 0xcc}, + {0xbf, 0xc1, 0x02, 0xcc}, {0xbf, 0xcc, 0x04, 0xcc}, + {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, + {} +}; +static __u8 mi1320_initQVGA_data[][4] = { + {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, + {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, + {0xb0, 0x16, 0x03, 0xcc}, {0xb3, 0x05, 0x01, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x34, 0x02, 0xcc}, + {0xb3, 0x35, 0xc8, 0xcc}, {0xb3, 0x02, 0x00, 0xcc}, + {0xb3, 0x03, 0x0a, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x00, 0x65, 0xcc}, {0xb8, 0x00, 0x00, 0xcc}, + {0xbc, 0x00, 0xd0, 0xcc}, {0xbc, 0x01, 0x01, 0xcc}, + {0xf0, 0x00, 0x00, 0xbb}, {0x0d, 0x00, 0x09, 0xbb}, + {0x00, 0x01, 0x00, 0xdd}, {0x0d, 0x00, 0x08, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x02, 0x00, 0x64, 0xbb}, + {0x05, 0x01, 0x78, 0xbb}, {0x06, 0x00, 0x11, 0xbb}, + {0x07, 0x01, 0x42, 0xbb}, {0x08, 0x00, 0x11, 0xbb}, + {0x20, 0x01, 0x00, 0xbb}, {0x21, 0x80, 0x00, 0xbb}, + {0x22, 0x0d, 0x0f, 0xbb}, {0x24, 0x80, 0x00, 0xbb}, + {0x59, 0x00, 0xff, 0xbb}, {0xf0, 0x00, 0x01, 0xbb}, + {0x9d, 0x3c, 0xa0, 0xbb}, {0x47, 0x30, 0x30, 0xbb}, + {0xf0, 0x00, 0x00, 0xbb}, {0x0a, 0x80, 0x11, 0xbb}, + {0x35, 0x00, 0x22, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0x9d, 0xc5, 0x05, 0xbb}, {0xdc, 0x0f, 0xfc, 0xbb}, + {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0x74, 0x0e, 0xbb}, + {0x80, 0x00, 0x06, 0xbb}, {0x81, 0x04, 0x00, 0xbb}, + {0x82, 0x01, 0x02, 0xbb}, {0x83, 0x03, 0x02, 0xbb}, + {0x84, 0x05, 0x00, 0xbb}, {0x85, 0x01, 0x00, 0xbb}, + {0x86, 0x03, 0x02, 0xbb}, {0x87, 0x05, 0x00, 0xbb}, + {0x88, 0x01, 0x00, 0xbb}, {0x89, 0x02, 0x02, 0xbb}, + {0x8a, 0xfd, 0x04, 0xbb}, {0x8b, 0xfc, 0xfd, 0xbb}, + {0x8c, 0xff, 0xfd, 0xbb}, {0x8d, 0x00, 0x00, 0xbb}, + {0x8e, 0xfe, 0x05, 0xbb}, {0x8f, 0xfc, 0xfd, 0xbb}, + {0x90, 0xfe, 0xfd, 0xbb}, {0x91, 0x00, 0x00, 0xbb}, + {0x92, 0xfe, 0x03, 0xbb}, {0x93, 0xfd, 0xfe, 0xbb}, + {0x94, 0xff, 0xfd, 0xbb}, {0x95, 0x00, 0x00, 0xbb}, + {0xb6, 0x07, 0x05, 0xbb}, {0xb7, 0x13, 0x06, 0xbb}, + {0xb8, 0x08, 0x06, 0xbb}, {0xb9, 0x14, 0x08, 0xbb}, + {0xba, 0x06, 0x05, 0xbb}, {0xbb, 0x13, 0x06, 0xbb}, + {0xbc, 0x03, 0x01, 0xbb}, {0xbd, 0x03, 0x04, 0xbb}, + {0xbe, 0x00, 0x02, 0xbb}, {0xbf, 0x03, 0x01, 0xbb}, + {0xc0, 0x02, 0x04, 0xbb}, {0xc1, 0x00, 0x04, 0xbb}, + {0xc2, 0x02, 0x01, 0xbb}, {0xc3, 0x01, 0x03, 0xbb}, + {0xc4, 0x00, 0x04, 0xbb}, {0xf0, 0x00, 0x02, 0xbb}, + {0xc8, 0x00, 0x00, 0xbb}, {0x2e, 0x00, 0x00, 0xbb}, + {0x2e, 0x0c, 0x5b, 0xbb}, {0x2f, 0xd1, 0x00, 0xbb}, + {0x39, 0x03, 0xca, 0xbb}, {0x3a, 0x06, 0x80, 0xbb}, + {0x3b, 0x01, 0x52, 0xbb}, {0x3c, 0x05, 0x40, 0xbb}, + {0x57, 0x01, 0x9c, 0xbb}, {0x58, 0x01, 0xee, 0xbb}, + {0x59, 0x00, 0xf0, 0xbb}, {0x5a, 0x01, 0x20, 0xbb}, + {0x5c, 0x1d, 0x17, 0xbb}, {0x5d, 0x22, 0x1c, 0xbb}, + {0x64, 0x1e, 0x1c, 0xbb}, {0x5b, 0x00, 0x01, 0xbb}, + {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x68, 0x10, 0xbb}, + {0x00, 0x00, 0x30, 0xdd}, {0x37, 0x81, 0x00, 0xbb}, + {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xbf, 0xc0, 0x26, 0xcc}, {0xbf, 0xc1, 0x02, 0xcc}, + {0xbf, 0xcc, 0x04, 0xcc}, {0xb3, 0x5c, 0x01, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, + {} +}; + +static __u8 po3130_gamma[17] = { + 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff +}; +static __u8 po3130_matrix[9] = { + 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 +}; + +static __u8 po3130_initVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, + {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, + {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe8, 0xcc}, {0xb8, 0x08, 0xe8, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, + {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0x71, 0xcc}, + {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, + {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, + {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, + {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, + {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, + {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, + {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, + {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, + {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, + {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, + {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, + {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, + {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, + {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, + {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, + {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, + {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, + {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, + {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, + {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, + {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, + {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, + {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, + {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, + {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, + {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, + {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, + {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, + {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, + {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, + {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, + {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, + {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, + {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, + {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, + {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, + {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, + {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, + {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, + {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, + {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, + {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, + {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, + {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, + {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, + {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, + {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, + {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, + {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, + {0x00, 0x7e, 0xea, 0xaa}, + {0x00, 0x4c, 0x07, 0xaa}, + {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, + {0x00, 0x59, 0x02, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, +/* {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, + {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, */ + {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, + {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, + {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, + {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, + {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, + {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, + {0xb9, 0x08, 0x3c, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, + {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, + {} +}; +static __u8 po3130_rundata[][4] = { + {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, + {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, + {0x00, 0x44, 0x40, 0xaa}, +/* {0x00, 0xd5, 0x7c, 0xaa}, */ + {0x00, 0xad, 0x04, 0xaa}, {0x00, 0xae, 0x00, 0xaa}, + {0x00, 0xb0, 0x78, 0xaa}, {0x00, 0x98, 0x02, 0xaa}, + {0x00, 0x94, 0x25, 0xaa}, {0x00, 0x95, 0x25, 0xaa}, + {0x00, 0x59, 0x68, 0xaa}, {0x00, 0x44, 0x20, 0xaa}, + {0x00, 0x17, 0x50, 0xaa}, {0x00, 0x19, 0x50, 0xaa}, + {0x00, 0xd1, 0x3c, 0xaa}, {0x00, 0xd1, 0x3c, 0xaa}, + {0x00, 0x1e, 0x06, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, + {} +}; + +static __u8 po3130_initQVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, + {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, {0xb3, 0x03, 0x1a, 0xcc}, + {0xb3, 0x04, 0x15, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xb8, 0x08, 0xe0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0xf6, 0xcc}, + {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, + {0xb8, 0x00, 0x21, 0xcc}, {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x01, 0x79, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x2c, 0x50, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, + {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, + {0xb8, 0x30, 0x50, 0xcc}, {0xb8, 0x31, 0xf8, 0xcc}, + {0xb8, 0x32, 0xf8, 0xcc}, {0xb8, 0x33, 0xf8, 0xcc}, + {0xb8, 0x34, 0x50, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, + {0x00, 0x1e, 0xc6, 0xaa}, {0x00, 0x20, 0x44, 0xaa}, + {0x00, 0xad, 0x02, 0xaa}, {0x00, 0xae, 0x2c, 0xaa}, + {0x00, 0x12, 0x08, 0xaa}, {0x00, 0x17, 0x41, 0xaa}, + {0x00, 0x19, 0x41, 0xaa}, {0x00, 0x1e, 0x06, 0xaa}, + {0x00, 0x21, 0x00, 0xaa}, {0x00, 0x36, 0xc0, 0xaa}, + {0x00, 0x37, 0xc8, 0xaa}, {0x00, 0x3b, 0x36, 0xaa}, + {0x00, 0x4b, 0xfe, 0xaa}, {0x00, 0x51, 0x1c, 0xaa}, + {0x00, 0x52, 0x01, 0xaa}, {0x00, 0x55, 0x0a, 0xaa}, + {0x00, 0x59, 0x6f, 0xaa}, {0x00, 0x5a, 0x04, 0xaa}, + {0x00, 0x5c, 0x10, 0xaa}, {0x00, 0x5d, 0x10, 0xaa}, + {0x00, 0x5e, 0x10, 0xaa}, {0x00, 0x5f, 0x10, 0xaa}, + {0x00, 0x61, 0x00, 0xaa}, {0x00, 0x62, 0x18, 0xaa}, + {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x70, 0x68, 0xaa}, + {0x00, 0x80, 0x71, 0xaa}, {0x00, 0x81, 0x08, 0xaa}, + {0x00, 0x82, 0x00, 0xaa}, {0x00, 0x83, 0x55, 0xaa}, + {0x00, 0x84, 0x06, 0xaa}, {0x00, 0x85, 0x06, 0xaa}, + {0x00, 0x86, 0x13, 0xaa}, {0x00, 0x87, 0x18, 0xaa}, + {0x00, 0xaa, 0x3f, 0xaa}, {0x00, 0xab, 0x44, 0xaa}, + {0x00, 0xb0, 0x68, 0xaa}, {0x00, 0xb5, 0x10, 0xaa}, + {0x00, 0xb8, 0x20, 0xaa}, {0x00, 0xb9, 0xa0, 0xaa}, + {0x00, 0xbc, 0x04, 0xaa}, {0x00, 0x8b, 0x40, 0xaa}, + {0x00, 0x8c, 0x91, 0xaa}, {0x00, 0x8d, 0x8f, 0xaa}, + {0x00, 0x8e, 0x91, 0xaa}, {0x00, 0x8f, 0x43, 0xaa}, + {0x00, 0x90, 0x92, 0xaa}, {0x00, 0x91, 0x89, 0xaa}, + {0x00, 0x92, 0x9d, 0xaa}, {0x00, 0x93, 0x46, 0xaa}, + {0x00, 0xd6, 0x22, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, + {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, + {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, + {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, + {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, + {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, + {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0xd6, 0x62, 0xaa}, + {0x00, 0x73, 0x00, 0xaa}, {0x00, 0x74, 0x10, 0xaa}, + {0x00, 0x75, 0x20, 0xaa}, {0x00, 0x76, 0x2b, 0xaa}, + {0x00, 0x77, 0x36, 0xaa}, {0x00, 0x78, 0x49, 0xaa}, + {0x00, 0x79, 0x5a, 0xaa}, {0x00, 0x7a, 0x7f, 0xaa}, + {0x00, 0x7b, 0x9b, 0xaa}, {0x00, 0x7c, 0xba, 0xaa}, + {0x00, 0x7d, 0xd4, 0xaa}, {0x00, 0x7e, 0xea, 0xaa}, + {0x00, 0xd6, 0xa2, 0xaa}, {0x00, 0x73, 0x00, 0xaa}, + {0x00, 0x74, 0x10, 0xaa}, {0x00, 0x75, 0x20, 0xaa}, + {0x00, 0x76, 0x2b, 0xaa}, {0x00, 0x77, 0x36, 0xaa}, + {0x00, 0x78, 0x49, 0xaa}, {0x00, 0x79, 0x5a, 0xaa}, + {0x00, 0x7a, 0x7f, 0xaa}, {0x00, 0x7b, 0x9b, 0xaa}, + {0x00, 0x7c, 0xba, 0xaa}, {0x00, 0x7d, 0xd4, 0xaa}, + {0x00, 0x7e, 0xea, 0xaa}, {0x00, 0x4c, 0x07, 0xaa}, + {0x00, 0x4b, 0xe0, 0xaa}, {0x00, 0x4e, 0x77, 0xaa}, + {0x00, 0x59, 0x66, 0xaa}, {0x00, 0x4d, 0x0a, 0xaa}, + {0x00, 0xd1, 0x00, 0xaa}, {0x00, 0x20, 0xc4, 0xaa}, + {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, + {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, + {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, + {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, + {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, + {0xb9, 0x08, 0x3c, 0xcc}, {0xbc, 0x02, 0x18, 0xcc}, + {0xbc, 0x03, 0x50, 0xcc}, {0xbc, 0x04, 0x18, 0xcc}, + {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, + {0xbc, 0x08, 0x30, 0xcc}, {0xbc, 0x09, 0x40, 0xcc}, + {0xbc, 0x0a, 0x10, 0xcc}, {0xbc, 0x0b, 0x00, 0xcc}, + {0xbc, 0x0c, 0x00, 0xcc}, {0x00, 0x05, 0x00, 0xaa}, + {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, + {} +}; + +static __u8 hv7131r_gamma[17] = { +/* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */ + 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1, + 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff +}; +static __u8 hv7131r_matrix[9] = { + 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 +}; +static __u8 hv7131r_initVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, + {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, {0xb3, 0x23, 0xe0, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, + {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, + {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc}, + {0xbc, 0x00, 0x73, 0xcc}, + {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa}, + {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa}, + {0x00, 0x16, 0x02, 0xaa}, + {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa}, + {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa}, + {0x00, 0x27, 0xc0, 0xaa}, + {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, + {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, + {0xb8, 0x30, 0x50, 0xcc}, + {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, + {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc}, + {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc}, + {0xb8, 0x81, 0x09, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, + {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc}, + {0xb9, 0x01, 0x28, 0xcc}, + {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, + {0xb9, 0x06, 0x3c, 0xcc}, + {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, + {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, + {0x00, 0x30, 0x18, 0xaa}, + {} +}; + +static __u8 hv7131r_initQVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, + {0xb3, 0x00, 0x24, 0xcc}, + {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc}, + {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x02, 0xcc}, + {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc}, + {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, + {0xb8, 0x00, 0x21, 0xcc}, + {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa}, + {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, + {0x00, 0x17, 0x86, 0xaa}, + {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa}, + {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa}, + {0xbc, 0x02, 0x08, 0xcc}, + {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc}, + {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc}, + {0xbc, 0x08, 0x3c, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xb8, 0xfe, 0x02, 0xcc}, + {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc}, + {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc}, + {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc}, + {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc}, + {0xb9, 0x08, 0x0f, 0xcc}, + {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc}, + {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc}, + {0xb8, 0x30, 0x50, 0xcc}, + {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc}, + {0xb8, 0x33, 0xf8, 0xcc}, + {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, + {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc}, + {0xb8, 0xff, 0x28, 0xcc}, + {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, + {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, + {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, + {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc}, + {0xb8, 0x8e, 0x00, 0xcc}, + {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa}, + {} +}; + +static __u8 ov7660_gamma[17] = { + 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, + 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff +}; +static __u8 ov7660_matrix[9] = { + 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 +}; +static __u8 ov7660_initVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, + {0xb0, 0x03, 0x01, 0xcc}, + {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, + {0xb3, 0x06, 0x03, 0xcc}, + {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, + {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, + {0xb3, 0x1f, 0x02, 0xcc}, + {0xb3, 0x34, 0x01, 0xcc}, + {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, + {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ + {0xb8, 0x01, 0x7d, 0xcc}, + {0xbc, 0x00, 0x73, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, + {0xb8, 0x8f, 0x50, 0xcc}, + {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, + {0x00, 0x12, 0x80, 0xaa}, + {0x00, 0x12, 0x05, 0xaa}, + {0x00, 0x1e, 0x01, 0xaa}, + {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ + {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ + {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, + {0x00, 0x13, 0xa7, 0xaa}, + {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, + {0x00, 0x36, 0x00, 0xaa}, + {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, + {0x00, 0x39, 0x43, 0xaa}, + {0x00, 0x8d, 0xcf, 0xaa}, + {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, + {0x00, 0x0f, 0x62, 0xaa}, + {0x00, 0x35, 0x84, 0xaa}, + {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ + {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ + {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ + {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, + {0x00, 0x01, 0x80, 0xaa}, + {0x00, 0x02, 0x80, 0xaa}, + {0xb8, 0xfe, 0x00, 0xcc}, {0xb8, 0xff, 0x28, 0xcc}, + {0xb9, 0x00, 0x28, 0xcc}, + {0xb9, 0x01, 0x28, 0xcc}, {0xb9, 0x02, 0x28, 0xcc}, + {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, + {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc}, + {0xb9, 0x07, 0x3c, 0xcc}, + {0xb9, 0x08, 0x3c, 0xcc}, + + {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc}, + + {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, + {} +}; +static __u8 ov7660_initQVGA_data[][4] = { + {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, + {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, + {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x03, 0xcc}, + {0xb3, 0x03, 0x1f, 0xcc}, {0xb3, 0x04, 0x05, 0xcc}, + {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x15, 0x00, 0xcc},/* 0xb315 <-0 href startl */ + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xb3, 0x1d, 0x01, 0xcc}, + {0xb3, 0x1f, 0x02, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, + {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, + {0xb8, 0x00, 0x33, 0xcc}, /* 13 */ + {0xb8, 0x01, 0x7d, 0xcc}, +/* sizer */ + {0xbc, 0x00, 0xd3, 0xcc}, + {0xb8, 0x81, 0x09, 0xcc}, {0xb8, 0x81, 0x09, 0xcc}, + {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x8f, 0x50, 0xcc}, + {0x00, 0x01, 0x80, 0xaa}, {0x00, 0x02, 0x80, 0xaa}, + {0x00, 0x12, 0x80, 0xaa}, {0x00, 0x12, 0x05, 0xaa}, + {0x00, 0x1e, 0x01, 0xaa}, + {0x00, 0x3d, 0x40, 0xaa}, /* 0x3d <-40 gamma 01 */ + {0x00, 0x41, 0x00, 0xaa}, /* edge 00 */ + {0x00, 0x0d, 0x48, 0xaa}, {0x00, 0x0e, 0x04, 0xaa}, + {0x00, 0x13, 0xa7, 0xaa}, + {0x00, 0x40, 0xc1, 0xaa}, {0x00, 0x35, 0x00, 0xaa}, + {0x00, 0x36, 0x00, 0xaa}, + {0x00, 0x3c, 0x68, 0xaa}, {0x00, 0x1b, 0x05, 0xaa}, + {0x00, 0x39, 0x43, 0xaa}, {0x00, 0x8d, 0xcf, 0xaa}, + {0x00, 0x8b, 0xcc, 0xaa}, {0x00, 0x8c, 0xcc, 0xaa}, + {0x00, 0x0f, 0x62, 0xaa}, {0x00, 0x35, 0x84, 0xaa}, + {0x00, 0x3b, 0x08, 0xaa}, /* 0 * Nightframe 1/4 + 50Hz -> 0xC8 */ + {0x00, 0x3a, 0x00, 0xaa}, /* mx change yuyv format 00, 04, 01; 08, 0c*/ + {0x00, 0x14, 0x2a, 0xaa}, /* agc ampli */ + {0x00, 0x9e, 0x40, 0xaa}, {0xb8, 0x8f, 0x50, 0xcc}, + {0x00, 0x01, 0x80, 0xaa}, + {0x00, 0x02, 0x80, 0xaa}, +/* sizer filters */ + {0xbc, 0x02, 0x08, 0xcc}, + {0xbc, 0x03, 0x70, 0xcc}, + {0xb8, 0x35, 0x00, 0xcc}, + {0xb8, 0x36, 0x00, 0xcc}, + {0xb8, 0x37, 0x00, 0xcc}, + {0xbc, 0x04, 0x08, 0xcc}, + {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, + {0xbc, 0x08, 0x3c, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, + {0xbc, 0x0a, 0x04, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, + {0xbc, 0x0c, 0x00, 0xcc}, +/* */ + {0xb8, 0xfe, 0x00, 0xcc}, + {0xb8, 0xff, 0x28, 0xcc}, +/* */ + {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc}, + {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc}, + {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc}, + {0xb9, 0x06, 0x3c, 0xcc}, {0xb9, 0x07, 0x3c, 0xcc}, + {0xb9, 0x08, 0x3c, 0xcc}, +/* */ + {0xb8, 0x8e, 0x00, 0xcc}, + {0xb8, 0x8f, 0xff, 0xcc}, /* ff */ + {0x00, 0x29, 0x3c, 0xaa}, + {0xb3, 0x01, 0x45, 0xcc}, /* 45 */ + {0x00, 0x00, 0x00, 0x00} +}; + +static __u8 ov7660_50HZ[][4] = { + {0x00, 0x3b, 0x08, 0xaa}, + {0x00, 0x9d, 0x40, 0xaa}, + {0x00, 0x13, 0xa7, 0xaa}, + {0x00, 0x00, 0x00, 0x00} +}; + +static __u8 ov7660_60HZ[][4] = { + {0x00, 0x3b, 0x00, 0xaa}, + {0x00, 0x9e, 0x40, 0xaa}, + {0x00, 0x13, 0xa7, 0xaa}, + {} +}; + +static __u8 ov7660_NoFliker[][4] = { + {0x00, 0x13, 0x87, 0xaa}, + {} +}; + +static __u8 ov7670_initVGA_JPG[][4] = { + {0xb3, 0x01, 0x05, 0xcc}, + {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, + {0x00, 0x00, 0x10, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, + {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, + {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0x41, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, + {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, + {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, + {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, + {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, + {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, + {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, + {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, + {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, + {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, + {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, + {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, + {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, + {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, + {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, + {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, + {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, + {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, + {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, + {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, + {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, + {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, + {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, + {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, + {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, + {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, + {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, + {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, + {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, + {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, + {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, + {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, + {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, + {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, + {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, + {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, + {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, + {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, + {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, + {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, + {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, + {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, + {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, + {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, + {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, + {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, + {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, + {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, + {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, + {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, + {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, + {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, + {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, + {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, + {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, + {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, + {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, + {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, + {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, + {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, + {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, + {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, + {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, + {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, + {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, + {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, + {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, + {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, + {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, + {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, + {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, + {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, + {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, + {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, + {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, + {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, + {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, + {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, + {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, + {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, + {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, + {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, + {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, + {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, + {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, + {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, + {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, + {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, + {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, + {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, + {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, + {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, + {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, + {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, + {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, + {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, + {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, + {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, + {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, + {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, + {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x02, 0xcc}, {0xb6, 0x02, 0x80, 0xcc}, + {0xb6, 0x05, 0x01, 0xcc}, {0xb6, 0x04, 0xe0, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x13, 0xcc}, + {0xb6, 0x18, 0x02, 0xcc}, {0xb6, 0x17, 0x58, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, + {0x00, 0x77, 0x05, 0xaa}, + {}, +}; + +static __u8 ov7670_initQVGA_JPG[][4] = { + {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, + {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, + {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, + {0xb3, 0x00, 0x66, 0xcc}, {0xb3, 0x00, 0x67, 0xcc}, + {0xb3, 0x35, 0xa1, 0xcc}, {0xb3, 0x34, 0x01, 0xcc}, + {0xb3, 0x05, 0x01, 0xcc}, {0xb3, 0x06, 0x01, 0xcc}, + {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc}, + {0xb3, 0x02, 0x02, 0xcc}, {0xb3, 0x03, 0x1f, 0xcc}, + {0xb3, 0x14, 0x00, 0xcc}, {0xb3, 0x15, 0x00, 0xcc}, + {0xb3, 0x16, 0x02, 0xcc}, {0xb3, 0x17, 0x7f, 0xcc}, + {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc}, + {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x01, 0xcc}, + {0xb3, 0x23, 0xe0, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc}, + {0xbc, 0x01, 0x01, 0xcc}, {0x00, 0x12, 0x80, 0xaa}, + {0x00, 0x00, 0x20, 0xdd}, {0x00, 0x12, 0x00, 0xaa}, + {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x6b, 0x0a, 0xaa}, + {0x00, 0x3a, 0x04, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, + {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x7a, 0x29, 0xaa}, + {0x00, 0x7b, 0x0e, 0xaa}, {0x00, 0x7c, 0x1a, 0xaa}, + {0x00, 0x7d, 0x31, 0xaa}, {0x00, 0x7e, 0x53, 0xaa}, + {0x00, 0x7f, 0x60, 0xaa}, {0x00, 0x80, 0x6b, 0xaa}, + {0x00, 0x81, 0x73, 0xaa}, {0x00, 0x82, 0x7b, 0xaa}, + {0x00, 0x83, 0x82, 0xaa}, {0x00, 0x84, 0x89, 0xaa}, + {0x00, 0x85, 0x96, 0xaa}, {0x00, 0x86, 0xa1, 0xaa}, + {0x00, 0x87, 0xb7, 0xaa}, {0x00, 0x88, 0xcc, 0xaa}, + {0x00, 0x89, 0xe1, 0xaa}, {0x00, 0x13, 0xe0, 0xaa}, + {0x00, 0x00, 0x00, 0xaa}, {0x00, 0x10, 0x00, 0xaa}, + {0x00, 0x0d, 0x40, 0xaa}, {0x00, 0x14, 0x28, 0xaa}, + {0x00, 0xa5, 0x05, 0xaa}, {0x00, 0xab, 0x07, 0xaa}, + {0x00, 0x24, 0x95, 0xaa}, {0x00, 0x25, 0x33, 0xaa}, + {0x00, 0x26, 0xe3, 0xaa}, {0x00, 0x9f, 0x88, 0xaa}, + {0x00, 0xa0, 0x78, 0xaa}, {0x00, 0x55, 0x90, 0xaa}, + {0x00, 0xa1, 0x03, 0xaa}, {0x00, 0xa6, 0xe0, 0xaa}, + {0x00, 0xa7, 0xd8, 0xaa}, {0x00, 0xa8, 0xf0, 0xaa}, + {0x00, 0xa9, 0x90, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, + {0x00, 0x13, 0xe5, 0xaa}, {0x00, 0x0e, 0x61, 0xaa}, + {0x00, 0x0f, 0x4b, 0xaa}, {0x00, 0x16, 0x02, 0xaa}, + {0x00, 0x1e, 0x07, 0xaa}, {0x00, 0x21, 0x02, 0xaa}, + {0x00, 0x22, 0x91, 0xaa}, {0x00, 0x29, 0x07, 0xaa}, + {0x00, 0x33, 0x0b, 0xaa}, {0x00, 0x35, 0x0b, 0xaa}, + {0x00, 0x37, 0x1d, 0xaa}, {0x00, 0x38, 0x71, 0xaa}, + {0x00, 0x39, 0x2a, 0xaa}, {0x00, 0x3c, 0x78, 0xaa}, + {0x00, 0x4d, 0x40, 0xaa}, {0x00, 0x4e, 0x20, 0xaa}, + {0x00, 0x74, 0x19, 0xaa}, {0x00, 0x8d, 0x4f, 0xaa}, + {0x00, 0x8e, 0x00, 0xaa}, {0x00, 0x8f, 0x00, 0xaa}, + {0x00, 0x90, 0x00, 0xaa}, {0x00, 0x91, 0x00, 0xaa}, + {0x00, 0x96, 0x00, 0xaa}, {0x00, 0x9a, 0x80, 0xaa}, + {0x00, 0xb0, 0x84, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, + {0x00, 0xb2, 0x0e, 0xaa}, {0x00, 0xb3, 0x82, 0xaa}, + {0x00, 0xb8, 0x0a, 0xaa}, {0x00, 0x43, 0x14, 0xaa}, + {0x00, 0x44, 0xf0, 0xaa}, {0x00, 0x45, 0x45, 0xaa}, + {0x00, 0x46, 0x63, 0xaa}, {0x00, 0x47, 0x2d, 0xaa}, + {0x00, 0x48, 0x46, 0xaa}, {0x00, 0x59, 0x88, 0xaa}, + {0x00, 0x5a, 0xa0, 0xaa}, {0x00, 0x5b, 0xc6, 0xaa}, + {0x00, 0x5c, 0x7d, 0xaa}, {0x00, 0x5d, 0x5f, 0xaa}, + {0x00, 0x5e, 0x19, 0xaa}, {0x00, 0x6c, 0x0a, 0xaa}, + {0x00, 0x6d, 0x55, 0xaa}, {0x00, 0x6e, 0x11, 0xaa}, + {0x00, 0x6f, 0x9e, 0xaa}, {0x00, 0x69, 0x00, 0xaa}, + {0x00, 0x6a, 0x40, 0xaa}, {0x00, 0x01, 0x40, 0xaa}, + {0x00, 0x02, 0x40, 0xaa}, {0x00, 0x13, 0xe7, 0xaa}, + {0x00, 0x5f, 0xf0, 0xaa}, {0x00, 0x60, 0xf0, 0xaa}, + {0x00, 0x61, 0xf0, 0xaa}, {0x00, 0x27, 0xa0, 0xaa}, + {0x00, 0x28, 0x80, 0xaa}, {0x00, 0x2c, 0x90, 0xaa}, + {0x00, 0x4f, 0x66, 0xaa}, {0x00, 0x50, 0x66, 0xaa}, + {0x00, 0x51, 0x00, 0xaa}, {0x00, 0x52, 0x22, 0xaa}, + {0x00, 0x53, 0x5e, 0xaa}, {0x00, 0x54, 0x80, 0xaa}, + {0x00, 0x58, 0x9e, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, + {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x85, 0xaa}, + {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, + {0x00, 0x77, 0x0a, 0xaa}, {0x00, 0x3d, 0x88, 0xaa}, + {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, + {0x00, 0x41, 0x38, 0xaa}, {0x00, 0x62, 0x30, 0xaa}, + {0x00, 0x63, 0x30, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, + {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x0b, 0xaa}, + {0x00, 0x65, 0x00, 0xaa}, {0x00, 0x66, 0x05, 0xaa}, + {0x00, 0x56, 0x50, 0xaa}, {0x00, 0x34, 0x11, 0xaa}, + {0x00, 0xa4, 0x88, 0xaa}, {0x00, 0x96, 0x00, 0xaa}, + {0x00, 0x97, 0x30, 0xaa}, {0x00, 0x98, 0x20, 0xaa}, + {0x00, 0x99, 0x30, 0xaa}, {0x00, 0x9a, 0x84, 0xaa}, + {0x00, 0x9b, 0x29, 0xaa}, {0x00, 0x9c, 0x03, 0xaa}, + {0x00, 0x78, 0x04, 0xaa}, {0x00, 0x79, 0x01, 0xaa}, + {0x00, 0xc8, 0xf0, 0xaa}, {0x00, 0x79, 0x0f, 0xaa}, + {0x00, 0xc8, 0x00, 0xaa}, {0x00, 0x79, 0x10, 0xaa}, + {0x00, 0xc8, 0x7e, 0xaa}, {0x00, 0x79, 0x0a, 0xaa}, + {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x0b, 0xaa}, + {0x00, 0xc8, 0x01, 0xaa}, {0x00, 0x79, 0x0c, 0xaa}, + {0x00, 0xc8, 0x0f, 0xaa}, {0x00, 0x79, 0x0d, 0xaa}, + {0x00, 0xc8, 0x20, 0xaa}, {0x00, 0x79, 0x09, 0xaa}, + {0x00, 0xc8, 0x80, 0xaa}, {0x00, 0x79, 0x02, 0xaa}, + {0x00, 0xc8, 0xc0, 0xaa}, {0x00, 0x79, 0x03, 0xaa}, + {0x00, 0xc8, 0x40, 0xaa}, {0x00, 0x79, 0x05, 0xaa}, + {0x00, 0xc8, 0x30, 0xaa}, {0x00, 0x79, 0x26, 0xaa}, + {0x00, 0x11, 0x40, 0xaa}, {0x00, 0x3a, 0x04, 0xaa}, + {0x00, 0x12, 0x00, 0xaa}, {0x00, 0x40, 0xc0, 0xaa}, + {0x00, 0x8c, 0x00, 0xaa}, {0x00, 0x17, 0x14, 0xaa}, + {0x00, 0x18, 0x02, 0xaa}, {0x00, 0x32, 0x92, 0xaa}, + {0x00, 0x19, 0x02, 0xaa}, {0x00, 0x1a, 0x7a, 0xaa}, + {0x00, 0x03, 0x0a, 0xaa}, {0x00, 0x0c, 0x00, 0xaa}, + {0x00, 0x3e, 0x00, 0xaa}, {0x00, 0x70, 0x3a, 0xaa}, + {0x00, 0x71, 0x35, 0xaa}, {0x00, 0x72, 0x11, 0xaa}, + {0x00, 0x73, 0xf0, 0xaa}, {0x00, 0xa2, 0x02, 0xaa}, + {0x00, 0xb1, 0x00, 0xaa}, {0x00, 0xb1, 0x0c, 0xaa}, + {0x00, 0x1e, 0x37, 0xaa}, {0x00, 0xaa, 0x14, 0xaa}, + {0x00, 0x24, 0x80, 0xaa}, {0x00, 0x25, 0x74, 0xaa}, + {0x00, 0x26, 0xd3, 0xaa}, {0x00, 0x0d, 0x00, 0xaa}, + {0x00, 0x14, 0x18, 0xaa}, {0x00, 0x9d, 0x99, 0xaa}, + {0x00, 0x9e, 0x7f, 0xaa}, {0x00, 0x64, 0x08, 0xaa}, + {0x00, 0x94, 0x07, 0xaa}, {0x00, 0x95, 0x06, 0xaa}, + {0x00, 0x66, 0x05, 0xaa}, {0x00, 0x41, 0x08, 0xaa}, + {0x00, 0x3f, 0x00, 0xaa}, {0x00, 0x75, 0x07, 0xaa}, + {0x00, 0x76, 0xe1, 0xaa}, {0x00, 0x4c, 0x00, 0xaa}, + {0x00, 0x77, 0x00, 0xaa}, {0x00, 0x3d, 0xc2, 0xaa}, + {0x00, 0x4b, 0x09, 0xaa}, {0x00, 0xc9, 0x60, 0xaa}, + {0x00, 0x41, 0x38, 0xaa}, {0xb6, 0x00, 0x00, 0xcc}, + {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc}, + {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc}, + {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x21, 0xcc}, + {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc}, + {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc}, + {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc}, + {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc}, + {0xbc, 0x02, 0x18, 0xcc}, {0xbc, 0x03, 0x50, 0xcc}, + {0xbc, 0x04, 0x18, 0xcc}, {0xbc, 0x05, 0x00, 0xcc}, + {0xbc, 0x06, 0x00, 0xcc}, {0xbc, 0x08, 0x30, 0xcc}, + {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x10, 0xcc}, + {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc}, + {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x45, 0xcc}, + {0x00, 0x77, 0x05, 0xaa }, + {}, +}; + +struct sensor_info { + int sensorId; + __u8 I2cAdd; + __u8 IdAdd; + __u16 VpId; + __u8 m1; + __u8 m2; + __u8 op; + }; + +static struct sensor_info sensor_info_data[] = { +/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ + {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, + {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, + {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01}, + {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01}, + {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05}, + {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, +}; + +static void reg_r(struct usb_device *dev, + __u16 req, + __u16 index, + __u8 *buffer, __u16 length) +{ + usb_control_msg(dev, + usb_rcvctrlpipe(dev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 1, /* value */ + index, buffer, length, + 500); +} + +static void reg_w(struct usb_device *dev, + __u16 req, + __u16 value, + __u16 index) +{ + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, NULL, 0, + 500); +} + +static void vc032x_read_sensor_register(struct usb_device *dev, + __u16 address, __u16 *value) +{ + __u8 ldata, mdata, hdata; + __u8 tmpvalue = 0; + int retry = 50; + ldata = 0; + mdata = 0; + hdata = 0; + *value = 0; + + reg_r(dev, 0xa1, 0xb33f, &tmpvalue, 1); + /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ + if (!(tmpvalue & 0x02)) { + PDEBUG(D_ERR, "I2c Bus Busy Wait %d", tmpvalue & 0x02); + return; + } + reg_w(dev, 0xa0, address, 0xb33a); + reg_w(dev, 0xa0, 0x02, 0xb339); + + tmpvalue = 0; + reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); + while (retry-- && tmpvalue) { + reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); +/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ + msleep(1); + } + reg_r(dev, 0xa1, 0xb33e, &hdata, 1); + reg_r(dev, 0xa1, 0xb33d, &mdata, 1); + reg_r(dev, 0xa1, 0xb33c, &ldata, 1); + PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", + hdata, mdata, ldata); + tmpvalue = 0; + reg_r(dev, 0xa1, 0xb334, &tmpvalue, 1); + if (tmpvalue == 0x02) + *value = (ldata << 8) + mdata; + else + *value = ldata; +} +static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + int i; + __u8 data; + __u16 value; + struct sensor_info *ptsensor_info; + + reg_r(dev, 0xa1, 0xbfcf, &data, 1); + PDEBUG(D_PROBE, "check sensor header %d", data); + for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { + ptsensor_info = &sensor_info_data[i]; + reg_w(dev, 0xa0, 0x02, 0xb334); + reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300); + reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300); + reg_w(dev, 0xa0, 0x01, 0xb308); + reg_w(dev, 0xa0, 0x0c, 0xb309); + reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335); +/* PDEBUG(D_PROBE, + "check sensor VC032X -> %d Add -> ox%02X!", + i, ptsensor_info->I2cAdd); */ + reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); + vc032x_read_sensor_register(dev, ptsensor_info->IdAdd, &value); + if (value == ptsensor_info->VpId) { +/* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", + ptsensor_info->VpId); */ + return ptsensor_info->sensorId; + } + } + return -1; +} + +static __u8 i2c_write(struct usb_device *dev, + __u8 reg, __u8 *val, __u8 size) +{ + __u8 retbyte; + + if (size > 3 || size < 1) + return -EINVAL; + reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); + reg_w(dev, 0xa0, size , 0xb334); + reg_w(dev, 0xa0, reg , 0xb33a); + switch (size) { + case 1: + reg_w(dev, 0xa0, val[0] , 0xb336); + break; + case 2: + reg_w(dev, 0xa0, val[0] , 0xb336); + reg_w(dev, 0xa0, val[1] , 0xb337); + break; + case 3: + reg_w(dev, 0xa0, val[0] , 0xb336); + reg_w(dev, 0xa0, val[1] , 0xb337); + reg_w(dev, 0xa0, val[2] , 0xb338); + break; + default: + reg_w(dev, 0xa0, 0x01, 0xb334); + return -EINVAL; + } + reg_w(dev, 0xa0, 0x01, 0xb339); + reg_r(dev, 0xa1, 0xb33b, &retbyte, 1); + return retbyte == 0; +} + +static void put_tab_to_reg(struct gspca_dev *gspca_dev, + __u8 *tab, __u8 tabsize, __u16 addr) +{ + int j; + __u16 ad = addr; + + for (j = 0; j < tabsize; j++) + reg_w(gspca_dev->dev, 0xa0, tab[j], ad++); +} + +static void usb_exchange(struct gspca_dev *gspca_dev, + __u8 data[][4]) +{ + struct usb_device *dev = gspca_dev->dev; + int i = 0; + + for (;;) { + switch (data[i][3]) { + default: + return; + case 0xcc: /* normal write */ + reg_w(dev, 0xa0, data[i][2], + ((data[i][0])<<8) | data[i][1]); + break; + case 0xaa: /* i2c op */ + i2c_write(dev, data[i][1], &data[i][2], 1); + break; + case 0xbb: /* i2c op */ + i2c_write(dev, data[i][0], &data[i][1], 2); + break; + case 0xdd: + msleep(data[i][2] + 10); + break; + } + i++; + } + /*not reached*/ +} + +/* + "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff + "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66 + */ + +static void vc0321_reset(struct gspca_dev *gspca_dev) +{ + reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d); + reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301); + msleep(100); + reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003); + msleep(100); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct sd *sd = (struct sd *) gspca_dev; + struct usb_device *dev = gspca_dev->dev; + struct cam *cam; + __u8 tmp2[4]; + int sensor; + __u16 vendor; + __u16 product; + + vendor = id->idVendor; + product = id->idProduct; + switch (vendor) { + case 0x046d: /* Logitech Labtec */ +/* switch (product) { */ +/* case 0x0892: */ +/* case 0x0896: */ + sd->bridge = BRIDGE_VC0321; +/* break; */ +/* } */ + break; + case 0x0ac8: /* Vimicro z-star */ + switch (product) { + case 0x0321: + case 0x0328: + case 0xc001: + case 0xc002: + sd->bridge = BRIDGE_VC0321; + break; + case 0x0323: + sd->bridge = BRIDGE_VC0323; + break; + } + break; + case 0x17ef: /* Lenovo */ +/* switch (product) { */ +/* case 0x4802: * Lenovo MI1310_SOC */ + sd->bridge = BRIDGE_VC0323; +/* break; */ +/* } */ + break; + } + + cam = &gspca_dev->cam; + cam->dev_name = (char *) id->driver_info; + cam->epaddr = 0x02; + if (sd->bridge == BRIDGE_VC0321) { + cam->cam_mode = vc0321_mode; + cam->nmodes = sizeof vc0321_mode / sizeof vc0321_mode[0]; + } else { + cam->cam_mode = vc0323_mode; + cam->nmodes = sizeof vc0323_mode / sizeof vc0323_mode[0]; + } + + vc0321_reset(gspca_dev); + sensor = vc032x_probe_sensor(gspca_dev); + switch (sensor) { + case -1: + PDEBUG(D_PROBE, "Unknown sensor..."); + return -EINVAL; + case SENSOR_HV7131R: + PDEBUG(D_PROBE, "Find Sensor HV7131R"); + sd->sensor = SENSOR_HV7131R; + break; + case SENSOR_MI1310_SOC: + PDEBUG(D_PROBE, "Find Sensor MI1310_SOC"); + sd->sensor = SENSOR_MI1310_SOC; + break; + case SENSOR_MI1320: + PDEBUG(D_PROBE, "Find Sensor MI1320"); + sd->sensor = SENSOR_MI1320; + break; + case SENSOR_OV7660: + PDEBUG(D_PROBE, "Find Sensor OV7660"); + sd->sensor = SENSOR_OV7660; + break; + case SENSOR_OV7670: + PDEBUG(D_PROBE, "Find Sensor OV7670"); + sd->sensor = SENSOR_OV7670; + break; + case SENSOR_PO3130NC: + PDEBUG(D_PROBE, "Find Sensor PO3130NC"); + sd->sensor = SENSOR_PO3130NC; + break; + } + + sd->qindex = 7; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + + if (sd->bridge == BRIDGE_VC0321) { + reg_r(dev, 0x8a, 0, tmp2, 3); + reg_w(dev, 0x87, 0x00, 0x0f0f); + + reg_r(dev, 0x8b, 0, tmp2, 3); + reg_w(dev, 0x88, 0x00, 0x0202); + } + return 0; +} + +/* this function is called at open time */ +static int sd_open(struct gspca_dev *gspca_dev) +{ + return 0; +} + +static void setquality(struct gspca_dev *gspca_dev) +{ +} + +static void setautogain(struct gspca_dev *gspca_dev) +{ +} + +static void setlightfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + static __u8 (*ov7660_freq_tb[3])[4] = + {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; + + if (sd->sensor != SENSOR_OV7660) + return; + usb_exchange(gspca_dev, ov7660_freq_tb[sd->lightfreq]); +} + +static void sd_start(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; +/* __u8 tmp2; */ + __u8 *GammaT = NULL; + __u8 *MatrixT = NULL; + int mode; + + /* Assume start use the good resolution from gspca_dev->mode */ + if (sd->bridge == BRIDGE_VC0321) { + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef); + } + + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + switch (sd->sensor) { + case SENSOR_HV7131R: + GammaT = hv7131r_gamma; + MatrixT = hv7131r_matrix; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, hv7131r_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, hv7131r_initVGA_data); + } + break; + case SENSOR_OV7660: + GammaT = ov7660_gamma; + MatrixT = ov7660_matrix; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, ov7660_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, ov7660_initVGA_data); + } + break; + case SENSOR_OV7670: + /*GammaT = ov7660_gamma; */ + /*MatrixT = ov7660_matrix; */ + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, ov7670_initQVGA_JPG); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, ov7670_initVGA_JPG); + } + break; + case SENSOR_MI1310_SOC: + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, mi1310_socinitVGA_JPG); + } + break; + case SENSOR_MI1320: + GammaT = mi1320_gamma; + MatrixT = mi1320_matrix; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, mi1320_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, mi1320_initVGA_data); + } + break; + case SENSOR_PO3130NC: + GammaT = po3130_gamma; + MatrixT = po3130_matrix; + if (mode) { + /* 320x240 */ + usb_exchange(gspca_dev, po3130_initQVGA_data); + } else { + /* 640x480 */ + usb_exchange(gspca_dev, po3130_initVGA_data); + } + usb_exchange(gspca_dev, po3130_rundata); + break; + default: + PDEBUG(D_PROBE, "Damned !! no sensor found Bye"); + return; + } + if (GammaT && MatrixT) { + put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a); + put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b); + put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c); + put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c); + + /* Seem SHARPNESS */ + /* + reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e); + */ + /* all 0x40 ??? do nothing + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822); + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823); + reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); + */ + /* Only works for HV7131R ?? + reg_r (gspca_dev->dev, 0xa1, 0xb881, &tmp2, 1); + reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); + reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); + */ + /* only hv7131r et ov7660 + reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827); + reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80 + reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS + */ + /* set the led on 0x0892 0x0896 */ + reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); + msleep(100); + setquality(gspca_dev); + setautogain(gspca_dev); + setlightfreq(gspca_dev); + } +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + reg_w(dev, 0x89, 0xffff, 0xffff); + reg_w(dev, 0xa0, 0x01, 0xb301); + reg_w(dev, 0xa0, 0x09, 0xb003); +} + +static void sd_stop0(struct gspca_dev *gspca_dev) +{ + struct usb_device *dev = gspca_dev->dev; + + reg_w(dev, 0x89, 0xffff, 0xffff); +} + +/* this function is called at close time */ +static void sd_close(struct gspca_dev *gspca_dev) +{ +/* struct usb_device *dev = gspca_dev->dev; + __u8 buffread; + + reg_w(dev, 0x89, 0xffff, 0xffff); + reg_w(dev, 0xa0, 0x01, 0xb301); + reg_w(dev, 0xa0, 0x09, 0xb303); + reg_w(dev, 0x89, 0xffff, 0xffff); +*/ +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, + struct gspca_frame *frame, /* target */ + unsigned char *data, /* isoc packet */ + int len) /* iso pkt length */ +{ + struct sd *sd = (struct sd *) gspca_dev; + + if (data[0] == 0xff && data[1] == 0xd8) { + PDEBUG(D_PACK, + "vc032x header packet found len %d", len); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); + if (sd->bridge == BRIDGE_VC0321) { +#define VCHDRSZ 46 + data += VCHDRSZ; + len -= VCHDRSZ; +#undef VCHDRSZ + } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + return; + } + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + if (gspca_dev->streaming) + setautogain(gspca_dev); + return 0; +} + +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->autogain; + return 0; +} + +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->lightfreq = val; + if (gspca_dev->streaming) + setlightfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->lightfreq; + return 0; +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ + strcpy(menu->name, "NoFliker"); + return 0; + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy(menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy(menu->name, "60 Hz"); + return 0; + } + break; + } + return -EINVAL; +} + +/* sub-driver description */ +static struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .open = sd_open, + .start = sd_start, + .stopN = sd_stopN, + .stop0 = sd_stop0, + .close = sd_close, + .pkt_scan = sd_pkt_scan, + .querymenu = sd_querymenu, +}; + +/* -- module initialisation -- */ +#define DVNM(name) .driver_info = (kernel_ulong_t) name +static __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, + {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, + {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, + {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")}, + {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")}, + {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")}, + {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")}, + {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")}, + {} +}; +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "v%s registered", version); + return 0; +} +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 03cc7fc58dbc..b767f32511bb 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -3,7 +3,7 @@ * Copyright (C) 2004 2005 2006 Michel Xhaard * mxhaard@magic.fr * - * V4L2 by Jean-François Moine + * V4L2 by Jean-Francois Moine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,15 +24,14 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 2, 13) -static const char version[] = "0.2.13"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) +static const char version[] = "2.1.0"; MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); MODULE_LICENSE("GPL"); -static int lightfreq = 50; static int force_sensor = -1; #include "jpeg.h" @@ -41,10 +40,12 @@ static int force_sensor = -1; struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char brightness; - unsigned char contrast; - unsigned char autogain; - unsigned char gamma; + __u8 brightness; + __u8 contrast; + __u8 gamma; + __u8 autogain; + __u8 lightfreq; + __u8 sharpness; char qindex; char sensor; /* Type of image sensor chip */ @@ -61,14 +62,13 @@ struct sd { #define SENSOR_OV7620 9 /*#define SENSOR_OV7648 9 - same values */ #define SENSOR_OV7630C 10 -/*#define SENSOR_free 11 */ -#define SENSOR_PAS106 12 -#define SENSOR_PB0330 13 -#define SENSOR_PO2030 14 -#define SENSOR_TAS5130CK 15 -#define SENSOR_TAS5130CXX 16 -#define SENSOR_TAS5130C_VF0250 17 -#define SENSOR_MAX 18 +#define SENSOR_PAS106 11 +#define SENSOR_PB0330 12 +#define SENSOR_PO2030 13 +#define SENSOR_TAS5130CK 14 +#define SENSOR_TAS5130CXX 15 +#define SENSOR_TAS5130C_VF0250 16 +#define SENSOR_MAX 17 unsigned short chip_revision; }; @@ -79,7 +79,12 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val); static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { #define SD_BRIGHTNESS 0 @@ -110,7 +115,21 @@ static struct ctrl sd_ctrls[] = { .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_AUTOGAIN 2 +#define SD_GAMMA 2 + { + { + .id = V4L2_CID_GAMMA, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gamma", + .minimum = 1, + .maximum = 6, + .step = 1, + .default_value = 4, + }, + .set = sd_setgamma, + .get = sd_getgamma, + }, +#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, @@ -124,19 +143,33 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, -#define SD_GAMMA 3 +#define SD_FREQ 4 { { - .id = V4L2_CID_GAMMA, + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light frequency filter", + .minimum = 0, + .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .step = 1, + .default_value = 1, + }, + .set = sd_setfreq, + .get = sd_getfreq, + }, +#define SD_SHARPNESS 5 + { + { + .id = V4L2_CID_SHARPNESS, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Gamma", - .minimum = 1, - .maximum = 6, + .name = "Sharpness", + .minimum = 0, + .maximum = 3, .step = 1, - .default_value = 4, + .default_value = 2, }, - .set = sd_setcontrast, - .get = sd_getgamma, + .set = sd_setsharpness, + .get = sd_getsharpness, }, }; @@ -211,11 +244,11 @@ static struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x08, 0x01c6}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x24, 0x0120}, /* gamma 5 */ {0xa0, 0x44, 0x0121}, {0xa0, 0x64, 0x0122}, @@ -284,7 +317,7 @@ static struct usb_action cs2102_Initial[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action cs2102_InitialScale[] = { @@ -341,11 +374,11 @@ static struct usb_action cs2102_InitialScale[] = { {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x08, 0x01c6}, /* clock ? */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x24, 0x0120}, /* gamma 5 */ {0xa0, 0x44, 0x0121}, {0xa0, 0x64, 0x0122}, @@ -414,7 +447,7 @@ static struct usb_action cs2102_InitialScale[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action cs2102_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -439,7 +472,7 @@ static struct usb_action cs2102_50HZ[] = { {0xa0, 0x8c, 0x001d}, /* 00,1d,8c,cc */ {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ - {0, 0, 0} + {} }; static struct usb_action cs2102_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -464,7 +497,7 @@ static struct usb_action cs2102_50HZScale[] = { {0xa0, 0x93, 0x001d}, /* 00,1d,93,cc */ {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ - {0, 0, 0} + {} }; static struct usb_action cs2102_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -489,7 +522,7 @@ static struct usb_action cs2102_60HZ[] = { {0xa0, 0x5d, 0x001d}, /* 00,1d,5d,cc */ {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ - {0, 0, 0} + {} }; static struct usb_action cs2102_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -514,7 +547,7 @@ static struct usb_action cs2102_60HZScale[] = { {0xa0, 0xb7, 0x001d}, /* 00,1d,b7,cc */ {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ - {0, 0, 0} + {} }; static struct usb_action cs2102_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -539,7 +572,7 @@ static struct usb_action cs2102_NoFliker[] = { {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0, 0, 0} + {} }; static struct usb_action cs2102_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -564,7 +597,7 @@ static struct usb_action cs2102_NoFlikerScale[] = { {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0, 0, 0} + {} }; /* CS2102_KOCOM */ @@ -676,8 +709,8 @@ static struct usb_action cs2102K_Initial[] = { {0xa0, 0x40, 0x0117}, {0xa0, 0x4c, 0x0118}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -824,7 +857,7 @@ static struct usb_action cs2102K_Initial[] = { {0xa0, 0x00, 0x01a7}, {0xa0, 0x04, 0x01a7}, {0xa0, 0x00, 0x01a7}, - {0, 0, 0} + {} }; static struct usb_action cs2102K_InitialScale[] = { @@ -936,8 +969,8 @@ static struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x40, 0x0117}, {0xa0, 0x4c, 0x0118}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -1137,8 +1170,8 @@ static struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x40, 0x0117}, {0xa0, 0x4c, 0x0118}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -1401,7 +1434,7 @@ static struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x04, 0x01a7}, {0xa0, 0x00, 0x01a7}, {0xa0, 0x04, 0x01a7}, - {0, 0, 0} + {} }; static struct usb_action gc0305_Initial[] = { /* 640x480 */ @@ -1466,7 +1499,7 @@ static struct usb_action gc0305_Initial[] = { /* 640x480 */ {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ - {0,0,0} + {} }; static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ @@ -1529,7 +1562,7 @@ static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ - {0,0,0} + {} }; static struct usb_action gc0305_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ @@ -1552,7 +1585,7 @@ static struct usb_action gc0305_50HZ[] = { {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ /* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ - {0,0,0} + {} }; static struct usb_action gc0305_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ @@ -1575,7 +1608,7 @@ static struct usb_action gc0305_60HZ[] = { {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ - {0,0,0} + {} }; static struct usb_action gc0305_NoFliker[] = { @@ -1598,7 +1631,7 @@ static struct usb_action gc0305_NoFliker[] = { {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ - {0,0,0} + {} }; /* play poker with registers at your own risk !! */ @@ -1647,11 +1680,11 @@ static struct usb_action hdcs2020xx_Initial[] = { {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x04, 0x01c6}, + {0xa0, 0x04, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x07, 0x01cb}, + {0xa0, 0x07, 0x01cb}, /* sharpness- */ {0xa0, 0x11, 0x0120}, /* gamma ~4 */ {0xa0, 0x37, 0x0121}, {0xa0, 0x58, 0x0122}, @@ -1744,7 +1777,7 @@ static struct usb_action hdcs2020xx_Initial[] = { {0xa1, 0x01, 0x0118}, /* {0xa0, 0x02, 0x0008}, */ {0xa0, 0x00, 0x0007}, - {0, 0, 0} + {} }; static struct usb_action hdcs2020xx_InitialScale[] = { @@ -1792,11 +1825,11 @@ static struct usb_action hdcs2020xx_InitialScale[] = { {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x04, 0x01c6}, + {0xa0, 0x04, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x07, 0x01cb}, + {0xa0, 0x07, 0x01cb}, /* sharpness- */ {0xa0, 0x11, 0x0120}, /* gamma ~4*/ {0xa0, 0x37, 0x0121}, {0xa0, 0x58, 0x0122}, @@ -1887,7 +1920,7 @@ static struct usb_action hdcs2020xx_InitialScale[] = { /* {0xa0, 0x02, 0x0008}, */ {0xa0, 0x00, 0x0007}, /* {0xa0, 0x18, 0x00fe}, */ - {0, 0, 0} + {} }; static struct usb_action hdcs2020xb_Initial[] = { {0xa0, 0x01, 0x0000}, @@ -1942,11 +1975,11 @@ static struct usb_action hdcs2020xb_Initial[] = { {0xa0, 0x40, 0x0118}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -2019,7 +2052,7 @@ static struct usb_action hdcs2020xb_Initial[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action hdcs2020xb_InitialScale[] = { {0xa0, 0x01, 0x0000}, @@ -2072,11 +2105,11 @@ static struct usb_action hdcs2020xb_InitialScale[] = { {0xa0, 0x40, 0x0118}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -2147,7 +2180,7 @@ static struct usb_action hdcs2020xb_InitialScale[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action hdcs2020b_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -2168,7 +2201,7 @@ static struct usb_action hdcs2020b_50HZ[] = { {0xa0, 0x05, 0x001d}, /* 00,1d,05,cc */ {0xa0, 0x1a, 0x001e}, /* 00,1e,1a,cc */ {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ - {0, 0, 0} + {} }; static struct usb_action hdcs2020b_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -2189,7 +2222,7 @@ static struct usb_action hdcs2020b_60HZ[] = { {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ {0xa0, 0x18, 0x001e}, /* 00,1e,18,cc */ {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ - {0, 0, 0} + {} }; static struct usb_action hdcs2020b_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -2210,7 +2243,7 @@ static struct usb_action hdcs2020b_NoFliker[] = { {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ {0xa0, 0x17, 0x001e}, /* 00,1e,17,cc */ {0xa0, 0x2a, 0x001f}, /* 00,1f,2a,cc */ - {0, 0, 0} + {} }; static struct usb_action hv7131bxx_Initial[] = { @@ -2266,11 +2299,11 @@ static struct usb_action hv7131bxx_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x50, 0x010a}, /* matrix */ {0xa0, 0xf8, 0x010b}, @@ -2318,7 +2351,7 @@ static struct usb_action hv7131bxx_Initial[] = { {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, /* {0xa0, 0x02, 0x0008}, */ - {0, 0, 0} + {} }; static struct usb_action hv7131bxx_InitialScale[] = { @@ -2373,11 +2406,11 @@ static struct usb_action hv7131bxx_InitialScale[] = { {0xa1, 0x01, 0x0096}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x50, 0x010a}, /* matrix */ {0xa0, 0xf8, 0x010b}, @@ -2424,7 +2457,7 @@ static struct usb_action hv7131bxx_InitialScale[] = { {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, /* {0xa0, 0x02, 0x0008}, */ - {0, 0, 0} + {} }; static struct usb_action hv7131cxx_Initial[] = { @@ -2478,11 +2511,11 @@ static struct usb_action hv7131cxx_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x60, 0x010a}, /* matrix */ {0xa0, 0xf0, 0x010b}, @@ -2518,7 +2551,7 @@ static struct usb_action hv7131cxx_Initial[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action hv7131cxx_InitialScale[] = { @@ -2577,11 +2610,11 @@ static struct usb_action hv7131cxx_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x60, 0x010a}, /* matrix */ {0xa0, 0xf0, 0x010b}, @@ -2619,7 +2652,7 @@ static struct usb_action hv7131cxx_InitialScale[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action icm105axx_Initial[] = { @@ -2743,11 +2776,11 @@ static struct usb_action icm105axx_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x52, 0x010a}, /* matrix */ {0xa0, 0xf7, 0x010b}, {0xa0, 0xf7, 0x010c}, @@ -2796,7 +2829,7 @@ static struct usb_action icm105axx_Initial[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action icm105axx_InitialScale[] = { @@ -2924,11 +2957,11 @@ static struct usb_action icm105axx_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x52, 0x010a}, /* matrix */ {0xa0, 0xf7, 0x010b}, @@ -2976,7 +3009,7 @@ static struct usb_action icm105axx_InitialScale[] = { {0xa0, 0x40, 0x0116}, {0xa0, 0x40, 0x0117}, {0xa0, 0x40, 0x0118}, - {0, 0, 0} + {} }; static struct usb_action icm105a_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3007,7 +3040,7 @@ static struct usb_action icm105a_50HZ[] = { {0xa0, 0xd8, 0x001e}, /* 00,1e,d8,cc */ {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0, 0, 0} + {} }; static struct usb_action icm105a_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3040,7 +3073,7 @@ static struct usb_action icm105a_50HZScale[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ - {0, 0, 0} + {} }; static struct usb_action icm105a_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3071,7 +3104,7 @@ static struct usb_action icm105a_60HZ[] = { {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0, 0, 0} + {} }; static struct usb_action icm105a_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3104,7 +3137,7 @@ static struct usb_action icm105a_60HZScale[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ - {0, 0, 0} + {} }; static struct usb_action icm105a_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3135,7 +3168,7 @@ static struct usb_action icm105a_NoFliker[] = { {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0, 0, 0} + {} }; static struct usb_action icm105a_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -3168,7 +3201,7 @@ static struct usb_action icm105a_NoFlikerScale[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_InitialScale[] = { @@ -3288,7 +3321,7 @@ static struct usb_action MC501CB_InitialScale[] = { {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_Initial[] = { /* 320x240 */ @@ -3407,7 +3440,7 @@ static struct usb_action MC501CB_Initial[] = { /* 320x240 */ {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ {0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */ {0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_50HZ[] = { @@ -3424,7 +3457,7 @@ static struct usb_action MC501CB_50HZ[] = { {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ {0xaa, 0x37, 0x0098}, /* 00,37,98,aa */ {0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_50HZScale[] = { @@ -3441,7 +3474,7 @@ static struct usb_action MC501CB_50HZScale[] = { {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_60HZ[] = { @@ -3458,7 +3491,7 @@ static struct usb_action MC501CB_60HZ[] = { {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_60HZScale[] = { @@ -3475,7 +3508,7 @@ static struct usb_action MC501CB_60HZScale[] = { {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ {0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */ {0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_NoFliker[] = { @@ -3492,7 +3525,7 @@ static struct usb_action MC501CB_NoFliker[] = { {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ {0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */ {0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */ - {0, 0, 0} + {} }; static struct usb_action MC501CB_NoFlikerScale[] = { @@ -3504,7 +3537,7 @@ static struct usb_action MC501CB_NoFlikerScale[] = { {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ {0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */ {0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */ - {0, 0, 0} + {} }; /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ @@ -3575,7 +3608,7 @@ static struct usb_action OV7620_mode0[] = { {0xa0, 0x40, 0x011d}, /* 01,1d,40,cc */ {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ - {0, 0, 0} + {} }; /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ @@ -3646,7 +3679,7 @@ static struct usb_action OV7620_mode1[] = { {0xa0, 0x50, 0x011d}, /* 01,1d,50,cc */ {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ - {0, 0, 0} + {} }; /* from zs211.inf - HKR,%OV7620%\AE,50HZ */ @@ -3665,7 +3698,7 @@ static struct usb_action OV7620_50HZ[] = { {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ /* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ - {0, 0, 0} + {} }; /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ @@ -3687,7 +3720,7 @@ static struct usb_action OV7620_60HZ[] = { /* ?? in gspca v1, it was {0xa0, 0x00, 0x0039}, * 00,00,00,dd * {0xa1, 0x01, 0x0037}, */ - {0, 0, 0} + {} }; /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ @@ -3707,7 +3740,7 @@ static struct usb_action OV7620_NoFliker[] = { /* ?? was {0xa0, 0x00, 0x0039}, * 00,00,00,dd * {0xa1, 0x01, 0x0037}, */ - {0, 0, 0} + {} }; static struct usb_action ov7630c_Initial[] = { @@ -3795,14 +3828,11 @@ static struct usb_action ov7630c_Initial[] = { /* 0x03, */ {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, -/* 0x05, */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, -/* 0x07, */ {0xa1, 0x01, 0x01c9}, -/* 0x0f, */ {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x01, 0x0120}, /* gamma 2 ?*/ {0xa0, 0x0c, 0x0121}, {0xa0, 0x1f, 0x0122}, @@ -3867,7 +3897,7 @@ static struct usb_action ov7630c_Initial[] = { {0xaa, 0x13, 0x0083}, /* 40 */ {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action ov7630c_InitialScale[] = { @@ -3954,14 +3984,11 @@ static struct usb_action ov7630c_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, - + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, - {0xa1, 0x01, 0x01c9}, - {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x16, 0x0120}, /* gamma ~4 */ {0xa0, 0x3a, 0x0121}, {0xa0, 0x5b, 0x0122}, @@ -4027,7 +4054,7 @@ static struct usb_action ov7630c_InitialScale[] = { {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action pas106b_Initial_com[] = { @@ -4041,7 +4068,7 @@ static struct usb_action pas106b_Initial_com[] = { {0xa0, 0x03, 0x003a}, {0xa0, 0x0c, 0x003b}, {0xa0, 0x04, 0x0038}, - {0, 0, 0} + {} }; static struct usb_action pas106b_Initial[] = { /* 176x144 */ @@ -4099,10 +4126,8 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ -/* Unknown */ - {0xa0, 0x08, 0x01c6}, -/* Sharpness */ - {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ /* Other registers */ {0xa0, 0x0d, 0x0100}, /* OperationMode */ /* Auto exposure and white balance */ @@ -4113,9 +4138,8 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ -/* Sharpness */ - {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ - {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x58, 0x010a}, /* matrix */ {0xa0, 0xf4, 0x010b}, @@ -4162,7 +4186,7 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xa0, 0x40, 0x0116}, /* RGain */ {0xa0, 0x40, 0x0117}, /* GGain */ {0xa0, 0x40, 0x0118}, /* BGain */ - {0, 0, 0} + {} }; static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ @@ -4221,10 +4245,8 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ -/* Unknown */ - {0xa0, 0x08, 0x01c6}, -/* Sharpness */ - {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ /* Other registers */ {0xa0, 0x0d, 0x0100}, /* OperationMode */ /* Auto exposure and white balance */ @@ -4235,9 +4257,8 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ -/* Sharpness */ - {0xa0, 0x08, 0x01c6}, /* Sharpness00 */ - {0xa0, 0x0f, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x58, 0x010a}, /* matrix */ {0xa0, 0xf4, 0x010b}, @@ -4289,7 +4310,7 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ {0xa0, 0xff, 0x0018}, /* Frame adjust */ - {0, 0, 0} + {} }; static struct usb_action pas106b_50HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ @@ -4305,7 +4326,7 @@ static struct usb_action pas106b_50HZ[] = { {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ - {0, 0, 0} + {} }; static struct usb_action pas106b_60HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ @@ -4321,7 +4342,7 @@ static struct usb_action pas106b_60HZ[] = { {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ - {0, 0, 0} + {} }; static struct usb_action pas106b_NoFliker[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ @@ -4337,10 +4358,9 @@ static struct usb_action pas106b_NoFliker[] = { {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0, 0, 0} + {} }; -/* Aurelien setting from snoop */ static struct usb_action pb03303x_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x03, 0x0008}, @@ -4411,11 +4431,11 @@ static struct usb_action pb03303x_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, {0xa0, 0x59, 0x0122}, @@ -4484,7 +4504,7 @@ static struct usb_action pb03303x_Initial[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action pb03303x_InitialScale[] = { @@ -4559,11 +4579,11 @@ static struct usb_action pb03303x_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x13, 0x0120}, /* gamma 4 */ {0xa0, 0x38, 0x0121}, @@ -4633,7 +4653,7 @@ static struct usb_action pb03303x_InitialScale[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action pb0330xx_Initial[] = { {0xa1, 0x01, 0x0008}, @@ -4701,11 +4721,11 @@ static struct usb_action pb0330xx_Initial[] = { {0xa0, 0x50, 0x0112}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x50, 0x010a}, /* matrix */ {0xa0, 0xf8, 0x010b}, @@ -4747,7 +4767,7 @@ static struct usb_action pb0330xx_Initial[] = { {0xa1, 0x01, 0x0007}, /* {0xa0, 0x30, 0x0007}, */ /* {0xa0, 0x00, 0x0007}, */ - {0, 0, 0} + {} }; static struct usb_action pb0330xx_InitialScale[] = { @@ -4816,11 +4836,11 @@ static struct usb_action pb0330xx_InitialScale[] = { {0xa0, 0x50, 0x0112}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x50, 0x010a}, /* matrix */ {0xa0, 0xf8, 0x010b}, @@ -4861,7 +4881,7 @@ static struct usb_action pb0330xx_InitialScale[] = { {0xa1, 0x01, 0x0007}, /* {0xa0, 0x30, 0x0007}, */ /* {0xa0, 0x00, 0x0007}, */ - {0, 0, 0} + {} }; static struct usb_action pb0330_50HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ @@ -4877,7 +4897,7 @@ static struct usb_action pb0330_50HZ[] = { {0xa0, 0x68, 0x001d}, /* 00,1d,68,cc */ {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0, 0, 0} + {} }; static struct usb_action pb0330_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -4894,7 +4914,7 @@ static struct usb_action pb0330_50HZScale[] = { {0xa0, 0xe5, 0x001d}, /* 00,1d,e5,cc */ {0xa0, 0xf0, 0x001e}, /* 00,1e,f0,cc */ {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ - {0, 0, 0} + {} }; static struct usb_action pb0330_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -4911,7 +4931,7 @@ static struct usb_action pb0330_60HZ[] = { {0xa0, 0x43, 0x001d}, /* 00,1d,43,cc */ {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ - {0, 0, 0} + {} }; static struct usb_action pb0330_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -4928,7 +4948,7 @@ static struct usb_action pb0330_60HZScale[] = { {0xa0, 0x41, 0x001d}, /* 00,1d,41,cc */ {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ - {0, 0, 0} + {} }; static struct usb_action pb0330_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -4945,7 +4965,7 @@ static struct usb_action pb0330_NoFliker[] = { {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ - {0, 0, 0} + {} }; static struct usb_action pb0330_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -4962,7 +4982,7 @@ static struct usb_action pb0330_NoFlikerScale[] = { {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ - {0, 0, 0} + {} }; /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ @@ -5039,7 +5059,7 @@ static struct usb_action PO2030_mode0[] = { {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ - {0, 0, 0} + {} }; /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ @@ -5116,7 +5136,7 @@ static struct usb_action PO2030_mode1[] = { {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ - {0, 0, 0} + {} }; static struct usb_action PO2030_50HZ[] = { @@ -5138,7 +5158,7 @@ static struct usb_action PO2030_50HZ[] = { {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ - {0, 0, 0} + {} }; static struct usb_action PO2030_60HZ[] = { @@ -5160,7 +5180,7 @@ static struct usb_action PO2030_60HZ[] = { {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ /* win: 01,8d,80 */ {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ - {0, 0, 0} + {} }; static struct usb_action PO2030_NoFliker[] = { @@ -5171,7 +5191,7 @@ static struct usb_action PO2030_NoFliker[] = { {0xaa, 0x1c, 0x0078}, /* 00,1c,78,aa */ {0xaa, 0x46, 0x0000}, /* 00,46,00,aa */ {0xaa, 0x15, 0x0000}, /* 00,15,00,aa */ - {0, 0, 0} + {} }; /* TEST */ @@ -5302,8 +5322,8 @@ static struct usb_action tas5130CK_Initial[] = { {0xa0, 0x03, 0x0111}, {0xa0, 0x51, 0x0112}, {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x01c6}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x38, 0x0120}, /* gamma > 5 */ {0xa0, 0x51, 0x0121}, {0xa0, 0x6e, 0x0122}, @@ -5375,7 +5395,7 @@ static struct usb_action tas5130CK_Initial[] = { {0xa0, 0x15, 0x01ae}, {0xa0, 0x40, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action tas5130CK_InitialScale[] = { @@ -5505,8 +5525,8 @@ static struct usb_action tas5130CK_InitialScale[] = { {0xa0, 0x03, 0x0111}, {0xa0, 0x51, 0x0112}, {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x01c6}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x38, 0x0120}, /* gamma > 5 */ {0xa0, 0x51, 0x0121}, {0xa0, 0x6e, 0x0122}, @@ -5583,7 +5603,7 @@ static struct usb_action tas5130CK_InitialScale[] = { {0xa0, 0x02, 0x0008}, {0xa0, 0x00, 0x0007}, {0xa0, 0x03, 0x0008}, - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_Initial[] = { @@ -5625,11 +5645,11 @@ static struct usb_action tas5130cxx_Initial[] = { {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x68, 0x010a}, /* matrix */ {0xa0, 0xec, 0x010b}, @@ -5673,7 +5693,7 @@ static struct usb_action tas5130cxx_Initial[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x01, 0x0000}, @@ -5718,11 +5738,11 @@ static struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x03, 0x0008}, {0xa1, 0x01, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, + {0xa0, 0x08, 0x01c6}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, + {0xa0, 0x0f, 0x01cb}, /* sharpness- */ {0xa0, 0x68, 0x010a}, /* matrix */ {0xa0, 0xec, 0x010b}, @@ -5763,7 +5783,7 @@ static struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x40, 0x0180}, {0xa1, 0x01, 0x0180}, {0xa0, 0x42, 0x0180}, - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -5786,7 +5806,7 @@ static struct usb_action tas5130cxx_50HZ[] = { {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -5809,7 +5829,7 @@ static struct usb_action tas5130cxx_50HZScale[] = { {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -5832,7 +5852,7 @@ static struct usb_action tas5130cxx_60HZ[] = { {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -5855,7 +5875,7 @@ static struct usb_action tas5130cxx_60HZScale[] = { {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ @@ -5878,7 +5898,7 @@ static struct usb_action tas5130cxx_NoFliker[] = { {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130cxx_NoFlikerScale[] = { @@ -5902,7 +5922,7 @@ static struct usb_action tas5130cxx_NoFlikerScale[] = { {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130c_vf0250_Initial[] = { @@ -5966,7 +5986,7 @@ static struct usb_action tas5130c_vf0250_Initial[] = { {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ - {0, 0, 0} + {} }; static struct usb_action tas5130c_vf0250_InitialScale[] = { @@ -6030,7 +6050,7 @@ static struct usb_action tas5130c_vf0250_InitialScale[] = { {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ - {0, 0, 0} + {} }; /* "50HZ" light frequency banding filter */ static struct usb_action tas5130c_vf0250_50HZ[] = { @@ -6054,7 +6074,7 @@ static struct usb_action tas5130c_vf0250_50HZ[] = { {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ - {0, 0, 0} + {} }; /* "50HZScale" light frequency banding filter */ @@ -6079,7 +6099,7 @@ static struct usb_action tas5130c_vf0250_50HZScale[] = { {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ - {0, 0, 0} + {} }; /* "60HZ" light frequency banding filter */ @@ -6104,7 +6124,7 @@ static struct usb_action tas5130c_vf0250_60HZ[] = { {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ - {0, 0, 0} + {} }; /* "60HZScale" light frequency banding ilter */ @@ -6129,7 +6149,7 @@ static struct usb_action tas5130c_vf0250_60HZScale[] = { {0xa0, 0x58, 0x011d}, /* 01,d,58,cc, */ {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ {0xa0, 0x78, 0x018d}, /* 01,d,78,cc */ - {0, 0, 0} + {} }; /* "NoFliker" light frequency banding flter */ @@ -6152,7 +6172,7 @@ static struct usb_action tas5130c_vf0250_NoFliker[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ - {0, 0, 0} + {} }; /* "NoFlikerScale" light frequency banding filter */ @@ -6175,7 +6195,7 @@ static struct usb_action tas5130c_vf0250_NoFlikerScale[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ - {0, 0, 0} + {} }; static void reg_r_i(struct usb_device *dev, @@ -6325,7 +6345,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) case SENSOR_PO2030: return; } -/*fixme: is it really 011d 018d for all other sensors? */ +/*fixme: is it really write to 011d and 018d for all other sensors? */ brightness = sd->brightness; reg_w(gspca_dev->dev, brightness, 0x011d); if (brightness < 0x70) @@ -6348,20 +6368,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) {0x10, 0x1e} }; - switch (sd->sensor) { - case SENSOR_GC0305: - sharpness = 3; - break; - case SENSOR_OV7620: - sharpness = 2; - break; - case SENSOR_PO2030: - sharpness = 0; - break; - default: - return; - } -/*fixme: sharpness set by V4L2_CID_SATURATION?*/ + sharpness = sd->sharpness; reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); reg_r(dev, 0x01c8, &retbyte); reg_r(dev, 0x01c9, &retbyte); @@ -6411,7 +6418,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) static __u8 Tgradient_5[16] = {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; - static __u8 Tgamma_6[16] = /* ?? was gama 5 */ + static __u8 Tgamma_6[16] = /* ?? was gamma 5 */ {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; static __u8 Tgradient_6[16] = @@ -6425,7 +6432,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) 0, Tgradient_1, Tgradient_2, Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 }; -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG __u8 v[16]; #endif @@ -6443,7 +6450,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) else if (g <= 0) g = 1; reg_w(dev, g, 0x0120 + i); /* gamma */ -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif @@ -6463,7 +6470,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) g = 1; } reg_w(dev, g, 0x0130 + i); /* gradient */ -#ifdef GSPCA_DEBUG +#ifdef VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif @@ -6488,7 +6495,7 @@ static void setquality(struct gspca_dev *gspca_dev) return; } /*fixme: is it really 0008 0007 0018 for all other sensors? */ - quality = sd->qindex & 0x0f; + quality = sd->qindex; reg_w(dev, quality, 0x0008); frxt = 0x30; reg_w(dev, frxt, 0x0007); @@ -6525,25 +6532,25 @@ static int setlightfreq(struct gspca_dev *gspca_dev) struct usb_action *zc3_freq; static struct usb_action *freq_tb[SENSOR_MAX][6] = { /* SENSOR_CS2102 0 */ - {cs2102_50HZ, cs2102_50HZScale, - cs2102_60HZ, cs2102_60HZScale, - cs2102_NoFliker, cs2102_NoFlikerScale}, + {cs2102_NoFliker, cs2102_NoFlikerScale, + cs2102_50HZ, cs2102_50HZScale, + cs2102_60HZ, cs2102_60HZScale}, /* SENSOR_CS2102K 1 */ - {cs2102_50HZ, cs2102_50HZScale, - cs2102_60HZ, cs2102_60HZScale, - cs2102_NoFliker, cs2102_NoFlikerScale}, + {cs2102_NoFliker, cs2102_NoFlikerScale, + cs2102_50HZ, cs2102_50HZScale, + cs2102_60HZ, cs2102_60HZScale}, /* SENSOR_GC0305 2 */ - {gc0305_50HZ, gc0305_50HZ, - gc0305_60HZ, gc0305_60HZ, - gc0305_NoFliker, gc0305_NoFliker}, + {gc0305_NoFliker, gc0305_NoFliker, + gc0305_50HZ, gc0305_50HZ, + gc0305_60HZ, gc0305_60HZ}, /* SENSOR_HDCS2020 3 */ {0, 0, 0, 0, 0, 0}, /* SENSOR_HDCS2020b 4 */ - {hdcs2020b_50HZ, hdcs2020b_50HZ, - hdcs2020b_60HZ, hdcs2020b_60HZ, - hdcs2020b_NoFliker, hdcs2020b_NoFliker}, + {hdcs2020b_NoFliker, hdcs2020b_NoFliker, + hdcs2020b_50HZ, hdcs2020b_50HZ, + hdcs2020b_60HZ, hdcs2020b_60HZ}, /* SENSOR_HV7131B 5 */ {0, 0, 0, 0, @@ -6553,66 +6560,48 @@ static int setlightfreq(struct gspca_dev *gspca_dev) 0, 0, 0, 0}, /* SENSOR_ICM105A 7 */ - {icm105a_50HZ, icm105a_50HZScale, - icm105a_60HZ, icm105a_60HZScale, - icm105a_NoFliker, icm105a_NoFlikerScale}, + {icm105a_NoFliker, icm105a_NoFlikerScale, + icm105a_50HZ, icm105a_50HZScale, + icm105a_60HZ, icm105a_60HZScale}, /* SENSOR_MC501CB 8 */ - {MC501CB_50HZ, MC501CB_50HZScale, - MC501CB_60HZ, MC501CB_60HZScale, - MC501CB_NoFliker, MC501CB_NoFlikerScale}, + {MC501CB_NoFliker, MC501CB_NoFlikerScale, + MC501CB_50HZ, MC501CB_50HZScale, + MC501CB_60HZ, MC501CB_60HZScale}, /* SENSOR_OV7620 9 */ - {OV7620_50HZ, OV7620_50HZ, - OV7620_60HZ, OV7620_60HZ, - OV7620_NoFliker, OV7620_NoFliker}, + {OV7620_NoFliker, OV7620_NoFliker, + OV7620_50HZ, OV7620_50HZ, + OV7620_60HZ, OV7620_60HZ}, /* SENSOR_OV7630C 10 */ {0, 0, 0, 0, 0, 0}, -/* SENSOR_free 11 */ - {0, 0, - 0, 0, - 0, 0}, -/* SENSOR_PAS106 12 */ - {pas106b_50HZ, pas106b_50HZ, - pas106b_60HZ, pas106b_60HZ, - pas106b_NoFliker, pas106b_NoFliker}, -/* SENSOR_PB0330 13 */ - {pb0330_50HZ, pb0330_50HZScale, - pb0330_60HZ, pb0330_60HZScale, - pb0330_NoFliker, pb0330_NoFlikerScale}, -/* SENSOR_PO2030 14 */ - {PO2030_50HZ, PO2030_50HZ, - PO2030_60HZ, PO2030_60HZ, - PO2030_NoFliker, PO2030_NoFliker}, -/* SENSOR_TAS5130CK 15 */ - {tas5130cxx_50HZ, tas5130cxx_50HZScale, - tas5130cxx_60HZ, tas5130cxx_60HZScale, - tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, -/* SENSOR_TAS5130CXX 16 */ - {tas5130cxx_50HZ, tas5130cxx_50HZScale, - tas5130cxx_60HZ, tas5130cxx_60HZScale, - tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale}, -/* SENSOR_TAS5130C_VF0250 17 */ - {tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, - tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale, - tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale}, +/* SENSOR_PAS106 11 */ + {pas106b_NoFliker, pas106b_NoFliker, + pas106b_50HZ, pas106b_50HZ, + pas106b_60HZ, pas106b_60HZ}, +/* SENSOR_PB0330 12 */ + {pb0330_NoFliker, pb0330_NoFlikerScale, + pb0330_50HZ, pb0330_50HZScale, + pb0330_60HZ, pb0330_60HZScale}, +/* SENSOR_PO2030 13 */ + {PO2030_NoFliker, PO2030_NoFliker, + PO2030_50HZ, PO2030_50HZ, + PO2030_60HZ, PO2030_60HZ}, +/* SENSOR_TAS5130CK 14 */ + {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, + tas5130cxx_50HZ, tas5130cxx_50HZScale, + tas5130cxx_60HZ, tas5130cxx_60HZScale}, +/* SENSOR_TAS5130CXX 15 */ + {tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale, + tas5130cxx_50HZ, tas5130cxx_50HZScale, + tas5130cxx_60HZ, tas5130cxx_60HZScale}, +/* SENSOR_TAS5130C_VF0250 16 */ + {tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale, + tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale, + tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale}, }; - switch (lightfreq) { - case 50: - i = 0; - break; - case 60: - i = 2; - break; - default: - PDEBUG(D_ERR, "Invalid light freq value %d", lightfreq); - lightfreq = 0; /* set to default filter value */ - /* fall thru */ - case 0: - i = 4; - break; - } + i = sd->lightfreq * 2; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; if (!mode) i++; /* 640x480 */ @@ -6622,13 +6611,13 @@ static int setlightfreq(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_GC0305: if (mode /* if 320x240 */ - && lightfreq == 50) + && sd->lightfreq == 1) /* and 50Hz */ reg_w(gspca_dev->dev, 0x85, 0x018d); /* win: 0x80, 0x018d */ break; case SENSOR_OV7620: if (!mode) { /* if 640x480 */ - if (lightfreq != 0) /* 50 or 60 Hz */ + if (sd->lightfreq != 0) /* and 50 or 60 Hz */ reg_w(gspca_dev->dev, 0x40, 0x0002); else reg_w(gspca_dev->dev, 0x44, 0x0002); @@ -6653,9 +6642,9 @@ static void setautogain(struct gspca_dev *gspca_dev) static void send_unknown(struct usb_device *dev, int sensor) { + reg_w(dev, 0x01, 0x0000); /* led off */ switch (sensor) { case SENSOR_PAS106: - reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x03, 0x003a); reg_w(dev, 0x0c, 0x003b); reg_w(dev, 0x08, 0x0038); @@ -6664,7 +6653,6 @@ static void send_unknown(struct usb_device *dev, int sensor) case SENSOR_OV7620: case SENSOR_PB0330: case SENSOR_PO2030: - reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x0d, 0x003a); reg_w(dev, 0x02, 0x003b); reg_w(dev, 0x00, 0x0038); @@ -6817,7 +6805,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ reg_w(dev, 0x02, 0x0010); - reg_r(dev, 0x0010, &retbyte); + reg_r(dev, 0x10, &retbyte); reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x00, 0x0010); reg_w(dev, 0x01, 0x0001); @@ -6964,7 +6952,7 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; __u8 bsensor; int vga = 1; /* 1: vga, 0: sif */ - static unsigned char gamma[SENSOR_MAX] = { + static __u8 gamma[SENSOR_MAX] = { 5, /* SENSOR_CS2102 0 */ 5, /* SENSOR_CS2102K 1 */ 4, /* SENSOR_GC0305 2 */ @@ -6976,16 +6964,16 @@ static int sd_config(struct gspca_dev *gspca_dev, 4, /* SENSOR_MC501CB 8 */ 3, /* SENSOR_OV7620 9 */ 4, /* SENSOR_OV7630C 10 */ - 4, /* SENSOR_free 11 */ - 4, /* SENSOR_PAS106 12 */ - 4, /* SENSOR_PB0330 13 */ - 4, /* SENSOR_PO2030 14 */ - 4, /* SENSOR_TAS5130CK 15 */ - 4, /* SENSOR_TAS5130CXX 16 */ - 3, /* SENSOR_TAS5130C_VF0250 17 */ + 4, /* SENSOR_PAS106 11 */ + 4, /* SENSOR_PB0330 12 */ + 4, /* SENSOR_PO2030 13 */ + 4, /* SENSOR_TAS5130CK 14 */ + 4, /* SENSOR_TAS5130CXX 15 */ + 3, /* SENSOR_TAS5130C_VF0250 16 */ }; /* define some sensors from the vendor/product */ + sd->sharpness = 2; switch (id->idVendor) { case 0x041e: /* Creative */ switch (id->idProduct) { @@ -7055,8 +7043,9 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = SENSOR_ICM105A; break; case 0x0e: - PDEBUG(D_PROBE, "Find Sensor PAS202BCB"); + PDEBUG(D_PROBE, "Find Sensor HDCS2020"); sd->sensor = SENSOR_HDCS2020; + sd->sharpness = 1; break; case 0x0f: PDEBUG(D_PROBE, "Find Sensor PAS106"); @@ -7097,6 +7086,7 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x2030: PDEBUG(D_PROBE, "Find Sensor PO2030"); sd->sensor = SENSOR_PO2030; + sd->sharpness = 0; /* from win traces */ break; case 0x7620: PDEBUG(D_PROBE, "Find Sensor OV7620"); @@ -7134,13 +7124,13 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->qindex = 1; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; sd->gamma = gamma[(int) sd->sensor]; + sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; + sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value; /* switch the led off */ -/*fixme: other sensors? */ - if (sensor == 0x06 || sensor == 0x11) - reg_w(gspca_dev->dev, 0x01, 0x0000); + reg_w(gspca_dev->dev, 0x01, 0x0000); return 0; } @@ -7170,15 +7160,14 @@ static void sd_start(struct gspca_dev *gspca_dev) {MC501CB_InitialScale, MC501CB_Initial}, /* 9 */ {OV7620_mode0, OV7620_mode1}, /* 9 */ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */ - {0, 0}, /* 11 */ - {pas106b_InitialScale, pas106b_Initial}, /* 12 */ - {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */ + {pas106b_InitialScale, pas106b_Initial}, /* 11 */ + {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */ /* or {pb03303x_InitialScale, pb03303x_Initial}, */ - {PO2030_mode0, PO2030_mode1}, /* 14 */ - {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */ - {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */ + {PO2030_mode0, PO2030_mode1}, /* 13 */ + {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */ + {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */ {tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial}, - /* 17 */ + /* 16 */ }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; @@ -7324,7 +7313,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, - unsigned char *data, + __u8 *data, int len) { @@ -7401,6 +7390,16 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gamma = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; @@ -7409,6 +7408,63 @@ static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->lightfreq = val; + if (gspca_dev->streaming) + setlightfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->lightfreq; + return 0; +} + +static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->sharpness = val; + if (gspca_dev->streaming) + setsharpness(gspca_dev); + return 0; +} + +static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->sharpness; + return 0; +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ + strcpy(menu->name, "NoFliker"); + return 0; + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy(menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy(menu->name, "60 Hz"); + return 0; + } + break; + } + return -EINVAL; +} + static struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, @@ -7420,6 +7476,7 @@ static struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .querymenu = sd_querymenu, }; #define DVNM(name) .driver_info = (kernel_ulong_t) name @@ -7514,10 +7571,6 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); -module_param(lightfreq, int, 0644); -MODULE_PARM_DESC(lightfreq, - "Light frequency banding filter: 50, 60 Hz or" - " 0 to NoFliker (default=50)"); module_param(force_sensor, int, 0644); MODULE_PARM_DESC(force_sensor, "Force sensor. Only for experts!!!"); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 9385c823a978..43a6c81a53ef 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -324,6 +324,8 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */ +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S','5','0','1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S','5','6','1') /* compressed BGGR bayer */ /* * F O R M A T E N U M E R A T I O N -- cgit v1.2.3 From 50a871fed9c82f01baa40100cd2d262784220953 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 30 Jun 2008 19:47:33 -0300 Subject: V4L/DVB (8158): gspca: minor changes main: V4L2_PIX_FMT_SPCA501 is compressed (thanks to Hans de Goede) main: return 0 when no change on vidioc_s_fmt_cap (thanks to Hans de Goede) pac207: cleanup Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 7 +++++-- drivers/media/video/gspca/pac207.c | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 5583c53e4863..07d765a7de6f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -316,6 +316,7 @@ static int gspca_is_compressed(__u32 format) switch (format) { case V4L2_PIX_FMT_MJPEG: case V4L2_PIX_FMT_JPEG: + case V4L2_PIX_FMT_SPCA561: return 1; } return 0; @@ -369,12 +370,12 @@ static __u32 get_v4l2_depth(__u32 pixfmt) case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ return 16; case V4L2_PIX_FMT_YUV420: /* 'YU12' planar 4.2.0 */ + case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ return 12; case V4L2_PIX_FMT_MJPEG: case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ - case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed BGGR bayer */ return 8; } @@ -913,8 +914,10 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, goto out; } - if (ret == gspca_dev->curr_mode) + if (ret == gspca_dev->curr_mode) { + ret = 0; goto out; /* same mode */ + } if (gspca_dev->streaming) { ret = -EBUSY; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 72a5b89cd59d..008954e755f1 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -492,7 +492,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) } static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, - unsigned char *m, int len) + unsigned char *m, int len) { struct sd *sd = (struct sd *) gspca_dev; int i; @@ -518,7 +518,9 @@ static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, } static int pac207_decompress_row(struct gspca_dev *gspca_dev, - struct gspca_frame *f, unsigned char *cdata, int len) + struct gspca_frame *f, + __u8 *cdata, + int len) { struct sd *sd = (struct sd *) gspca_dev; struct pac207_decoder_state *decoder_state = &sd->decoder_state; @@ -667,10 +669,10 @@ static int pac207_decode_frame_data(struct gspca_dev *gspca_dev, case LINE_HEADER2: decoder_state->line_marker |= data[0]; switch (decoder_state->line_marker) { - case 0x0FF0: + case 0x0ff0: decoder_state->line_state = LINE_UNCOMPRESSED; break; - case 0x1EE1: + case 0x1ee1: decoder_state->line_state = LINE_COMPRESSED; break; default: -- cgit v1.2.3 From e078770a050aa686f895a965f54222c0f201feb3 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 1 Jul 2008 04:06:22 -0300 Subject: V4L/DVB (8161): gspca: Fix compilation Some callbacks were renamed. Fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 07d765a7de6f..c84e0b352f46 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -739,7 +739,7 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev, return -EINVAL; } -static int vidioc_enum_fmt_cap(struct file *file, void *priv, +static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fmtdesc) { struct gspca_dev *gspca_dev = priv; @@ -782,7 +782,7 @@ static int vidioc_enum_fmt_cap(struct file *file, void *priv, return 0; } -static int vidioc_g_fmt_cap(struct file *file, void *priv, +static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; @@ -811,7 +811,7 @@ static int vidioc_g_fmt_cap(struct file *file, void *priv, return 0; } -static int try_fmt_cap(struct gspca_dev *gspca_dev, +static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, struct v4l2_format *fmt) { int w, h, mode, mode2, frsz; @@ -865,20 +865,20 @@ static int try_fmt_cap(struct gspca_dev *gspca_dev, return mode; /* used when s_fmt */ } -static int vidioc_try_fmt_cap(struct file *file, +static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; int ret; - ret = try_fmt_cap(gspca_dev, fmt); + ret = try_fmt_vid_cap(gspca_dev, fmt); if (ret < 0) return ret; return 0; } -static int vidioc_s_fmt_cap(struct file *file, void *priv, +static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; @@ -904,7 +904,7 @@ static int vidioc_s_fmt_cap(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - ret = try_fmt_cap(gspca_dev, fmt); + ret = try_fmt_vid_cap(gspca_dev, fmt); if (ret < 0) goto out; @@ -1369,7 +1369,7 @@ static int vidiocgmbuf(struct file *file, void *priv, fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width; fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24; - ret = vidioc_s_fmt_cap(file, priv, &fmt); + ret = vidioc_s_fmt_vid_cap(file, priv, &fmt); if (ret != 0) return ret; } @@ -1845,10 +1845,10 @@ static struct video_device gspca_template = { .vidioc_querycap = vidioc_querycap, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_qbuf = vidioc_qbuf, - .vidioc_enum_fmt_cap = vidioc_enum_fmt_cap, - .vidioc_try_fmt_cap = vidioc_try_fmt_cap, - .vidioc_g_fmt_cap = vidioc_g_fmt_cap, - .vidioc_s_fmt_cap = vidioc_s_fmt_cap, + .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, .vidioc_streamon = vidioc_streamon, .vidioc_queryctrl = vidioc_queryctrl, .vidioc_g_ctrl = vidioc_g_ctrl, -- cgit v1.2.3 From c1738904d6808a091d7d496b445d20671d513ad4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Jun 2008 15:33:02 -0300 Subject: V4L/DVB (8162): cx18: fix PAL/SECAM support Reverted the 'Fix unintended auto configurations in cx18-av-core' patch, instead disable the auto config completely. Fix a bug in cx18_av_vbi_setup() where the standard tests were done in the wrong order. Tested with NTSC-M, PAL-BG, PAL-I, PAL-DK, PAL-M, PAL-Nc, SECAM-DK, SECAM-L and SECAM-BG. The last one does not work at the moment due to a tda9887.c bug. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 74 ++++----------------------------- drivers/media/video/cx18/cx18-av-core.h | 10 ----- drivers/media/video/cx18/cx18-av-vbi.c | 25 +++++------ 3 files changed, 17 insertions(+), 92 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index faca43eb940f..cf98b2c445f4 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -69,58 +69,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, or_value); } -int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, int no_acfg_mask) -{ - int retval; - u32 saved_reg[8] = {0}; - - if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { - saved_reg[0] = cx18_av_read4(cx, CXADEC_CHIP_CTRL); - saved_reg[1] = cx18_av_read4(cx, CXADEC_AFE_CTRL); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { - saved_reg[2] = cx18_av_read4(cx, CXADEC_PLL_CTRL1); - saved_reg[3] = cx18_av_read4(cx, CXADEC_VID_PLL_FRAC); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_VID) { - saved_reg[4] = cx18_av_read4(cx, CXADEC_HORIZ_TIM_CTRL); - saved_reg[5] = cx18_av_read4(cx, CXADEC_VERT_TIM_CTRL); - saved_reg[6] = cx18_av_read4(cx, CXADEC_SRC_COMB_CFG); - saved_reg[7] = cx18_av_read4(cx, CXADEC_CHROMA_VBIOFF_CFG); - } - - retval = cx18_av_write(cx, addr, value); - - if (no_acfg_mask & CXADEC_NO_ACFG_AFE) { - cx18_av_write4(cx, CXADEC_CHIP_CTRL, saved_reg[0]); - cx18_av_write4(cx, CXADEC_AFE_CTRL, saved_reg[1]); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_PLL) { - cx18_av_write4(cx, CXADEC_PLL_CTRL1, saved_reg[2]); - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, saved_reg[3]); - } - - if (no_acfg_mask & CXADEC_NO_ACFG_VID) { - cx18_av_write4(cx, CXADEC_HORIZ_TIM_CTRL, saved_reg[4]); - cx18_av_write4(cx, CXADEC_VERT_TIM_CTRL, saved_reg[5]); - cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, saved_reg[6]); - cx18_av_write4(cx, CXADEC_CHROMA_VBIOFF_CFG, saved_reg[7]); - } - - return retval; -} - -int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned and_mask, - u8 or_value, int no_acfg_mask) -{ - return cx18_av_write_no_acfg(cx, addr, - (cx18_av_read(cx, addr) & and_mask) | - or_value, no_acfg_mask); -} - /* ----------------------------------------------------------------------- */ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, @@ -221,16 +169,9 @@ static void input_change(struct cx18 *cx) v4l2_std_id std = state->std; /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ - if (std & V4L2_STD_SECAM) - cx18_av_write_no_acfg(cx, 0x402, 0, CXADEC_NO_ACFG_ALL); - else { - cx18_av_write_no_acfg(cx, 0x402, 0x04, CXADEC_NO_ACFG_ALL); - cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); - } - cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); - cx18_av_and_or_no_acfg(cx, 0x401, ~0x60, 0x60, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); + cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); + cx18_av_and_or(cx, 0x401, ~0x60, 0); + cx18_av_and_or(cx, 0x401, ~0x60, 0x60); if (std & V4L2_STD_525_60) { if (std == V4L2_STD_NTSC_M_JP) { @@ -316,8 +257,7 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, cx18_av_write(cx, 0x103, reg); /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx18_av_and_or_no_acfg(cx, 0x401, ~0x6, is_composite ? 0 : 0x02, - CXADEC_NO_ACFG_PLL | CXADEC_NO_ACFG_VID); + cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ cx18_av_and_or(cx, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ @@ -373,12 +313,12 @@ static int set_v4lstd(struct cx18 *cx) This happens for example with the Yuan MPC622. */ if (fmt >= 4 && fmt < 8) { /* Set format to NTSC-M */ - cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, 1, CXADEC_NO_ACFG_AFE); + cx18_av_and_or(cx, 0x400, ~0xf, 1); /* Turn off LCOMB */ cx18_av_and_or(cx, 0x47b, ~6, 0); } - cx18_av_and_or_no_acfg(cx, 0x400, ~0xf, fmt, CXADEC_NO_ACFG_AFE); - cx18_av_and_or_no_acfg(cx, 0x403, ~0x3, pal_m, CXADEC_NO_ACFG_ALL); + cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20); + cx18_av_and_or(cx, 0x403, ~0x3, pal_m); cx18_av_vbi_setup(cx); input_change(cx); return 0; diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index c172823ce1d8..39f3c9397158 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -295,24 +295,14 @@ struct cx18_av_state { #define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ #define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ -/* Flags on what to preserve on write to 0x400-0x403 with cx18_av_.*_no_acfg()*/ -#define CXADEC_NO_ACFG_AFE 0x01 /* Preserve 0x100-0x107 */ -#define CXADEC_NO_ACFG_PLL 0x02 /* Preserve 0x108-0x10f */ -#define CXADEC_NO_ACFG_VID 0x04 /* Preserve 0x470-0x47f */ -#define CXADEC_NO_ACFG_ALL 0x07 - /* ----------------------------------------------------------------------- */ /* cx18_av-core.c */ int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); -int cx18_av_write_no_acfg(struct cx18 *cx, u16 addr, u8 value, - int no_acfg_mask); u8 cx18_av_read(struct cx18 *cx, u16 addr); u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); -int cx18_av_and_or_no_acfg(struct cx18 *cx, u16 addr, unsigned mask, u8 value, - int no_acfg_mask); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index d09f1daf4ebf..0c92f123686f 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c @@ -108,18 +108,18 @@ void cx18_av_vbi_setup(struct cx18 *cx) src_decimation = 0x21f; luma_lpf = 2; - if (std & V4L2_STD_SECAM) { - uv_lpf = 0; - comb = 0; - sc = 0x0a425f; - } else if (std == V4L2_STD_PAL_Nc) { + if (std & V4L2_STD_PAL) { uv_lpf = 1; comb = 0x20; - sc = 556453; - } else { + sc = 0x0a8263; + } else if (std == V4L2_STD_PAL_Nc) { uv_lpf = 1; comb = 0x20; - sc = 0x0a8263; + sc = 0x087da5; + } else { /* SECAM */ + uv_lpf = 0; + comb = 0; + sc = 0x0a425f; } } else { hactive = 720; @@ -127,25 +127,20 @@ void cx18_av_vbi_setup(struct cx18 *cx) vactive = 487; luma_lpf = 1; uv_lpf = 1; + vblank = 26; + vblank656 = 26; src_decimation = 0x21f; if (std == V4L2_STD_PAL_60) { - vblank = 26; - vblank656 = 26; burst = 0x5b; luma_lpf = 2; comb = 0x20; sc = 0x0a8263; } else if (std == V4L2_STD_PAL_M) { - vblank = 20; - vblank656 = 24; burst = 0x61; comb = 0x20; - sc = 555452; } else { - vblank = 26; - vblank656 = 26; burst = 0x5b; comb = 0x66; sc = 556063; -- cgit v1.2.3 From c3cb4d95ae778dbc6a4be1e74672d645fc75c8a7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 27 Jun 2008 23:27:25 -0300 Subject: V4L/DVB (8164): cx18/ivtv: choose a better initial TV standard for cards without eeprom. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 6 ++++++ drivers/media/video/ivtv/ivtv-driver.c | 6 ++++++ 2 files changed, 12 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 71bb04ab91d7..2f4909a32540 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -722,6 +722,12 @@ static int __devinit cx18_probe(struct pci_dev *dev, /* if no tuner was found, then pick the first tuner in the card list */ if (cx->options.tuner == -1 && cx->card->tuners[0].std) { cx->std = cx->card->tuners[0].std; + if (cx->std & V4L2_STD_PAL) + cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; + else if (cx->std & V4L2_STD_NTSC) + cx->std = V4L2_STD_NTSC_M; + else if (cx->std & V4L2_STD_SECAM) + cx->std = V4L2_STD_SECAM_L; cx->options.tuner = cx->card->tuners[0].tuner; } if (cx->options.radio == -1) diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 9e6a64903875..41fd79279bb5 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -1128,6 +1128,12 @@ static int __devinit ivtv_probe(struct pci_dev *dev, /* if no tuner was found, then pick the first tuner in the card list */ if (itv->options.tuner == -1 && itv->card->tuners[0].std) { itv->std = itv->card->tuners[0].std; + if (itv->std & V4L2_STD_PAL) + itv->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; + else if (itv->std & V4L2_STD_NTSC) + itv->std = V4L2_STD_NTSC_M; + else if (itv->std & V4L2_STD_SECAM) + itv->std = V4L2_STD_SECAM_L; itv->options.tuner = itv->card->tuners[0].tuner; } if (itv->options.radio == -1) -- cgit v1.2.3 From f313da113fe083bfb1eb43377f551db4bbe702a6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 28 Jun 2008 08:03:02 -0300 Subject: V4L/DVB (8165): cx18: fix v4l-cx23418-dig.fw firmware load. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-firmware.c | 70 ++++++++++++++++++----------- 1 file changed, 44 insertions(+), 26 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index a1a6af6c1c8f..ab86dc71bf8d 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c @@ -31,40 +31,58 @@ int cx18_av_loadfw(struct cx18 *cx) u32 v; const u8 *ptr; int i; + int retries = 0; if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { CX18_ERR("unable to open firmware %s\n", FWFILE); return -EINVAL; } - cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); - cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); /* Byte 0 */ - - /* Reset the Mako core (Register is undocumented.) */ - cx18_av_write4(cx, 0x8100, 0x00010000); - - /* Put the 8051 in reset and enable firmware upload */ - cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000); - - ptr = fw->data; - size = fw->size; - - for (i = 0; i < size; i++) { - u32 dl_control = 0x0F000000 | ((u32)ptr[i] << 16); - u32 value = 0; - int retries; - - for (retries = 0; retries < 5; retries++) { - cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); - value = cx18_av_read4(cx, CXADEC_DL_CTL); - if ((value & 0x3F00) == (dl_control & 0x3F00)) + /* The firmware load often has byte errors, so allow for several + retries, both at byte level and at the firmware load level. */ + while (retries < 5) { + cx18_av_write4(cx, CXADEC_CHIP_CTRL, 0x00010000); + cx18_av_write(cx, CXADEC_STD_DET_CTL, 0xf6); + + /* Reset the Mako core (Register is undocumented.) */ + cx18_av_write4(cx, 0x8100, 0x00010000); + + /* Put the 8051 in reset and enable firmware upload */ + cx18_av_write4(cx, CXADEC_DL_CTL, 0x0F000000); + + ptr = fw->data; + size = fw->size; + + for (i = 0; i < size; i++) { + u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); + u32 value = 0; + int retries; + + for (retries = 0; retries < 5; retries++) { + cx18_av_write4(cx, CXADEC_DL_CTL, dl_control); + udelay(10); + value = cx18_av_read4(cx, CXADEC_DL_CTL); + if (value == dl_control) + break; + /* Check if we can correct the byte by changing + the address. We can only write the lower + address byte of the address. */ + if ((value & 0x3F00) != (dl_control & 0x3F00)) { + retries = 5; + break; + } + } + if (retries >= 5) break; } - if (retries >= 5) { - CX18_ERR("unable to load firmware %s\n", FWFILE); - release_firmware(fw); - return -EIO; - } + if (i == size) + break; + retries++; + } + if (retries >= 5) { + CX18_ERR("unable to load firmware %s\n", FWFILE); + release_firmware(fw); + return -EIO; } cx18_av_write4(cx, CXADEC_DL_CTL, 0x13000000 | fw->size); -- cgit v1.2.3 From 81cb727d29eda7692a03be035b7228b4c3f6b610 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 28 Jun 2008 12:49:20 -0300 Subject: V4L/DVB (8167): cx18: set correct audio inputs for tuner and line-in 2. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-audio.c | 15 +++++++++++++- drivers/media/video/cx18/cx18-av-audio.c | 12 +++++------ drivers/media/video/cx18/cx18-av-core.c | 3 ++- drivers/media/video/cx18/cx18-av-core.h | 3 ++- drivers/media/video/cx18/cx18-av-firmware.c | 2 +- drivers/media/video/cx18/cx18-cards.c | 32 ++++++++++++++--------------- drivers/media/video/cx18/cx18-firmware.c | 3 --- drivers/media/video/cx18/cx18-mailbox.c | 1 + drivers/media/video/cx18/cx23418.h | 5 +++++ 9 files changed, 47 insertions(+), 29 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c index 1adc404d955e..6d5b94fc7087 100644 --- a/drivers/media/video/cx18/cx18-audio.c +++ b/drivers/media/video/cx18/cx18-audio.c @@ -26,13 +26,17 @@ #include "cx18-cards.h" #include "cx18-audio.h" +#define CX18_AUDIO_ENABLE 0xc72014 + /* Selects the audio input and output according to the current settings. */ int cx18_audio_set_io(struct cx18 *cx) { struct v4l2_routing route; u32 audio_input; + u32 val; int mux_input; + int err; /* Determine which input to use */ if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { @@ -51,8 +55,17 @@ int cx18_audio_set_io(struct cx18 *cx) cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route); route.input = audio_input; - return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, + err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_INT_S_AUDIO_ROUTING, &route); + if (err) + return err; + + val = read_reg(CX18_AUDIO_ENABLE) & ~0x30; + val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : + (audio_input << 4); + write_reg(val | 0xb00, CX18_AUDIO_ENABLE); + cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); + return 0; } void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route) diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index 2dc3a5dd170e..c40a286de1b9 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c @@ -34,7 +34,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ cx18_av_write(cx, 0x127, 0x50); - if (state->aud_input != CX18_AV_AUDIO_SERIAL) { + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { switch (freq) { case 32000: /* VID_PLL and AUX_PLL */ @@ -148,7 +148,7 @@ void cx18_av_audio_set_path(struct cx18 *cx) /* Mute everything to prevent the PFFT! */ cx18_av_write(cx, 0x8d3, 0x1f); - if (state->aud_input == CX18_AV_AUDIO_SERIAL) { + if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) { /* Set Path1 to Serial Audio Input */ cx18_av_write4(cx, 0x8d0, 0x01011012); @@ -165,7 +165,7 @@ void cx18_av_audio_set_path(struct cx18 *cx) /* deassert soft reset */ cx18_av_and_or(cx, 0x810, ~0x1, 0x00); - if (state->aud_input != CX18_AV_AUDIO_SERIAL) { + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { /* When the microcontroller detects the * audio format, it will unmute the lines */ cx18_av_and_or(cx, 0x803, ~0x10, 0x10); @@ -271,7 +271,7 @@ static void set_mute(struct cx18 *cx, int mute) { struct cx18_av_state *state = &cx->av_state; - if (state->aud_input != CX18_AV_AUDIO_SERIAL) { + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { /* Must turn off microcontroller in order to mute sound. * Not sure if this is the best method, but it does work. * If the microcontroller is running, then it will undo any @@ -298,14 +298,14 @@ int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) switch (cmd) { case VIDIOC_INT_AUDIO_CLOCK_FREQ: - if (state->aud_input != CX18_AV_AUDIO_SERIAL) { + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { cx18_av_and_or(cx, 0x803, ~0x10, 0); cx18_av_write(cx, 0x8d3, 0x1f); } cx18_av_and_or(cx, 0x810, ~0x1, 1); retval = set_audclk_freq(cx, *(u32 *)arg); cx18_av_and_or(cx, 0x810, ~0x1, 0); - if (state->aud_input != CX18_AV_AUDIO_SERIAL) + if (state->aud_input > CX18_AV_AUDIO_SERIAL2) cx18_av_and_or(cx, 0x803, ~0x10, 0x10); return retval; diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index cf98b2c445f4..3ccdf613bce0 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -241,7 +241,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, } switch (aud_input) { - case CX18_AV_AUDIO_SERIAL: + case CX18_AV_AUDIO_SERIAL1: + case CX18_AV_AUDIO_SERIAL2: /* do nothing, use serial audio input */ break; case CX18_AV_AUDIO4: reg &= ~0x30; break; diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 39f3c9397158..b54239959a68 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -62,7 +62,8 @@ enum cx18_av_video_input { enum cx18_av_audio_input { /* Audio inputs: serial or In4-In8 */ - CX18_AV_AUDIO_SERIAL, + CX18_AV_AUDIO_SERIAL1, + CX18_AV_AUDIO_SERIAL2, CX18_AV_AUDIO4 = 4, CX18_AV_AUDIO5, CX18_AV_AUDIO6, diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c index ab86dc71bf8d..834b9248242e 100644 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ b/drivers/media/video/cx18/cx18-av-firmware.c @@ -22,6 +22,7 @@ #include "cx18-driver.h" #include +#define CX18_AUDIO_ENABLE 0xc72014 #define FWFILE "v4l-cx23418-dig.fw" int cx18_av_loadfw(struct cx18 *cx) @@ -118,7 +119,6 @@ int cx18_av_loadfw(struct cx18 *cx) have a name in the spec. */ cx18_av_write4(cx, 0x09CC, 1); -#define CX18_AUDIO_ENABLE 0xc72014 v = read_reg(CX18_AUDIO_ENABLE); /* If bit 11 is 1 */ if (v & 0x800) diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 0b892aacabef..bb45bcf68ea6 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -67,12 +67,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, .ddr = { /* ESMT M13S128324A-5B memory */ .chip_config = 0x003, @@ -112,12 +112,12 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, CS5345_IN_2 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL, CS5345_IN_3 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, CS5345_IN_4 }, + CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, .ddr = { /* Samsung K4D263238G-VC33 memory */ .chip_config = 0x003, @@ -163,10 +163,10 @@ static const struct cx18_card cx18_card_h900 = { { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO8, 0 }, { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL1, 0 }, }, .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL, 0 }, + CX18_AV_AUDIO_SERIAL1, 0 }, .tuners = { { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, }, @@ -211,11 +211,11 @@ static const struct cx18_card cx18_card_mpc718 = { { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 0 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 0 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 }, + { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL1, 0 }, }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 }, .tuners = { /* XC3028 tuner */ { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, @@ -261,14 +261,14 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = { { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, }, .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL, 1 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL, 1 }, + { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, + { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, + { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 }, }, .tuners = { { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL, 2 }, + .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 }, .ddr = { /* MT 46V16M16 memory */ .chip_config = 0x50306, diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 2c280728dd7e..02453f09693f 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -41,9 +41,6 @@ #define CX18_REG_BUS_TIMEOUT_EN 0xc72024 -#define CX18_AUDIO_ENABLE 0xc72014 -#define CX18_REG_BUS_TIMEOUT_EN 0xc72024 - #define CX18_FAST_CLOCK_PLL_INT 0xc78000 #define CX18_FAST_CLOCK_PLL_FRAC 0xc78004 #define CX18_FAST_CLOCK_PLL_POST 0xc78008 diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index 2a5ccef9185b..93177514e846 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -81,6 +81,7 @@ static const struct cx18_api_info api_info[] = { API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), + API_ENTRY(CPU, CX18_APU_RESETAI, API_FAST), API_ENTRY(0, 0, 0), }; diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h index 33f78da9dba8..e7ed053059a8 100644 --- a/drivers/media/video/cx18/cx23418.h +++ b/drivers/media/video/cx18/cx23418.h @@ -52,6 +52,11 @@ #define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000) #define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000) +#define APU_CMD_MASK 0x10000000 +#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) + +#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) + /* Description: This command indicates that a Memory Descriptor List has been filled with the requested channel type IN[0] - Task handle. Handle of the task -- cgit v1.2.3 From 1a3932e0ed9ca46db2b76ce067e4ebaf04d91ea1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 28 Jun 2008 20:57:30 -0300 Subject: V4L/DVB (8168): cx18: Upgrade to newer firmware & update cx18 documentation. Conexant graciously gave us permission to redistribute the firmware. Update the documentation where the firmware can be downloaded. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/cx18.txt | 12 +++--------- drivers/media/video/cx18/cx18-firmware.c | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/cx18.txt b/Documentation/video4linux/cx18.txt index ecab5a06bd74..914cb7e734a2 100644 --- a/Documentation/video4linux/cx18.txt +++ b/Documentation/video4linux/cx18.txt @@ -23,14 +23,8 @@ encoder chip: Firmware: -The firmware needs to be extracted from the Windows Hauppauge HVR-1600 -driver, available here: +You can obtain the firmware files here: -http://hauppauge.lightpath.net/software/install_cd/hauppauge_cd_3.4d1.zip +http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz -Unzip, then copy the following files to the firmware directory -and rename them as follows: - -Drivers/Driver18/hcw18apu.rom -> v4l-cx23418-apu.fw -Drivers/Driver18/hcw18enc.rom -> v4l-cx23418-cpu.fw -Drivers/Driver18/hcw18mlC.rom -> v4l-cx23418-dig.fw +Untar and copy the .fw files to your firmware directory. diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 02453f09693f..2d630d9f7496 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -87,7 +87,7 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C /* Encoder/decoder firmware sizes */ -#define CX18_FW_CPU_SIZE (174716) +#define CX18_FW_CPU_SIZE (158332) #define CX18_FW_APU_SIZE (141200) #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ -- cgit v1.2.3 From e8b934de12989d1704e7df7ebb408a6021f08442 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 28 Jun 2008 20:57:56 -0300 Subject: V4L/DVB (8169): cx18: enable TS support Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 2f4909a32540..e73de6252257 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -436,7 +436,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) (cx->params.video_temporal_filter_mode << 1) | (cx->params.video_median_filter_type << 2); cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = 0; + cx->params.capabilities = CX2341X_CAP_HAS_TS; init_waitqueue_head(&cx->cap_w); init_waitqueue_head(&cx->mb_apu_waitq); init_waitqueue_head(&cx->mb_cpu_waitq); -- cgit v1.2.3 From dc5e42fb20229487ef11fd6fa0cdb7b7d42170f6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 30 Jun 2008 20:02:47 -0300 Subject: V4L/DVB (8171): ivtv: put back full device name, people relied on it in udev rules. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-streams.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index 8e3addd45090..f8883b487f4a 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -213,8 +213,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { s->v4l2dev->type |= VID_TYPE_MPEG_DECODER; } - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d", - itv->num); + snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", + itv->num, s->name); s->v4l2dev->minor = minor; s->v4l2dev->dev = &itv->dev->dev; -- cgit v1.2.3 From 7e87218bbfa2697c7df42ac80498a2fd17b276a4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 1 Jul 2008 18:46:09 -0300 Subject: V4L/DVB (8173): saa711x.c: remove obsolete file. saa711x.c is no longer used. Remove. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa711x.c | 584 ------------------------------------------ 1 file changed, 584 deletions(-) delete mode 100644 drivers/media/video/saa711x.c (limited to 'drivers/media') diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c deleted file mode 100644 index cedb988574bd..000000000000 --- a/drivers/media/video/saa711x.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * saa711x - Philips SAA711x video decoder driver version 0.0.1 - * - * To do: Now, it handles only saa7113/7114. Should be improved to - * handle all Philips saa711x devices. - * - * Based on saa7113 driver from Dave Perks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("Philips SAA711x video decoder driver"); -MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland, Dwaine Garden"); -MODULE_LICENSE("GPL"); - -#include - -#define I2C_NAME(s) (s)->name - -#include - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, " Set the default Debug level. Default: 0 (Off) - (0-1)"); - - -#define dprintk(num, format, args...) \ - do { \ - if (debug >= num) \ - printk(format, ##args); \ - } while (0) - -/* ----------------------------------------------------------------------- */ - -struct saa711x { - unsigned char reg[32]; - - int norm; - int input; - int enable; - int bright; - int contrast; - int hue; - int sat; -}; - -#define I2C_SAA7113 0x4A -#define I2C_SAA7114 0x42 - -/* ----------------------------------------------------------------------- */ - -static inline int -saa711x_write (struct i2c_client *client, - u8 reg, - u8 value) -{ - struct saa711x *decoder = i2c_get_clientdata(client); - - decoder->reg[reg] = value; - return i2c_smbus_write_byte_data(client, reg, value); -} - -static int -saa711x_write_block (struct i2c_client *client, - const u8 *data, - unsigned int len) -{ - int ret = -1; - u8 reg; - - /* the saa711x has an autoincrement function, use it if - * the adapter understands raw I2C */ - if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - /* do raw I2C, not smbus compatible */ - struct saa711x *decoder = i2c_get_clientdata(client); - struct i2c_msg msg; - u8 block_data[32]; - - msg.addr = client->addr; - msg.flags = 0; - while (len >= 2) { - msg.buf = (char *) block_data; - msg.len = 0; - block_data[msg.len++] = reg = data[0]; - do { - block_data[msg.len++] = - decoder->reg[reg++] = data[1]; - len -= 2; - data += 2; - } while (len >= 2 && data[0] == reg && - msg.len < 32); - if ((ret = i2c_transfer(client->adapter, - &msg, 1)) < 0) - break; - } - } else { - /* do some slow I2C emulation kind of thing */ - while (len >= 2) { - reg = *data++; - if ((ret = saa711x_write(client, reg, - *data++)) < 0) - break; - len -= 2; - } - } - - return ret; -} - -static int -saa711x_init_decoder (struct i2c_client *client, - struct video_decoder_init *init) -{ - return saa711x_write_block(client, init->data, init->len); -} - -static inline int -saa711x_read (struct i2c_client *client, - u8 reg) -{ - return i2c_smbus_read_byte_data(client, reg); -} - -/* ----------------------------------------------------------------------- */ - -static const unsigned char saa711x_i2c_init[] = { - 0x00, 0x00, /* PH711x_CHIP_VERSION 00 - ID byte */ - 0x01, 0x08, /* PH711x_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ - 0x02, 0xc0, /* PH711x_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ - 0x03, 0x23, /* PH711x_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ - 0x04, 0x00, /* PH711x_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ - 0x05, 0x00, /* PH711x_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ - 0x06, 0xeb, /* PH711x_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ - 0x07, 0xe0, /* PH711x_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ - 0x08, 0x88, /* PH711x_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ - 0x09, 0x00, /* PH711x_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ - 0x0a, 0x80, /* PH711x_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ - 0x0b, 0x47, /* PH711x_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ - 0x0c, 0x40, /* PH711x_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ - 0x0d, 0x00, /* PH711x_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ - 0x0e, 0x01, /* PH711x_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ - 0x0f, 0xaa, /* PH711x_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ - 0x10, 0x00, /* PH711x_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ - 0x11, 0x1C, /* PH711x_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ - 0x12, 0x01, /* PH711x_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ - 0x13, 0x00, /* PH711x_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ - 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ - 0x15, 0x00, /* PH711x_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ - 0x16, 0x00, /* PH711x_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ - 0x17, 0x00, /* PH711x_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */ -}; - -static int -saa711x_command (struct i2c_client *client, - unsigned int cmd, - void *arg) -{ - struct saa711x *decoder = i2c_get_clientdata(client); - - switch (cmd) { - - case 0: - case DECODER_INIT: - { - struct video_decoder_init *init = arg; - if (NULL != init) - return saa711x_init_decoder(client, init); - else { - struct video_decoder_init vdi; - vdi.data = saa711x_i2c_init; - vdi.len = sizeof(saa711x_i2c_init); - return saa711x_init_decoder(client, &vdi); - } - } - - case DECODER_DUMP: - { - int i; - - for (i = 0; i < 32; i += 16) { - int j; - - printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i); - for (j = 0; j < 16; ++j) { - printk(" %02x", - saa711x_read(client, i + j)); - } - printk("\n"); - } - } - break; - - case DECODER_GET_CAPABILITIES: - { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_PAL | - VIDEO_DECODER_NTSC | - VIDEO_DECODER_SECAM | - VIDEO_DECODER_AUTO | - VIDEO_DECODER_CCIR; - cap->inputs = 8; - cap->outputs = 1; - } - break; - - case DECODER_GET_STATUS: - { - int *iarg = arg; - int status; - int res; - - status = saa711x_read(client, 0x1f); - dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client), - status); - res = 0; - if ((status & (1 << 6)) == 0) { - res |= DECODER_STATUS_GOOD; - } - switch (decoder->norm) { - case VIDEO_MODE_NTSC: - res |= DECODER_STATUS_NTSC; - break; - case VIDEO_MODE_PAL: - res |= DECODER_STATUS_PAL; - break; - case VIDEO_MODE_SECAM: - res |= DECODER_STATUS_SECAM; - break; - default: - case VIDEO_MODE_AUTO: - if ((status & (1 << 5)) != 0) { - res |= DECODER_STATUS_NTSC; - } else { - res |= DECODER_STATUS_PAL; - } - break; - } - if ((status & (1 << 0)) != 0) { - res |= DECODER_STATUS_COLOR; - } - *iarg = res; - } - break; - - case DECODER_SET_GPIO: - { - int *iarg = arg; - if (0 != *iarg) { - saa711x_write(client, 0x11, - (decoder->reg[0x11] | 0x80)); - } else { - saa711x_write(client, 0x11, - (decoder->reg[0x11] & 0x7f)); - } - break; - } - - case DECODER_SET_VBI_BYPASS: - { - int *iarg = arg; - if (0 != *iarg) { - saa711x_write(client, 0x13, - (decoder->reg[0x13] & 0xf0) | 0x0a); - } else { - saa711x_write(client, 0x13, - (decoder->reg[0x13] & 0xf0)); - } - break; - } - - case DECODER_SET_NORM: - { - int *iarg = arg; - - switch (*iarg) { - - case VIDEO_MODE_NTSC: - saa711x_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x40); - saa711x_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_PAL: - saa711x_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa711x_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - case VIDEO_MODE_SECAM: - saa711x_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x00); - saa711x_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f) | 0x50); - break; - - case VIDEO_MODE_AUTO: - saa711x_write(client, 0x08, - (decoder->reg[0x08] & 0x3f) | 0x80); - saa711x_write(client, 0x0e, - (decoder->reg[0x0e] & 0x8f)); - break; - - default: - return -EINVAL; - - } - decoder->norm = *iarg; - } - break; - - case DECODER_SET_INPUT: - { - int *iarg = arg; - if (*iarg < 0 || *iarg > 9) { - return -EINVAL; - } - if (decoder->input != *iarg) { - decoder->input = *iarg; - /* select mode */ - saa711x_write(client, 0x02, - (decoder->reg[0x02] & 0xf0) | decoder->input); - /* bypass chrominance trap for modes 4..7 */ - saa711x_write(client, 0x09, - (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0)); - } - } - break; - - case DECODER_SET_OUTPUT: - { - int *iarg = arg; - - /* not much choice of outputs */ - if (*iarg != 0) { - return -EINVAL; - } - } - break; - - case DECODER_ENABLE_OUTPUT: - { - int *iarg = arg; - int enable = (*iarg != 0); - - if (decoder->enable != enable) { - decoder->enable = enable; - - /* RJ: If output should be disabled (for - * playing videos), we also need a open PLL. - * The input is set to 0 (where no input - * source is connected), although this - * is not necessary. - * - * If output should be enabled, we have to - * reverse the above. - */ - - if (decoder->enable) { - saa711x_write(client, 0x02, - (decoder-> - reg[0x02] & 0xf8) | - decoder->input); - saa711x_write(client, 0x08, - (decoder->reg[0x08] & 0xfb)); - saa711x_write(client, 0x11, - (decoder-> - reg[0x11] & 0xf3) | 0x0c); - } else { - saa711x_write(client, 0x02, - (decoder->reg[0x02] & 0xf8)); - saa711x_write(client, 0x08, - (decoder-> - reg[0x08] & 0xfb) | 0x04); - saa711x_write(client, 0x11, - (decoder->reg[0x11] & 0xf3)); - } - } - } - break; - - case DECODER_SET_PICTURE: - { - struct video_picture *pic = arg; - - if (decoder->bright != pic->brightness) { - /* We want 0 to 255 we get 0-65535 */ - decoder->bright = pic->brightness; - saa711x_write(client, 0x0a, decoder->bright >> 8); - } - if (decoder->contrast != pic->contrast) { - /* We want 0 to 127 we get 0-65535 */ - decoder->contrast = pic->contrast; - saa711x_write(client, 0x0b, - decoder->contrast >> 9); - } - if (decoder->sat != pic->colour) { - /* We want 0 to 127 we get 0-65535 */ - decoder->sat = pic->colour; - saa711x_write(client, 0x0c, decoder->sat >> 9); - } - if (decoder->hue != pic->hue) { - /* We want -128 to 127 we get 0-65535 */ - decoder->hue = pic->hue; - saa711x_write(client, 0x0d, - (decoder->hue - 32768) >> 8); - } - } - break; - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* - * Generic i2c probe - * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1' - */ - -/* standard i2c insmod options */ -static unsigned short normal_i2c[] = { - I2C_SAA7113>>1, /* saa7113 */ - I2C_SAA7114>>1, /* saa7114 */ - I2C_CLIENT_END -}; - -I2C_CLIENT_INSMOD; - - -static struct i2c_driver i2c_driver_saa711x; - -static int -saa711x_detect_client (struct i2c_adapter *adapter, - int address, - int kind) -{ - int i; - struct i2c_client *client; - struct saa711x *decoder; - struct video_decoder_init vdi; - - dprintk(1, - KERN_INFO - "saa711x.c: detecting saa711x client on address 0x%x\n", - address << 1); - - /* Check if the adapter supports the needed features */ - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return 0; - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == 0) - return -ENOMEM; - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver_saa711x; - strlcpy(I2C_NAME(client), "saa711x", sizeof(I2C_NAME(client))); - decoder = kzalloc(sizeof(struct saa711x), GFP_KERNEL); - if (decoder == NULL) { - kfree(client); - return -ENOMEM; - } - decoder->norm = VIDEO_MODE_NTSC; - decoder->input = 0; - decoder->enable = 1; - decoder->bright = 32768; - decoder->contrast = 32768; - decoder->hue = 32768; - decoder->sat = 32768; - i2c_set_clientdata(client, decoder); - - i = i2c_attach_client(client); - if (i) { - kfree(client); - kfree(decoder); - return i; - } - - vdi.data = saa711x_i2c_init; - vdi.len = sizeof(saa711x_i2c_init); - i = saa711x_init_decoder(client, &vdi); - if (i < 0) { - dprintk(1, KERN_ERR "%s_attach error: init status %d\n", - I2C_NAME(client), i); - } else { - dprintk(1, - KERN_INFO - "%s_attach: chip version %x at address 0x%x\n", - I2C_NAME(client), saa711x_read(client, 0x00) >> 4, - client->addr << 1); - } - - return 0; -} - -static int -saa711x_attach_adapter (struct i2c_adapter *adapter) -{ - dprintk(1, - KERN_INFO - "saa711x.c: starting probe for adapter %s (0x%x)\n", - I2C_NAME(adapter), adapter->id); - return i2c_probe(adapter, &addr_data, &saa711x_detect_client); -} - -static int -saa711x_detach_client (struct i2c_client *client) -{ - struct saa711x *decoder = i2c_get_clientdata(client); - int err; - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(decoder); - kfree(client); - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver i2c_driver_saa711x = { - .driver = { - .name = "saa711x", - }, - .id = I2C_DRIVERID_SAA711X, - .attach_adapter = saa711x_attach_adapter, - .detach_client = saa711x_detach_client, - .command = saa711x_command, -}; - -static int __init -saa711x_init (void) -{ - return i2c_add_driver(&i2c_driver_saa711x); -} - -static void __exit -saa711x_exit (void) -{ - i2c_del_driver(&i2c_driver_saa711x); -} - -module_init(saa711x_init); -module_exit(saa711x_exit); -- cgit v1.2.3 From ab062fe3b540c157eb66c4acedbedbc200cfd9e2 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 30 Jun 2008 03:32:35 -0300 Subject: V4L/DVB (8175): pvrusb2: Fix misleading source code comment Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 6517ba81bd4b..de0f41b956bd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2453,9 +2453,8 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) struct pvr2_ctrl *cptr; int disruptive_change; - /* When video standard changes, reset the hres and vres values - - but if the user has pending changes there, then let the changes - take priority. */ + /* Handle some required side effects when the video standard is + changed.... */ if (hdw->std_dirty) { /* Rewrite the vertical resolution to be appropriate to the video standard that has been selected. */ -- cgit v1.2.3 From 00528d9c2e9e15625883c161867cba61725ba335 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Mon, 30 Jun 2008 03:35:52 -0300 Subject: V4L/DVB (8176): pvrusb2: Update video_gop_size When switching video standard, ensure that video GOP size remains appropriately configured. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-hdw.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index de0f41b956bd..a5217a2cf4c0 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -2456,18 +2456,35 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw) /* Handle some required side effects when the video standard is changed.... */ if (hdw->std_dirty) { - /* Rewrite the vertical resolution to be appropriate to the - video standard that has been selected. */ int nvres; + int gop_size; if (hdw->std_mask_cur & V4L2_STD_525_60) { nvres = 480; + gop_size = 15; } else { nvres = 576; + gop_size = 12; } + /* Rewrite the vertical resolution to be appropriate to the + video standard that has been selected. */ if (nvres != hdw->res_ver_val) { hdw->res_ver_val = nvres; hdw->res_ver_dirty = !0; } + /* Rewrite the GOP size to be appropriate to the video + standard that has been selected. */ + if (gop_size != hdw->enc_ctl_state.video_gop_size) { + struct v4l2_ext_controls cs; + struct v4l2_ext_control c1; + memset(&cs, 0, sizeof(cs)); + memset(&c1, 0, sizeof(c1)); + cs.controls = &c1; + cs.count = 1; + c1.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE; + c1.value = gop_size; + cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs, + VIDIOC_S_EXT_CTRLS); + } } if (hdw->input_dirty && hdw->state_pathway_ok && -- cgit v1.2.3 From 956e42d28f300f5bb928fb5850b3e3c0a8982d23 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 1 Jul 2008 10:03:42 -0300 Subject: V4L/DVB (8180): Source cleanup - compile error with VIDEO_ADV_DEBUG. main, etoms, mars, pac207, pac7311, sonixb, sonixj, spca500, spca505: Cleanup source. sunplus: Compilation error when VIDEO_ADV_DEBUG set. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/etoms.c | 4 ++-- drivers/media/video/gspca/gspca.c | 8 ++++---- drivers/media/video/gspca/mars.c | 6 ++++-- drivers/media/video/gspca/pac207.c | 24 ++++++++++++------------ drivers/media/video/gspca/pac7311.c | 3 ++- drivers/media/video/gspca/sonixb.c | 2 +- drivers/media/video/gspca/sonixj.c | 2 +- drivers/media/video/gspca/spca500.c | 9 +++++---- drivers/media/video/gspca/spca505.c | 2 +- drivers/media/video/gspca/sunplus.c | 6 +++--- 10 files changed, 35 insertions(+), 31 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index c479f638413e..195b8123ba75 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -233,7 +233,7 @@ static void Et_RegWrite(struct usb_device *dev, 0, index, buffer, len, 500); } -static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 * buffer, +static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 *buffer, __u16 length, __u8 mode) { /* buffer should be [D0..D7] */ @@ -256,7 +256,7 @@ static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 * buffer, return 0; } -static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 * buffer, +static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 *buffer, __u16 length, __u8 mode) { /* buffer should be [D0..D7] */ diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index c84e0b352f46..13cd9968f1f5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -28,9 +28,9 @@ #include #include #include -#include +#include #include -#include +#include #include #include "gspca.h" @@ -45,8 +45,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1) +static const char version[] = "2.1.1"; static int video_nr = -1; diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 48b861d68299..d8cd2148f301 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -220,13 +220,15 @@ static void sd_start(struct gspca_dev *gspca_dev) if (0) { /* fixed dark-gain */ data[1] = 0; /* reg 94, Y Gain (1.75) */ data[2] = 0; /* reg 95, UV Gain (1.75) */ - data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ + data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable + * auto dark-gain */ data[4] = 0; /* reg 97, set fixed dark level */ data[5] = 0; /* reg 98, don't care */ } else { /* auto dark-gain */ data[1] = 0; /* reg 94, Y Gain (auto) */ data[2] = 0; /* reg 95, UV Gain (1.75) */ - data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable auto dark-gain */ + data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable + * auto dark-gain */ switch (gspca_dev->width) { /* case 1280: */ /* data[4] = 154; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 008954e755f1..84986684c4db 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -452,30 +452,30 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) for (i = 0; i < steps; i++) { if (avg_lum > desired_avg_lum) { - if (sd->gain > PAC207_GAIN_KNEE) { + if (sd->gain > PAC207_GAIN_KNEE) sd->gain--; - } else if (sd->exposure > PAC207_EXPOSURE_KNEE) { + else if (sd->exposure > PAC207_EXPOSURE_KNEE) sd->exposure--; - } else if (sd->gain > PAC207_GAIN_DEFAULT) { + else if (sd->gain > PAC207_GAIN_DEFAULT) sd->gain--; - } else if (sd->exposure > PAC207_EXPOSURE_MIN) { + else if (sd->exposure > PAC207_EXPOSURE_MIN) sd->exposure--; - } else if (sd->gain > PAC207_GAIN_MIN) { + else if (sd->gain > PAC207_GAIN_MIN) sd->gain--; - } else + else break; } else { - if (sd->gain < PAC207_GAIN_DEFAULT) { + if (sd->gain < PAC207_GAIN_DEFAULT) sd->gain++; - } else if (sd->exposure < PAC207_EXPOSURE_KNEE) { + else if (sd->exposure < PAC207_EXPOSURE_KNEE) sd->exposure++; - } else if (sd->gain < PAC207_GAIN_KNEE) { + else if (sd->gain < PAC207_GAIN_KNEE) sd->gain++; - } else if (sd->exposure < PAC207_EXPOSURE_MAX) { + else if (sd->exposure < PAC207_EXPOSURE_MAX) sd->exposure++; - } else if (sd->gain < PAC207_GAIN_MAX) { + else if (sd->gain < PAC207_GAIN_MAX) sd->gain++; - } else + else break; } } diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 8f51976db995..14eb25d81848 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -714,7 +714,8 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, - {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350")}, + {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")}, + /* and also ', Trust WB-3350p, SIGMA cam 2350' */ {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, {} diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index d26255ddfd5b..80911a21e4ae 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -831,7 +831,7 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, - {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia-OV6650-SN9C101G")}, + {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 6180bc565ca1..e6a49fe2c4e3 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1076,7 +1076,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, | ((expo & 0x0003) << 4); i2c_w8(gspca_dev->dev, expoMo10); i2c_w8(gspca_dev->dev, gainMo); - PDEBUG(D_CONF," set exposure %d", + PDEBUG(D_CONF, "set exposure %d", ((expoMo10[3] & 0x07) << 10) | (expoMof[3] << 2) | ((expoMo10[3] & 0x30) >> 4)); diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index c0dd969a3106..e72fca5744ac 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -336,7 +336,7 @@ static unsigned char qtable_kodak_ez200[2][64] = { }; static unsigned char qtable_pocketdv[2][64] = { - { /* Q-table Y-components start registers 0x8800 */ + { /* Q-table Y-components start registers 0x8800 */ 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16, @@ -346,7 +346,7 @@ static unsigned char qtable_pocketdv[2][64] = { 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28, 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28, }, - { /* Q-table C-components start registers 0x8840 */ + { /* Q-table C-components start registers 0x8840 */ 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28, 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28, @@ -833,7 +833,8 @@ static void sd_start(struct gspca_dev *gspca_dev) * - NWG (Sat 29th March 2003) */ /* do a full reset */ - if ((err = spca500_full_reset(gspca_dev)) < 0) + err = spca500_full_reset(gspca_dev); + if (err < 0) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ @@ -918,7 +919,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* Init SDRAM - needed for SDRAM access */ reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); - spca500_setmode(gspca_dev,xmult,ymult); + spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 5b23518d970d..d8ff121c2c5a 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -904,7 +904,7 @@ MODULE_DEVICE_TABLE(usb, device_table); static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return gspca_dev_probe(intf, id, &sd_desc, sizeof (struct sd), + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), THIS_MODULE); } diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 52d1b32523b1..25c5245725d6 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1) +static const char version[] = "2.1.1"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); @@ -459,7 +459,7 @@ static int reg_write(struct usb_device *dev, USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", - reg, index, value, ret); + req, index, value, ret); if (ret < 0) PDEBUG(D_ERR, "reg write: error %d", ret); return ret; -- cgit v1.2.3 From 82643d0e90896fba965e6e43692538b2cc093d34 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 2 Jul 2008 09:14:56 -0300 Subject: V4L/DVB (8181): gspca: read() did not work (loop in kernel, timeout...) main: Remove some vidioc_xx traces. main: read() did not work (user irq instead of mmap irq). main: Lack of v4l1 compat. main: Process loop inside kernel when no frame arriving. main: Double qbuf in read() when too many buffered frames. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 71 +++++++++++++++------------------------ 1 file changed, 28 insertions(+), 43 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 13cd9968f1f5..25e42bd7af87 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -35,8 +35,6 @@ #include "gspca.h" -#undef CONFIG_VIDEO_V4L1_COMPAT - /* global values */ #define DEF_NURBS 2 /* default number of URBs (mmap) */ #define USR_NURBS 5 /* default number of URBs (userptr) */ @@ -45,8 +43,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1) -static const char version[] = "2.1.1"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 2) +static const char version[] = "2.1.2"; static int video_nr = -1; @@ -281,10 +279,16 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, frame->v4l2_buf.length); packet_type = DISCARD_PACKET; } else { - if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) + if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) { memcpy(frame->data_end, data, len); - else - copy_to_user(frame->data_end, data, len); + } else { + if (copy_to_user(frame->data_end, + data, len) != 0) { + PDEBUG(D_ERR|D_PACK, + "copy to user failed"); + packet_type = DISCARD_PACKET; + } + } frame->data_end += len; } } @@ -565,9 +569,8 @@ static int create_urbs(struct gspca_dev *gspca_dev, bsize = psize * npkt; PDEBUG(D_STREAM, "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); -/*fixme:change for userptr*/ /*fixme:don't submit all URBs when userptr*/ - if (gspca_dev->memory == V4L2_MEMORY_MMAP) { + if (gspca_dev->memory != V4L2_MEMORY_USERPTR) { usb_complete = isoc_irq_mmap; nurbs = DEF_NURBS; } else { @@ -746,8 +749,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, int i, j, index; __u32 fmt_tb[8]; - PDEBUG(D_CONF, "enum fmt cap"); - /* give an index to each format */ index = 0; j = 0; @@ -792,14 +793,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, fmt->fmt.pix.width = gspca_dev->width; fmt->fmt.pix.height = gspca_dev->height; fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; -#ifdef VIDEO_ADV_DEBUG - if (gspca_debug & D_CONF) { - PDEBUG_MODE("get fmt cap", - fmt->fmt.pix.pixelformat, - fmt->fmt.pix.width, - fmt->fmt.pix.height); - } -#endif fmt->fmt.pix.field = V4L2_FIELD_NONE; fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) * fmt->fmt.pix.width / 8; @@ -893,13 +886,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; return 0; } -#endif -#ifdef VIDEO_ADV_DEBUG - if (gspca_debug & D_CONF) { - PDEBUG_MODE("set fmt cap", - fmt->fmt.pix.pixelformat, - fmt->fmt.pix.width, fmt->fmt.pix.height); - } #endif if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; @@ -1013,7 +999,6 @@ static int vidioc_querycap(struct file *file, void *priv, { struct gspca_dev *gspca_dev = priv; - PDEBUG(D_CONF, "querycap"); memset(cap, 0, sizeof *cap); strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); @@ -1071,7 +1056,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct ctrl *ctrls; int i, ret; - PDEBUG(D_CONF, "set ctrl"); for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; i < gspca_dev->sd_desc->nctrls; i++, ctrls++) { @@ -1155,7 +1139,6 @@ static int vidioc_reqbufs(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int i, ret = 0; - PDEBUG(D_STREAM, "reqbufs %d", rb->count); if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; switch (rb->memory) { @@ -1205,7 +1188,6 @@ static int vidioc_querybuf(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; struct gspca_frame *frame; - PDEBUG(D_STREAM, "querybuf"); if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || v4l2_buf->index < 0 || v4l2_buf->index >= gspca_dev->nframes) @@ -1222,7 +1204,6 @@ static int vidioc_streamon(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int ret; - PDEBUG(D_STREAM, "stream on"); if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) @@ -1264,7 +1245,6 @@ static int vidioc_streamoff(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int ret; - PDEBUG(D_STREAM, "stream off"); if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (!gspca_dev->streaming) @@ -1499,8 +1479,10 @@ static int frame_wait(struct gspca_dev *gspca_dev, i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; - if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) + if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) { + atomic_dec(&gspca_dev->nevent); goto ok; + } if (nonblock_ing) /* no frame yet */ return -EAGAIN; @@ -1511,9 +1493,10 @@ static int frame_wait(struct gspca_dev *gspca_dev, msecs_to_jiffies(3000)); if (ret <= 0) { if (ret < 0) - return ret; - return -EIO; + return ret; /* interrupt */ + return -EIO; /* timeout */ } + atomic_dec(&gspca_dev->nevent); if (!gspca_dev->streaming || !gspca_dev->present) return -EIO; if (gspca_dev->memory == V4L2_MEMORY_USERPTR) @@ -1525,7 +1508,6 @@ static int frame_wait(struct gspca_dev *gspca_dev, break; } ok: - atomic_dec(&gspca_dev->nevent); gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", gspca_dev->fr_q, @@ -1725,7 +1707,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) goto out; } - /* if not mmap, treat the awaiting URBs */ + /* if userptr, treat the awaiting URBs */ if (gspca_dev->memory == V4L2_MEMORY_USERPTR && gspca_dev->capt_file == file) isoc_transfer(gspca_dev); @@ -1748,7 +1730,7 @@ static ssize_t dev_read(struct file *file, char __user *data, struct gspca_frame *frame; struct v4l2_buffer v4l2_buf; struct timeval timestamp; - int i, ret, ret2; + int n, ret, ret2; PDEBUG(D_FRAM, "read (%d)", count); if (!gspca_dev->present) @@ -1760,9 +1742,9 @@ static ssize_t dev_read(struct file *file, char __user *data, return ret; break; case GSPCA_MEMORY_READ: - if (gspca_dev->capt_file != file) - return -EINVAL; - break; + if (gspca_dev->capt_file == file) + break; + /* fall thru */ default: return -EINVAL; } @@ -1770,7 +1752,8 @@ static ssize_t dev_read(struct file *file, char __user *data, /* get a frame */ jiffies_to_timeval(get_jiffies_64(), ×tamp); timestamp.tv_sec--; - for (i = 0; i < 2; i++) { + n = 2; + for (;;) { memset(&v4l2_buf, 0, sizeof v4l2_buf); v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buf.memory = V4L2_MEMORY_MMAP; @@ -1781,8 +1764,10 @@ static ssize_t dev_read(struct file *file, char __user *data, } /* if the process slept for more than 1 second, - * get a brand new frame */ + * get anewer frame */ frame = &gspca_dev->frame[v4l2_buf.index]; + if (--n < 0) + break; /* avoid infinite loop */ if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec) break; ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); -- cgit v1.2.3 From 30b4d355aa02ba274279eae1187539b85bd100ed Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 2 Jul 2008 12:55:49 -0300 Subject: V4L/DVB (8183): cxusb: select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE After adding support for AVerTVHD Volar, DVB_USB_CXUSB must select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 7847a8320fe7..a577c0f89f67 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -109,6 +109,7 @@ config DVB_USB_CXUSB select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE help Say Y here to support the Conexant USB2.0 hybrid reference design. Currently, only DVB and ATSC modes are supported, analog mode -- cgit v1.2.3 From 69b28b110975abcfac3f7345494e74a771e9b724 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Fri, 4 Jul 2008 04:40:28 -0300 Subject: V4L/DVB (8184): spca508: Add Clone Digital Webcam 11043 Added ID vendor/product for Clone Digital Webcam 11043. Thanks to Ivan Brasil Fuzzer for testing and data collection. Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 1 + drivers/media/video/gspca/spca508.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 37996e59d516..6e68cdeb29d3 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -144,6 +144,7 @@ spca500 06be:0800 Optimedia sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom spca506 06e1:a190 ADS Instant VCD spca508 0733:0110 ViewQuest VQ110 +spca508 0130:0130 Clone Digital Webcam 11043 spca501 0733:0401 Intel Create and Share spca501 0733:0402 ViewQuest M318B spca505 0733:0430 Intel PC Camera Pro diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 566adf41f59f..2ccd877b998d 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1490,8 +1490,10 @@ static int sd_config(struct gspca_dev *gspca_dev, /* break; */ /* } */ break; + case 0x0130: /* Clone webcam */ case 0x0af9: /* Hama cameras */ switch (product) { + case 0x0130: case 0x0010: sd->subtype = HamaUSBSightcam; break; @@ -1737,6 +1739,8 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, + {USB_DEVICE(0x0130, 0x0130), + DVNM("Clone Digital Webcam 11043 (spca508a)")}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From d01eb2dc7d5265ec3bee9ec1b8ab79155e1310d6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 3 Jul 2008 23:43:36 -0300 Subject: V4L/DVB (8186): dib0700: add support for Hauppauge Nova-TD Stick 52009 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dib0700_devices.c | 7 ++++++- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index c4d40fe01d57..3dd20bfbed32 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -1117,6 +1117,7 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, + { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -1372,7 +1373,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { } }, - .num_device_descs = 2, + .num_device_descs = 3, .devices = { { "DiBcom STK7070PD reference design", { &dib0700_usb_id_table[17], NULL }, @@ -1381,6 +1382,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { { "Pinnacle PCTV Dual DVB-T Diversity Stick", { &dib0700_usb_id_table[18], NULL }, { NULL }, + }, + { "Hauppauge Nova-TD Stick (52009)", + { &dib0700_usb_id_table[35], NULL }, + { NULL }, } } }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 75ec9caa1421..e5238b31e946 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -134,6 +134,7 @@ #define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 #define USB_PID_HAUPPAUGE_MYTV_T 0x7080 #define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 +#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200 #define USB_PID_AVERMEDIA_EXPRESS 0xb568 #define USB_PID_AVERMEDIA_VOLAR 0xa807 #define USB_PID_AVERMEDIA_VOLAR_2 0xb808 -- cgit v1.2.3 From 53ad02efe7d5908f0ce73a7dac9530f1180f2514 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 6 Jul 2008 19:36:52 -0300 Subject: V4L/DVB (8188): cx18: Add missing reset recovery delay in cx18-i2c.c cx18: Add a missing reset recovery delay in cx18-i2c.c after the final deassert. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-i2c.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index bca905901d61..3f972e2db705 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -409,6 +409,7 @@ int init_cx18_i2c(struct cx18 *cx) write_reg_sync(0x00c000c0, 0xc7001c); mdelay(10); write_reg_sync(0x00c00000, 0xc7001c); + mdelay(10); write_reg_sync(0x00c00000, 0xc730c8); /* Set to edge-triggered intrs. */ write_reg_sync(0x00c00000, 0xc730c4); /* Clear any stale intrs */ -- cgit v1.2.3 From 0c61621412ca09bd692cef86d4c9f358d5e81b0c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Mon, 7 Jul 2008 10:36:16 -0300 Subject: V4L/DVB (8189): cx18: Use correct GPIO pin for resetting Xceive 3028 tuner on Yuan MPC718 Change the Yuan MPC718 cards entry to use the correct GPIO pin for resetting the Xceive 3028 tuner. Thanks to Brian Hope for taking the time and figuring out which pin to use. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index bb45bcf68ea6..0caae1a5edc4 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -196,7 +196,7 @@ static const struct cx18_card_pci_info cx18_pci_mpc718[] = { static const struct cx18_card cx18_card_mpc718 = { .type = CX18_CARD_YUAN_MPC718, .name = "Yuan MPC718", - .comment = "Some Composite and S-Video inputs are currently working.\n", + .comment = "Analog video capture works; some audio line in may not.\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, @@ -229,7 +229,7 @@ static const struct cx18_card cx18_card_mpc718 = { .tune_lane = 0, .initial_emrs = 2, }, - .xceive_pin = 15, + .xceive_pin = 0, .pci_list = cx18_pci_mpc718, .i2c = &cx18_i2c_std, }; -- cgit v1.2.3 From d646e701819f994c5cb1507dc859b739b5478d32 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 3 Jul 2008 06:48:22 -0300 Subject: V4L/DVB (8191): gspca: Make CONFIG_VIDEO_ADV_DEBUG actually work. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 12 ++++++------ drivers/media/video/gspca/gspca.h | 2 +- drivers/media/video/gspca/zc3xx.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 25e42bd7af87..b36913017d7b 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -50,7 +50,7 @@ static int video_nr = -1; static int comp_fac = 30; /* Buffer size ratio when compressed in % */ -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG int gspca_debug = D_ERR | D_PROBE; EXPORT_SYMBOL(gspca_debug); @@ -817,7 +817,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, /* (luvcview problem) */ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); #endif @@ -837,7 +837,7 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, /* no chance, return this mode */ fmt->fmt.pix.pixelformat = gspca_dev->cam.cam_mode[mode].pixfmt; -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) { PDEBUG_MODE("new format", fmt->fmt.pix.pixelformat, @@ -952,7 +952,7 @@ static int dev_open(struct inode *inode, struct file *file) } gspca_dev->users++; file->private_data = gspca_dev; -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG /* activate the v4l2 debug */ if (gspca_debug & D_V4L2) gspca_dev->vdev.debug |= 3; @@ -1225,7 +1225,7 @@ static int vidioc_streamon(struct file *file, void *priv, if (ret < 0) goto out; } -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_STREAM) { PDEBUG_MODE("stream on OK", gspca_dev->pixfmt, @@ -1980,7 +1980,7 @@ static void __exit gspca_exit(void) module_init(gspca_init); module_exit(gspca_exit); -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG module_param_named(debug, gspca_debug, int, 0644); MODULE_PARM_DESC(debug, "Debug (bit) 0x01:error 0x02:probe 0x04:config" diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 1581fa808b6f..9c894daf356a 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -28,7 +28,7 @@ #define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) #endif -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG /* GSPCA our debug messages */ extern int gspca_debug; #define PDEBUG(level, fmt, args...) \ diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index b767f32511bb..ccd24cb92b3f 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6432,7 +6432,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) 0, Tgradient_1, Tgradient_2, Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 }; -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG __u8 v[16]; #endif @@ -6450,7 +6450,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) else if (g <= 0) g = 1; reg_w(dev, g, 0x0120 + i); /* gamma */ -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif @@ -6470,7 +6470,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) g = 1; } reg_w(dev, g, 0x0130 + i); /* gradient */ -#ifdef VIDEO_ADV_DEBUG +#ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) v[i] = g; #endif -- cgit v1.2.3 From 0d2a722ddae5e736a5c36a1b99ee4ca59a8373bc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 3 Jul 2008 08:15:22 -0300 Subject: V4L/DVB (8192): Try to fix a reg_w() bug Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 41 ++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 80911a21e4ae..7850efa41096 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); @@ -336,13 +336,22 @@ static void reg_w(struct usb_device *dev, const __u8 *buffer, __u16 len) { + __u8 tmpbuf[32]; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof tmpbuf) { + PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + return; + } +#endif + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x08, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, /* index */ - (__u8 *) buffer, len, + tmpbuf, len, 500); } @@ -747,22 +756,20 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, unsigned char *data, /* isoc packet */ int len) /* iso packet length */ { - int p; + int i; if (len > 6 && len < 24) { - for (p = 0; p < len - 6; p++) { - if (data[0 + p] == 0xff - && data[1 + p] == 0xff - && data[2 + p] == 0x00 - && data[3 + p] == 0xc4 - && data[4 + p] == 0xc4 - && data[5 + p] == 0x96) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - data, 0); - data += 12; - len -= 12; + for (i = 0; i < len - 6; i++) { + if (data[0 + i] == 0xff + && data[1 + i] == 0xff + && data[2 + i] == 0x00 + && data[3 + i] == 0xc4 + && data[4 + i] == 0xc4 + && data[5 + i] == 0x96) { /* start of frame */ + frame = gspca_frame_add(gspca_dev, LAST_PACKET, + frame, data, 0); + data += i + 12; + len -= i + 12; gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); return; -- cgit v1.2.3 From bf7f0b98426b54c29ec8100a3f1963114c2f2ef0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 3 Jul 2008 11:09:12 -0300 Subject: V4L/DVB (8193): gspca: Input buffer may be changed on reg write. Done for conex, etoms, pac7311, sonixj, t613 and tv8532. Code cleanup for some other subdrivers. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 41 +++--- drivers/media/video/gspca/etoms.c | 279 ++++++++++++++++++------------------ drivers/media/video/gspca/mars.c | 48 +++---- drivers/media/video/gspca/pac7311.c | 63 ++++---- drivers/media/video/gspca/sonixb.c | 2 +- drivers/media/video/gspca/sonixj.c | 17 ++- drivers/media/video/gspca/spca500.c | 2 +- drivers/media/video/gspca/sunplus.c | 2 +- drivers/media/video/gspca/t613.c | 33 +++-- drivers/media/video/gspca/tv8532.c | 13 +- 10 files changed, 257 insertions(+), 243 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index b0294c9274e3..473bea750b5f 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -25,8 +25,8 @@ #define CONEX_CAM 1 /* special JPEG header */ #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); @@ -114,21 +114,29 @@ static void reg_r(struct usb_device *dev, 0, index, buffer, length, 500); - PDEBUG(D_USBI, "reg read i:%02x -> %02x", index, *buffer); + PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", index, *buffer); } static void reg_w(struct usb_device *dev, __u16 index, - const __u8 *buffer, __u16 length) + const __u8 *buffer, __u16 len) { - PDEBUG(D_USBO, "reg write i:%02x = %02x", index, *buffer); + __u8 tmpbuf[8]; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof tmpbuf) { + PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + return; + } + PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); +#endif + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, - index, (__u8 *) buffer, length, - 500); + index, tmpbuf, len, 500); } static const __u8 cx_sensor_init[][4] = { @@ -269,7 +277,7 @@ static void cx_sensor(struct gspca_dev*gspca_dev) reg_w(gspca_dev->dev, 0x0071, reg71b, 4); break; default: -/* case 2: */ +/* case 2: */ reg_w(gspca_dev->dev, 0x0071, reg71c, 4); break; case 3: @@ -662,8 +670,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, - cxjpeg_640[i], length); + reg_w(gspca_dev->dev, 0x0008, cxjpeg_640[i], length); } Reg55 = 0x28; break; @@ -671,8 +678,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, - cxjpeg_352[i], length); + reg_w(gspca_dev->dev, 0x0008, cxjpeg_352[i], length); } Reg55 = 0x16; break; @@ -681,8 +687,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, - cxjpeg_320[i], length); + reg_w(gspca_dev->dev, 0x0008, cxjpeg_320[i], length); } Reg55 = 0x14; break; @@ -690,8 +695,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, - cxjpeg_176[i], length); + reg_w(gspca_dev->dev, 0x0008, cxjpeg_176[i], length); } Reg55 = 0x0B; break; @@ -731,8 +735,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 18; i++) { if (i == 17) length = 2; - reg_w(gspca_dev->dev, 0x0008, - cxjpeg_qtable[i], length); + reg_w(gspca_dev->dev, 0x0008, cxjpeg_qtable[i], length); } reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */ @@ -866,7 +869,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0x0053, &val, 1); while (retry--) { -/* reg_r (gspca_dev->dev,0x00,0x00,0x0002,&val,1);*/ +/* reg_r(gspca_dev->dev, 0x0002, &val, 1);*/ reg_r(gspca_dev->dev, 0x0053, &val, 1); if (val == 0) break; diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 195b8123ba75..ed7a8f9c0d7a 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("Etoms USB Camera Driver"); @@ -213,7 +213,7 @@ static __u8 I2c3[] = { 0x12, 0x05 }; static __u8 I2c4[] = { 0x41, 0x08 }; -static void Et_RegRead(struct usb_device *dev, +static void reg_r(struct usb_device *dev, __u16 index, __u8 *buffer, int len) { usb_control_msg(dev, @@ -223,14 +223,17 @@ static void Et_RegRead(struct usb_device *dev, 0, index, buffer, len, 500); } -static void Et_RegWrite(struct usb_device *dev, +static void reg_w(struct usb_device *dev, __u16 index, __u8 *buffer, __u16 len) { + __u8 tmpbuf[8]; + + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, buffer, len, 500); + 0, index, tmpbuf, len, 500); } static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 *buffer, @@ -243,14 +246,14 @@ static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 *buffer, ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); /* set the base address */ - Et_RegWrite(dev, ET_I2C_BASE, &base, 1); + reg_w(dev, ET_I2C_BASE, &base, 1); /* set count and prefetch */ - Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); + reg_w(dev, ET_I2C_COUNT, &ptchcount, 1); /* set the register base */ - Et_RegWrite(dev, ET_I2C_REG, ®, 1); + reg_w(dev, ET_I2C_REG, ®, 1); j = length - 1; for (i = 0; i < length; i++) { - Et_RegWrite(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); + reg_w(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); j--; } return 0; @@ -267,17 +270,17 @@ static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 *buffer, ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); /* set the base address */ - Et_RegWrite(dev, ET_I2C_BASE, &base, 1); + reg_w(dev, ET_I2C_BASE, &base, 1); /* set count and prefetch */ - Et_RegWrite(dev, ET_I2C_COUNT, &ptchcount, 1); + reg_w(dev, ET_I2C_COUNT, &ptchcount, 1); /* set the register base */ - Et_RegWrite(dev, ET_I2C_REG, ®, 1); - Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); + reg_w(dev, ET_I2C_REG, ®, 1); + reg_w(dev, ET_I2C_PREFETCH, &prefetch, 1); prefetch = 0x00; - Et_RegWrite(dev, ET_I2C_PREFETCH, &prefetch, 1); + reg_w(dev, ET_I2C_PREFETCH, &prefetch, 1); j = length - 1; for (i = 0; i < length; i++) { - Et_RegRead(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); + reg_r(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); j--; } return 0; @@ -289,7 +292,7 @@ static int Et_WaitStatus(struct usb_device *dev) int retry = 10; while (retry--) { - Et_RegRead(dev, ET_ClCK, &bytereceived, 1); + reg_r(dev, ET_ClCK, &bytereceived, 1); if (bytereceived != 0) return 1; } @@ -301,7 +304,7 @@ static int Et_videoOff(struct usb_device *dev) int err; __u8 stopvideo = 0; - Et_RegWrite(dev, ET_GPIO_OUT, &stopvideo, 1); + reg_w(dev, ET_GPIO_OUT, &stopvideo, 1); err = Et_WaitStatus(dev); if (!err) PDEBUG(D_ERR, "timeout Et_waitStatus VideoON"); @@ -313,7 +316,7 @@ static int Et_videoOn(struct usb_device *dev) int err; __u8 startvideo = 0x10; /* set Bit5 */ - Et_RegWrite(dev, ET_GPIO_OUT, &startvideo, 1); + reg_w(dev, ET_GPIO_OUT, &startvideo, 1); err = Et_WaitStatus(dev); if (!err) PDEBUG(D_ERR, "timeout Et_waitStatus VideoOFF"); @@ -329,156 +332,156 @@ static void Et_init2(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "Open Init2 ET"); value = 0x2f; - Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); + reg_w(dev, ET_GPIO_DIR_CTRL, &value, 1); value = 0x10; - Et_RegWrite(dev, ET_GPIO_OUT, &value, 1); - Et_RegRead(dev, ET_GPIO_IN, &received, 1); + reg_w(dev, ET_GPIO_OUT, &value, 1); + reg_r(dev, ET_GPIO_IN, &received, 1); value = 0x14; /* 0x14 // 0x16 enabled pattern */ - Et_RegWrite(dev, ET_ClCK, &value, 1); + reg_w(dev, ET_ClCK, &value, 1); value = 0x1b; - Et_RegWrite(dev, ET_CTRL, &value, 1); + reg_w(dev, ET_CTRL, &value, 1); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) value = ET_COMP_VAL1; /* 320 */ else value = ET_COMP_VAL0; /* 640 */ - Et_RegWrite(dev, ET_COMP, &value, 1); + reg_w(dev, ET_COMP, &value, 1); value = 0x1f; - Et_RegWrite(dev, ET_MAXQt, &value, 1); + reg_w(dev, ET_MAXQt, &value, 1); value = 0x04; - Et_RegWrite(dev, ET_MINQt, &value, 1); + reg_w(dev, ET_MINQt, &value, 1); /* undocumented registers */ value = 0xff; - Et_RegWrite(dev, ET_REG1d, &value, 1); + reg_w(dev, ET_REG1d, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG1e, &value, 1); + reg_w(dev, ET_REG1e, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG1f, &value, 1); + reg_w(dev, ET_REG1f, &value, 1); value = 0x35; - Et_RegWrite(dev, ET_REG20, &value, 1); + reg_w(dev, ET_REG20, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_REG21, &value, 1); + reg_w(dev, ET_REG21, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_REG22, &value, 1); + reg_w(dev, ET_REG22, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG23, &value, 1); + reg_w(dev, ET_REG23, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG24, &value, 1); + reg_w(dev, ET_REG24, &value, 1); value = 0x0f; - Et_RegWrite(dev, ET_REG25, &value, 1); + reg_w(dev, ET_REG25, &value, 1); /* colors setting */ value = 0x11; - Et_RegWrite(dev, 0x30, &value, 1); /* 0x30 */ + reg_w(dev, 0x30, &value, 1); /* 0x30 */ value = 0x40; - Et_RegWrite(dev, 0x31, &value, 1); + reg_w(dev, 0x31, &value, 1); value = 0x00; - Et_RegWrite(dev, 0x32, &value, 1); + reg_w(dev, 0x32, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_O_RED, &value, 1); /* 0x34 */ + reg_w(dev, ET_O_RED, &value, 1); /* 0x34 */ value = 0x00; - Et_RegWrite(dev, ET_O_GREEN1, &value, 1); + reg_w(dev, ET_O_GREEN1, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_O_BLUE, &value, 1); + reg_w(dev, ET_O_BLUE, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_O_GREEN2, &value, 1); + reg_w(dev, ET_O_GREEN2, &value, 1); /*************/ value = 0x80; - Et_RegWrite(dev, ET_G_RED, &value, 1); /* 0x4d */ + reg_w(dev, ET_G_RED, &value, 1); /* 0x4d */ value = 0x80; - Et_RegWrite(dev, ET_G_GREEN1, &value, 1); + reg_w(dev, ET_G_GREEN1, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_G_BLUE, &value, 1); + reg_w(dev, ET_G_BLUE, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_G_GREEN2, &value, 1); + reg_w(dev, ET_G_GREEN2, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_G_GR_H, &value, 1); + reg_w(dev, ET_G_GR_H, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_G_GB_H, &value, 1); /* 0x52 */ + reg_w(dev, ET_G_GB_H, &value, 1); /* 0x52 */ /* Window control registers */ value = 0x80; /* use cmc_out */ - Et_RegWrite(dev, 0x61, &value, 1); + reg_w(dev, 0x61, &value, 1); value = 0x02; - Et_RegWrite(dev, 0x62, &value, 1); + reg_w(dev, 0x62, &value, 1); value = 0x03; - Et_RegWrite(dev, 0x63, &value, 1); + reg_w(dev, 0x63, &value, 1); value = 0x14; - Et_RegWrite(dev, 0x64, &value, 1); + reg_w(dev, 0x64, &value, 1); value = 0x0e; - Et_RegWrite(dev, 0x65, &value, 1); + reg_w(dev, 0x65, &value, 1); value = 0x02; - Et_RegWrite(dev, 0x66, &value, 1); + reg_w(dev, 0x66, &value, 1); value = 0x02; - Et_RegWrite(dev, 0x67, &value, 1); + reg_w(dev, 0x67, &value, 1); /**************************************/ value = 0x8f; - Et_RegWrite(dev, ET_SYNCHRO, &value, 1); /* 0x68 */ + reg_w(dev, ET_SYNCHRO, &value, 1); /* 0x68 */ value = 0x69; /* 0x6a //0x69 */ - Et_RegWrite(dev, ET_STARTX, &value, 1); + reg_w(dev, ET_STARTX, &value, 1); value = 0x0d; /* 0x0d //0x0c */ - Et_RegWrite(dev, ET_STARTY, &value, 1); + reg_w(dev, ET_STARTY, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); + reg_w(dev, ET_WIDTH_LOW, &value, 1); value = 0xe0; - Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); + reg_w(dev, ET_HEIGTH_LOW, &value, 1); value = 0x60; - Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */ + reg_w(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */ value = 0x86; - Et_RegWrite(dev, ET_REG6e, &value, 1); + reg_w(dev, ET_REG6e, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_REG6f, &value, 1); + reg_w(dev, ET_REG6f, &value, 1); value = 0x26; - Et_RegWrite(dev, ET_REG70, &value, 1); + reg_w(dev, ET_REG70, &value, 1); value = 0x7a; - Et_RegWrite(dev, ET_REG71, &value, 1); + reg_w(dev, ET_REG71, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_REG72, &value, 1); + reg_w(dev, ET_REG72, &value, 1); /* Clock Pattern registers ***************** */ value = 0x00; - Et_RegWrite(dev, ET_REG73, &value, 1); + reg_w(dev, ET_REG73, &value, 1); value = 0x18; /* 0x28 */ - Et_RegWrite(dev, ET_REG74, &value, 1); + reg_w(dev, ET_REG74, &value, 1); value = 0x0f; /* 0x01 */ - Et_RegWrite(dev, ET_REG75, &value, 1); + reg_w(dev, ET_REG75, &value, 1); /**********************************************/ value = 0x20; - Et_RegWrite(dev, 0x8a, &value, 1); + reg_w(dev, 0x8a, &value, 1); value = 0x0f; - Et_RegWrite(dev, 0x8d, &value, 1); + reg_w(dev, 0x8d, &value, 1); value = 0x08; - Et_RegWrite(dev, 0x8e, &value, 1); + reg_w(dev, 0x8e, &value, 1); /**************************************/ value = 0x08; - Et_RegWrite(dev, 0x03, &value, 1); + reg_w(dev, 0x03, &value, 1); value = 0x03; - Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + reg_w(dev, ET_PXL_CLK, &value, 1); value = 0xff; - Et_RegWrite(dev, 0x81, &value, 1); + reg_w(dev, 0x81, &value, 1); value = 0x00; - Et_RegWrite(dev, 0x80, &value, 1); + reg_w(dev, 0x80, &value, 1); value = 0xff; - Et_RegWrite(dev, 0x81, &value, 1); + reg_w(dev, 0x81, &value, 1); value = 0x20; - Et_RegWrite(dev, 0x80, &value, 1); + reg_w(dev, 0x80, &value, 1); value = 0x01; - Et_RegWrite(dev, 0x03, &value, 1); + reg_w(dev, 0x03, &value, 1); value = 0x00; - Et_RegWrite(dev, 0x03, &value, 1); + reg_w(dev, 0x03, &value, 1); value = 0x08; - Et_RegWrite(dev, 0x03, &value, 1); + reg_w(dev, 0x03, &value, 1); /********************************************/ - /* Et_RegRead(dev,0x0,ET_I2C_BASE,&received,1); + /* reg_r(dev,0x0,ET_I2C_BASE,&received,1); always 0x40 as the pas106 ??? */ /* set the sensor */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { value = 0x04; /* 320 */ - Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + reg_w(dev, ET_PXL_CLK, &value, 1); /* now set by fifo the FormatLine setting */ - Et_RegWrite(dev, 0x62, FormLine, 6); + reg_w(dev, 0x62, FormLine, 6); } else { /* 640 */ /* setting PixelClock 0x03 mean 24/(3+1) = 6 Mhz @@ -487,24 +490,24 @@ static void Et_init2(struct gspca_dev *gspca_dev) 0x17 -> 24/(23+1) = 1 Mhz */ value = 0x1e; /* 0x17 */ - Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + reg_w(dev, ET_PXL_CLK, &value, 1); /* now set by fifo the FormatLine setting */ - Et_RegWrite(dev, 0x62, FormLine, 6); + reg_w(dev, 0x62, FormLine, 6); } /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ value = 0x47; /* 0x47; */ - Et_RegWrite(dev, 0x81, &value, 1); + reg_w(dev, 0x81, &value, 1); value = 0x40; /* 0x40; */ - Et_RegWrite(dev, 0x80, &value, 1); + reg_w(dev, 0x80, &value, 1); /* Pedro change */ /* Brightness change Brith+ decrease value */ /* Brigth- increase value */ /* original value = 0x70; */ value = 0x30; /* 0x20; */ - Et_RegWrite(dev, 0x81, &value, 1); /* set brightness */ + reg_w(dev, 0x81, &value, 1); /* set brightness */ value = 0x20; /* 0x20; */ - Et_RegWrite(dev, 0x80, &value, 1); + reg_w(dev, 0x80, &value, 1); } static void setcolors(struct gspca_dev *gspca_dev) @@ -554,16 +557,16 @@ static void Et_init1(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "Open Init1 ET"); value = 7; - Et_RegWrite(dev, ET_GPIO_DIR_CTRL, &value, 1); - Et_RegRead(dev, ET_GPIO_IN, &received, 1); + reg_w(dev, ET_GPIO_DIR_CTRL, &value, 1); + reg_r(dev, ET_GPIO_IN, &received, 1); value = 1; - Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + reg_w(dev, ET_RESET_ALL, &value, 1); value = 0; - Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + reg_w(dev, ET_RESET_ALL, &value, 1); value = 0x10; - Et_RegWrite(dev, ET_ClCK, &value, 1); + reg_w(dev, ET_ClCK, &value, 1); value = 0x19; - Et_RegWrite(dev, ET_CTRL, &value, 1); + reg_w(dev, ET_CTRL, &value, 1); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) value = ET_COMP_VAL1; @@ -573,77 +576,77 @@ static void Et_init1(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "Open mode %d Compression %d", gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode, value); - Et_RegWrite(dev, ET_COMP, &value, 1); + reg_w(dev, ET_COMP, &value, 1); value = 0x1d; - Et_RegWrite(dev, ET_MAXQt, &value, 1); + reg_w(dev, ET_MAXQt, &value, 1); value = 0x02; - Et_RegWrite(dev, ET_MINQt, &value, 1); + reg_w(dev, ET_MINQt, &value, 1); /* undocumented registers */ value = 0xff; - Et_RegWrite(dev, ET_REG1d, &value, 1); + reg_w(dev, ET_REG1d, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG1e, &value, 1); + reg_w(dev, ET_REG1e, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG1f, &value, 1); + reg_w(dev, ET_REG1f, &value, 1); value = 0x35; - Et_RegWrite(dev, ET_REG20, &value, 1); + reg_w(dev, ET_REG20, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_REG21, &value, 1); + reg_w(dev, ET_REG21, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_REG22, &value, 1); + reg_w(dev, ET_REG22, &value, 1); value = 0xf7; - Et_RegWrite(dev, ET_REG23, &value, 1); + reg_w(dev, ET_REG23, &value, 1); value = 0xff; - Et_RegWrite(dev, ET_REG24, &value, 1); + reg_w(dev, ET_REG24, &value, 1); value = 0x07; - Et_RegWrite(dev, ET_REG25, &value, 1); + reg_w(dev, ET_REG25, &value, 1); /* colors setting */ value = 0x80; - Et_RegWrite(dev, ET_G_RED, &value, 1); + reg_w(dev, ET_G_RED, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_G_GREEN1, &value, 1); + reg_w(dev, ET_G_GREEN1, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_G_BLUE, &value, 1); + reg_w(dev, ET_G_BLUE, &value, 1); value = 0x80; - Et_RegWrite(dev, ET_G_GREEN2, &value, 1); + reg_w(dev, ET_G_GREEN2, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_G_GR_H, &value, 1); + reg_w(dev, ET_G_GR_H, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_G_GB_H, &value, 1); + reg_w(dev, ET_G_GB_H, &value, 1); /* Window control registers */ value = 0xf0; - Et_RegWrite(dev, ET_SYNCHRO, &value, 1); + reg_w(dev, ET_SYNCHRO, &value, 1); value = 0x56; /* 0x56 */ - Et_RegWrite(dev, ET_STARTX, &value, 1); + reg_w(dev, ET_STARTX, &value, 1); value = 0x05; /* 0x04 */ - Et_RegWrite(dev, ET_STARTY, &value, 1); + reg_w(dev, ET_STARTY, &value, 1); value = 0x60; - Et_RegWrite(dev, ET_WIDTH_LOW, &value, 1); + reg_w(dev, ET_WIDTH_LOW, &value, 1); value = 0x20; - Et_RegWrite(dev, ET_HEIGTH_LOW, &value, 1); + reg_w(dev, ET_HEIGTH_LOW, &value, 1); value = 0x50; - Et_RegWrite(dev, ET_W_H_HEIGTH, &value, 1); + reg_w(dev, ET_W_H_HEIGTH, &value, 1); value = 0x86; - Et_RegWrite(dev, ET_REG6e, &value, 1); + reg_w(dev, ET_REG6e, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_REG6f, &value, 1); + reg_w(dev, ET_REG6f, &value, 1); value = 0x86; - Et_RegWrite(dev, ET_REG70, &value, 1); + reg_w(dev, ET_REG70, &value, 1); value = 0x14; - Et_RegWrite(dev, ET_REG71, &value, 1); + reg_w(dev, ET_REG71, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_REG72, &value, 1); + reg_w(dev, ET_REG72, &value, 1); /* Clock Pattern registers */ value = 0x00; - Et_RegWrite(dev, ET_REG73, &value, 1); + reg_w(dev, ET_REG73, &value, 1); value = 0x00; - Et_RegWrite(dev, ET_REG74, &value, 1); + reg_w(dev, ET_REG74, &value, 1); value = 0x0a; - Et_RegWrite(dev, ET_REG75, &value, 1); + reg_w(dev, ET_REG75, &value, 1); value = 0x04; - Et_RegWrite(dev, ET_I2C_CLK, &value, 1); + reg_w(dev, ET_I2C_CLK, &value, 1); value = 0x01; - Et_RegWrite(dev, ET_PXL_CLK, &value, 1); + reg_w(dev, ET_PXL_CLK, &value, 1); /* set the sensor */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { I2c0[0] = 0x06; @@ -679,7 +682,7 @@ static void Et_init1(struct gspca_dev *gspca_dev) /* magnetude and sign bit for DAC */ Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1); /* now set by fifo the whole colors setting */ - Et_RegWrite(dev, ET_G_RED, GainRGBG, 6); + reg_w(dev, ET_G_RED, GainRGBG, 6); getcolors(gspca_dev); setcolors(gspca_dev); } @@ -738,7 +741,7 @@ static int sd_open(struct gspca_dev *gspca_dev) else Et_init2(gspca_dev); value = 0x08; - Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + reg_w(dev, ET_RESET_ALL, &value, 1); err = Et_videoOff(dev); PDEBUG(D_STREAM, "Et_Init_VideoOff %d", err); return 0; @@ -758,7 +761,7 @@ static void sd_start(struct gspca_dev *gspca_dev) Et_init2(gspca_dev); value = 0x08; - Et_RegWrite(dev, ET_RESET_ALL, &value, 1); + reg_w(dev, ET_RESET_ALL, &value, 1); err = Et_videoOn(dev); PDEBUG(D_STREAM, "Et_VideoOn %d", err); } @@ -787,7 +790,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 brightness = sd->brightness; for (i = 0; i < 4; i++) - Et_RegWrite(gspca_dev->dev, (ET_O_RED + i), &brightness, 1); + reg_w(gspca_dev->dev, (ET_O_RED + i), &brightness, 1); } static void getbrightness(struct gspca_dev *gspca_dev) @@ -798,7 +801,7 @@ static void getbrightness(struct gspca_dev *gspca_dev) __u8 value = 0; for (i = 0; i < 4; i++) { - Et_RegRead(gspca_dev->dev, (ET_O_RED + i), &value, 1); + reg_r(gspca_dev->dev, (ET_O_RED + i), &value, 1); brightness += value; } sd->brightness = brightness >> 3; @@ -811,7 +814,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) __u8 contrast = sd->contrast; memset(RGBG, contrast, sizeof RGBG - 2); - Et_RegWrite(gspca_dev->dev, ET_G_RED, RGBG, 6); + reg_w(gspca_dev->dev, ET_G_RED, RGBG, 6); } static void getcontrast(struct gspca_dev *gspca_dev) @@ -822,7 +825,7 @@ static void getcontrast(struct gspca_dev *gspca_dev) __u8 value = 0; for (i = 0; i < 4; i++) { - Et_RegRead(gspca_dev->dev, (ET_G_RED + i), &value, 1); + reg_r(gspca_dev->dev, (ET_G_RED + i), &value, 1); contrast += value; } sd->contrast = contrast >> 2; @@ -870,7 +873,7 @@ static void setautogain(struct gspca_dev *gspca_dev) __u8 r, g, b; Gbright = Et_getgainG(gspca_dev); - Et_RegRead(dev, ET_LUMA_CENTER, GRBG, 4); + reg_r(dev, ET_LUMA_CENTER, GRBG, 4); g = (GRBG[0] + GRBG[3]) >> 1; r = GRBG[1]; b = GRBG[2]; diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index d8cd2148f301..6556e0a330fa 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -79,49 +79,35 @@ enum { }; static int pcam_reg_write(struct usb_device *dev, - __u16 index, unsigned char *value, int length) + __u16 index, __u8 *value, int len) { int rc; rc = usb_control_msg(dev, usb_sndbulkpipe(dev, 4), 0x12, -/* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ +/* ?? 0xc8 = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_??? !? */ 0xc8, 0, /* value */ - index, value, length, 500); - PDEBUG(D_USBO, "reg write: 0x%02X , result = 0x%x", index, rc); - + index, value, len, 500); if (rc < 0) - PDEBUG(D_ERR, "reg write: error %d", rc); + PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); return rc; } -static void MISensor_BulkWrite(struct usb_device *dev, unsigned short *pch, - char Address) +static void MISensor_BulkWrite(struct usb_device *dev, + unsigned short *pch, + char Address) { - int result; - unsigned char data[6]; + __u8 data[6]; data[0] = 0x1f; - data[1] = 0; + data[1] = 0; /* control byte */ data[2] = Address; data[3] = *pch >> 8; /* high byte */ data[4] = *pch; /* low byte */ - data[5] = 0; - - result = usb_control_msg(dev, - usb_sndbulkpipe(dev, 4), - 0x12, -/* ?? 0xc8 = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_??? !? */ - 0xc8, - 0, /* value */ - Address, /* index */ - data, 5, 500); - PDEBUG(D_USBO, "bulk write 0x%02x = 0x%04x", Address, *pch); - if (result < 0) - PDEBUG(D_ERR, "reg write: error %d", result); + pcam_reg_write(dev, Address, data, 5); } /* this function is called at probe time */ @@ -167,7 +153,7 @@ static void sd_start(struct gspca_dev *gspca_dev) data[0] = 0x01; /* address */ data[1] = 0x01; - err_code = pcam_reg_write(dev, data[0], data, 0x02); + err_code = pcam_reg_write(dev, data[0], data, 2); if (err_code < 0) return; @@ -193,14 +179,14 @@ static void sd_start(struct gspca_dev *gspca_dev) data[10] = 0x5d; /* reg 9, I2C device address * [for PAS5101 (0x40)] [for MI (0x5d)] */ - err_code = pcam_reg_write(dev, data[0], data, 0x0b); + err_code = pcam_reg_write(dev, data[0], data, 11); if (err_code < 0) return; data[0] = 0x23; /* address */ data[1] = 0x09; /* reg 35, append frame header */ - err_code = pcam_reg_write(dev, data[0], data, 0x02); + err_code = pcam_reg_write(dev, data[0], data, 2); if (err_code < 0) { PDEBUG(D_ERR, "Register write failed"); return; @@ -213,7 +199,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* else */ data[1] = 50; /* 50 reg 60, pc-cam frame size * (unit: 4KB) 200KB */ - err_code = pcam_reg_write(dev, data[0], data, 0x02); + err_code = pcam_reg_write(dev, data[0], data, 2); if (err_code < 0) return; @@ -255,13 +241,13 @@ static void sd_start(struct gspca_dev *gspca_dev) /* auto dark-gain */ data[0] = 0x5e; /* address */ - err_code = pcam_reg_write(dev, data[0], data, 0x06); + err_code = pcam_reg_write(dev, data[0], data, 6); if (err_code < 0) return; data[0] = 0x67; data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ - err_code = pcam_reg_write(dev, data[0], data, 0x02); + err_code = pcam_reg_write(dev, data[0], data, 2); if (err_code < 0) return; @@ -340,7 +326,7 @@ static void sd_start(struct gspca_dev *gspca_dev) data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ - pcam_reg_write(dev, data[0], data, 0x02); + pcam_reg_write(dev, data[0], data, 2); } static void sd_stopN(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 14eb25d81848..14cc49a4c2cc 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); @@ -195,16 +195,18 @@ const unsigned char pac7311_jpeg_header[] = { }; static void reg_w(struct usb_device *dev, - __u16 req, - __u16 value, __u16 index, - __u8 *buffer, __u16 length) + char *buffer, __u16 len) { + __u8 tmpbuf[8]; + + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), - req, + 1, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, buffer, length, + 0, /* value */ + index, tmpbuf, len, 500); } @@ -227,7 +229,12 @@ static void pac7311_reg_write(struct usb_device *dev, __u8 buf; buf = value; - reg_w(dev, 0x00, value, index, &buf, 1); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, &buf, 1, + 500); } /* this function is called at probe time */ @@ -313,26 +320,26 @@ static void sd_start(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; pac7311_reg_write(dev, 0xff, 0x01); - reg_w(dev, 0x01, 0, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); - reg_w(dev, 0x01, 0, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); - reg_w(dev, 0x01, 0, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); - reg_w(dev, 0x01, 0, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); - reg_w(dev, 0x01, 0, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); - reg_w(dev, 0x01, 0, 0x002a, "\x00\x00\x00", 3); - reg_w(dev, 0x01, 0, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); - reg_w(dev, 0x01, 0, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); - reg_w(dev, 0x01, 0, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); - reg_w(dev, 0x01, 0, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); - reg_w(dev, 0x01, 0, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); - reg_w(dev, 0x01, 0, 0x0066, "\xd0\xff", 2); - reg_w(dev, 0x01, 0, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); - reg_w(dev, 0x01, 0, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); - reg_w(dev, 0x01, 0, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); - reg_w(dev, 0x01, 0, 0x008f, "\x18\x20", 2); - reg_w(dev, 0x01, 0, 0x0096, "\x01\x08\x04", 3); - reg_w(dev, 0x01, 0, 0x00a0, "\x44\x44\x44\x04", 4); - reg_w(dev, 0x01, 0, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); - reg_w(dev, 0x01, 0, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); + reg_w(dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); + reg_w(dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); + reg_w(dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); + reg_w(dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); + reg_w(dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); + reg_w(dev, 0x002a, "\x00\x00\x00", 3); + reg_w(dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); + reg_w(dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); + reg_w(dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); + reg_w(dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); + reg_w(dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); + reg_w(dev, 0x0066, "\xd0\xff", 2); + reg_w(dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); + reg_w(dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); + reg_w(dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); + reg_w(dev, 0x008f, "\x18\x20", 2); + reg_w(dev, 0x0096, "\x01\x08\x04", 3); + reg_w(dev, 0x00a0, "\x44\x44\x44\x04", 4); + reg_w(dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); + reg_w(dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); pac7311_reg_write(dev, 0xff, 0x04); pac7311_reg_write(dev, 0x02, 0x04); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 7850efa41096..4baac51bf40a 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -334,7 +334,7 @@ static void reg_r(struct usb_device *dev, static void reg_w(struct usb_device *dev, __u16 value, const __u8 *buffer, - __u16 len) + int len) { __u8 tmpbuf[32]; diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index e6a49fe2c4e3..4f23b16c89a8 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); @@ -515,15 +515,24 @@ static void reg_r(struct usb_device *dev, static void reg_w(struct usb_device *dev, __u16 value, - __u8 *buffer, + const __u8 *buffer, int len) { + __u8 tmpbuf[64]; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof tmpbuf) { + PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + return; + } +#endif + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, - buffer, len, + tmpbuf, len, 500); } diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index e72fca5744ac..1db5b33ad85e 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -377,7 +377,7 @@ static int reg_write(struct usb_device *dev, ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), req, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x, 0x%x", index, value, ret); diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 25c5245725d6..113c07106924 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -456,7 +456,7 @@ static int reg_write(struct usb_device *dev, ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), req, - USB_TYPE_VENDOR | USB_RECIP_DEVICE, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", req, index, value, ret); diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index c22b301ebae0..de43118dec7a 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -26,8 +26,8 @@ #define MODULE_NAME "t613" #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) +static const char version[] = "2.1.3"; struct control_menu_info { int value; @@ -366,13 +366,22 @@ static void t16RegRead(struct usb_device *dev, static void t16RegWrite(struct usb_device *dev, __u16 value, - __u16 index, __u8 *buffer, __u16 length) + __u16 index, __u8 *buffer, __u16 len) { + __u8 tmpbuf[70]; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof tmpbuf) { + PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + return; + } +#endif + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, buffer, length, 500); + value, index, tmpbuf, len, 500); } /* this function is called at probe time */ @@ -491,24 +500,24 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); t16RegWrite(dev, 0x00, 0x338e, 0x00, 0x0); - t16RegWrite(dev, 0x01, 00, nset5, 0x04); + t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04); t16RegWrite(dev, 0x00, 0x00a9, 0x00, 0x0); - t16RegWrite(dev, 0x01, 00, nset6, 0x22); + t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22); t16RegWrite(dev, 0x00, 0x86bb, 0x00, 0x0); t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x0); - t16RegWrite(dev, 0x01, 00, missing, 0x08); + t16RegWrite(dev, 0x01, 0x0000, missing, 0x08); t16RegWrite(dev, 0x00, 0x2087, 0x00, 0x0); t16RegWrite(dev, 0x00, 0x2088, 0x00, 0x0); t16RegWrite(dev, 0x00, 0x2089, 0x00, 0x0); - t16RegWrite(dev, 0x01, 00, nset7, 0x4); - t16RegWrite(dev, 0x01, 00, nset10, 0x06); - t16RegWrite(dev, 0x01, 00, nset8, 0x06); - t16RegWrite(dev, 0x01, 00, nset9, 0x04); + t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04); + t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06); + t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06); + t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04); - t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x00); t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 6218441ba1f0..6da5280b5433 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -192,8 +192,7 @@ static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) datacmd = 0xb0;; reg_w(dev, TV8532_GPIO, &datacmd, 1); datacmd = TV8532_CMD_EEprom_Open; - reg_w(dev, TV8532_CTRL, &datacmd, - 1); + reg_w(dev, TV8532_CTRL, &datacmd, 1); /* msleep(1); */ while (tv_8532_eeprom_data[i]) { reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; @@ -390,8 +389,7 @@ static int sd_open(struct gspca_dev *gspca_dev) tv_8532_setReg(gspca_dev); /*************************************************/ data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, - 1); + reg_w(dev, TV8532_GPIO_OE, &data, 1); /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ @@ -417,8 +415,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 data = 0; - __u8 dataStart = 0; + __u8 data; __u8 value[2]; data = 0x32; @@ -459,8 +456,8 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ data = TESTPTH; /* 0x04; */ reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ - dataStart = TESTPTBL; /* 0x04; */ - reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ + data = TESTPTBL; /* 0x04; */ + reg_w(dev, TV8532_POINTB_L, &data, 1); /* 0x2f */ data = TESTPTBH; /* 0x04; */ reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ data = TV8532_CMD_UPDATE; -- cgit v1.2.3 From 54ab92ca05550550bcec2462de2605f35d079b66 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 3 Jul 2008 11:20:58 -0300 Subject: V4L/DVB (8194): gspca: Fix the format of the low resolution mode of spca561. The low (half) res modes of the spca561 are not spca561 compressed, but are raw bayer, this patches fixes this and adds a PIX_FMT define for the GBRG bayer format used by the spca561 in low res mode. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/spca561.c | 6 +++--- include/linux/videodev2.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index a94e6270115e..dbd1648a655f 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -98,8 +98,8 @@ static struct ctrl sd_ctrls[] = { }; static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SPCA561, 160, 120, 3}, - {V4L2_PIX_FMT_SPCA561, 176, 144, 2}, + {V4L2_PIX_FMT_SGBRG8, 160, 120, 3}, + {V4L2_PIX_FMT_SGBRG8, 176, 144, 2}, {V4L2_PIX_FMT_SPCA561, 320, 240, 1}, {V4L2_PIX_FMT_SPCA561, 352, 288, 0}, }; @@ -808,7 +808,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); } else { - /*fixme: which format?*/ + /* raw bayer (with a header, which we skip) */ data += 20; len -= 20; gspca_frame_add(gspca_dev, FIRST_PACKET, diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 43a6c81a53ef..577f15634791 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -310,6 +310,7 @@ struct v4l2_pix_format /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B','A','8','1') /* 8 BGBG.. GRGR.. */ +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G','B','R','G') /* 8 GBGB.. RGRG.. */ #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B','Y','R','2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ -- cgit v1.2.3 From a5ae2062252e697d38e53dbbeb91460252208914 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 4 Jul 2008 11:16:16 -0300 Subject: V4L/DVB (8195): gspca: Input buffer overwritten in spca561 + cleanup code. spca561: Input buffer may be changed on reg write. (all sd): Cleanup code, 'const' added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 98 ++++--- drivers/media/video/gspca/etoms.c | 546 ++++++++++++++---------------------- drivers/media/video/gspca/gspca.c | 6 +- drivers/media/video/gspca/gspca.h | 26 +- drivers/media/video/gspca/mars.c | 13 +- drivers/media/video/gspca/ov519.c | 60 ++-- drivers/media/video/gspca/pac207.c | 14 +- drivers/media/video/gspca/pac7311.c | 40 +-- drivers/media/video/gspca/sonixj.c | 165 ++++++----- drivers/media/video/gspca/spca500.c | 301 ++++++++++---------- drivers/media/video/gspca/spca501.c | 27 +- drivers/media/video/gspca/spca505.c | 22 +- drivers/media/video/gspca/spca508.c | 22 +- drivers/media/video/gspca/spca561.c | 30 +- drivers/media/video/gspca/stk014.c | 36 +-- drivers/media/video/gspca/sunplus.c | 28 +- drivers/media/video/gspca/t613.c | 198 ++++++------- drivers/media/video/gspca/tv8532.c | 22 +- drivers/media/video/gspca/vc032x.c | 80 +++--- drivers/media/video/gspca/zc3xx.c | 246 ++++++++-------- 20 files changed, 932 insertions(+), 1048 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 473bea750b5f..6d50247b7ad2 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -25,8 +25,8 @@ #define CONEX_CAM 1 /* special JPEG header */ #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); @@ -229,7 +229,7 @@ static void cx11646_fw(struct gspca_dev*gspca_dev) reg_w(gspca_dev->dev, 0x006a, &val, 1); } -static __u8 cxsensor[] = { +static const __u8 cxsensor[] = { 0x88, 0x12, 0x70, 0x01, 0x88, 0x0d, 0x02, 0x01, 0x88, 0x0f, 0x00, 0x01, @@ -244,24 +244,24 @@ static __u8 cxsensor[] = { 0x00 }; -static __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; -static __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; -static __u8 reg10[] = { 0xb1, 0xb1 }; -static __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ -static __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; +static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff }; +static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff }; +static const __u8 reg10[] = { 0xb1, 0xb1 }; +static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */ +static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f }; /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */ -static __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; +static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 }; /* 320{0x04,0x0c,0x05,0x0f}; //320 */ -static __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ -static __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; +static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */ +static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; static void cx_sensor(struct gspca_dev*gspca_dev) { - __u8 val = 0; + __u8 val; int i = 0; __u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int length = 0; - __u8 *ptsensor = cxsensor; + int length; + const __u8 *ptsensor = cxsensor; reg_w(gspca_dev->dev, 0x0020, reg20, 8); reg_w(gspca_dev->dev, 0x0028, reg28, 8); @@ -305,7 +305,7 @@ static void cx_sensor(struct gspca_dev*gspca_dev) reg_r(gspca_dev->dev, 0x00e7, bufread, 8); } -static __u8 cx_inits_176[] = { +static const __u8 cx_inits_176[] = { 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */ 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03, 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30, @@ -314,7 +314,7 @@ static __u8 cx_inits_176[] = { 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static __u8 cx_inits_320[] = { +static const __u8 cx_inits_320[] = { 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01, 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81, @@ -323,7 +323,7 @@ static __u8 cx_inits_320[] = { 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02, 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static __u8 cx_inits_352[] = { +static const __u8 cx_inits_352[] = { 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03, 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b, 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25, @@ -332,7 +332,7 @@ static __u8 cx_inits_352[] = { 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02, 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static __u8 cx_inits_640[] = { +static const __u8 cx_inits_640[] = { 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01, 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01, 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81, @@ -344,7 +344,7 @@ static __u8 cx_inits_640[] = { static int cx11646_initsize(struct gspca_dev *gspca_dev) { - __u8 *cxinit; + const __u8 *cxinit; __u8 val; static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; static const __u8 reg17[] = @@ -396,7 +396,7 @@ static int cx11646_initsize(struct gspca_dev *gspca_dev) return val; } -static __u8 cx_jpeg_init[][8] = { +static const __u8 cx_jpeg_init[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */ {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11}, {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22}, @@ -479,7 +479,7 @@ static __u8 cx_jpeg_init[][8] = { }; -static __u8 cxjpeg_640[][8] = { +static const __u8 cxjpeg_640[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */ {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d}, {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a}, @@ -508,7 +508,7 @@ static __u8 cxjpeg_640[][8] = { {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ }; -static __u8 cxjpeg_352[][8] = { +static const __u8 cxjpeg_352[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a}, {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14}, @@ -537,7 +537,7 @@ static __u8 cxjpeg_352[][8] = { {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static __u8 cxjpeg_320[][8] = { +static const __u8 cxjpeg_320[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05}, {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04}, {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08}, @@ -566,7 +566,7 @@ static __u8 cxjpeg_320[][8] = { {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */ }; -static __u8 cxjpeg_176[][8] = { +static const __u8 cxjpeg_176[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d}, {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A}, {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14}, @@ -595,7 +595,8 @@ static __u8 cxjpeg_176[][8] = { {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00}, {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static __u8 cxjpeg_qtable[][8] = { /* 640 take with the zcx30x part */ +/* 640 take with the zcx30x part */ +static const __u8 cxjpeg_qtable[][8] = { {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08}, {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07}, {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a}, @@ -641,22 +642,23 @@ static void cx11646_jpegInit(struct gspca_dev*gspca_dev) reg_w(gspca_dev->dev, 0x0055, &val, 1); } -static __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; -static __u8 regE5_8[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; -static __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; -static __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; -static __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; -static __u8 reg51[] = { 0x77, 0x03 }; -static __u8 reg70 = 0x03; +static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; +static const __u8 regE5_8[] = + { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; +static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; +static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; +static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; +static const __u8 reg51[] = { 0x77, 0x03 }; +static const __u8 reg70 = 0x03; static void cx11646_jpeg(struct gspca_dev*gspca_dev) { __u8 val; int i; - int length = 8; - __u8 Reg55 = 0x14; - __u8 bufread[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int retry = 50; + int length; + __u8 Reg55; + __u8 bufread[8]; + int retry; val = 0x01; reg_w(gspca_dev->dev, 0x00c0, &val, 1); @@ -665,6 +667,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) val = 0x00; reg_w(gspca_dev->dev, 0x00c0, &val, 1); reg_r(gspca_dev->dev, 0x0001, &val, 1); + length = 8; switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { case 0: for (i = 0; i < 27; i++) { @@ -719,6 +722,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) val = 0x00; reg_w(gspca_dev->dev, 0x0000, &val, 1); /* wait for completion */ + retry = 50; while (retry--) { reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x07 until 0x00 */ @@ -796,8 +800,8 @@ static void cx11646_init1(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0x003f, &val, 1); val = 0x40; reg_w(gspca_dev->dev, 0x003d, &val, 1); -/* val= 0x60; */ -/* reg_w(gspca_dev->dev,0x00,0x00,0x003d,&val,1); */ +/* val= 0x60; */ +/* reg_w(gspca_dev->dev, 0x00, 0x00, 0x003d, &val, 1); */ reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */ while (cx_sensor_init[i][0]) { @@ -827,7 +831,7 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; - sd->qindex = 0; /* set the quantization table */ + sd->qindex = 0; /* set the quantization */ sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; @@ -891,7 +895,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { if (data[0] == 0xff && data[1] == 0xd8) { @@ -914,21 +918,22 @@ static void setbrightness(struct gspca_dev*gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 }; - __u8 reg51c[] = { 0x77, 0x03 }; + __u8 reg51c[2]; __u8 bright; __u8 colors; __u8 val; __u8 bufread[8]; bright = sd->brightness; - colors = sd->colors; regE5cbx[2] = bright; - reg51c[1] = colors; reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8); reg_r(gspca_dev->dev, 0x00e8, bufread, 8); reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + colors = sd->colors; + reg51c[0] = 0x77; + reg51c[1] = colors; reg_w(gspca_dev->dev, 0x0051, reg51c, 2); reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w(gspca_dev->dev, 0x0070, ®70, 1); @@ -938,14 +943,15 @@ static void setcontrast(struct gspca_dev*gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ - /* __u8 regE5bcx[]={0x88,0x0b,0x12,0x01}; // LSB */ - __u8 reg51c[] = { 0x77, 0x03 }; +/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ + __u8 reg51c[2]; __u8 val; - reg51c[1] = sd->colors; regE5acx[2] = sd->contrast; reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4); reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + reg51c[0] = 0x77; + reg51c[1] = sd->colors; reg_w(gspca_dev->dev, 0x0051, reg51c, 2); reg_w(gspca_dev->dev, 0x0010, reg10, 2); reg_w(gspca_dev->dev, 0x0070, ®70, 1); diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index ed7a8f9c0d7a..bbbe65923cfc 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("Etoms USB Camera Driver"); @@ -56,7 +56,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -65,12 +64,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 1, .maximum = 127, .step = 1, - .default_value = 63, +#define BRIGHTNESS_DEF 63 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -79,12 +78,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -93,12 +92,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 15, .step = 1, - .default_value = 7, +#define COLOR_DEF 7 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, -#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, @@ -107,7 +106,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, @@ -205,13 +205,13 @@ static struct cam_mode sif_mode[] = { #define PAS106_REG0e 0x0e /* global gain [4..0](default 0x0e) */ #define PAS106_REG13 0x13 /* end i2c write */ -static __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; +static const __u8 GainRGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; -static __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; +static const __u8 I2c2[] = { 0x08, 0x08, 0x08, 0x08, 0x0d }; -static __u8 I2c3[] = { 0x12, 0x05 }; +static const __u8 I2c3[] = { 0x12, 0x05 }; -static __u8 I2c4[] = { 0x41, 0x08 }; +static const __u8 I2c4[] = { 0x41, 0x08 }; static void reg_r(struct usb_device *dev, __u16 index, __u8 *buffer, int len) @@ -223,8 +223,21 @@ static void reg_r(struct usb_device *dev, 0, index, buffer, len, 500); } +static void reg_w_val(struct usb_device *dev, + __u16 index, __u8 val) +{ + __u8 data; + + data = val; + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0, index, &data, 1, 500); +} + static void reg_w(struct usb_device *dev, - __u16 index, __u8 *buffer, __u16 len) + __u16 index, const __u8 *buffer, __u16 len) { __u8 tmpbuf[8]; @@ -236,48 +249,42 @@ static void reg_w(struct usb_device *dev, 0, index, tmpbuf, len, 500); } -static int Et_i2cwrite(struct usb_device *dev, __u8 reg, __u8 *buffer, - __u16 length, __u8 mode) +static int Et_i2cwrite(struct usb_device *dev, __u8 reg, + const __u8 *buffer, + __u16 len, __u8 mode) { -/* buffer should be [D0..D7] */ - int i, j; - __u8 base = 0x40; /* sensor base for the pas106 */ - __u8 ptchcount = 0; - - ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); -/* set the base address */ - reg_w(dev, ET_I2C_BASE, &base, 1); -/* set count and prefetch */ - reg_w(dev, ET_I2C_COUNT, &ptchcount, 1); -/* set the register base */ - reg_w(dev, ET_I2C_REG, ®, 1); - j = length - 1; - for (i = 0; i < length; i++) { - reg_w(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); - j--; - } + /* buffer should be [D0..D7] */ + __u8 ptchcount; + + /* set the base address */ + reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ + /* set count and prefetch */ + ptchcount = ((len & 0x07) << 4) | (mode & 0x03); + reg_w_val(dev, ET_I2C_COUNT, ptchcount); + /* set the register base */ + reg_w_val(dev, ET_I2C_REG, reg); + while (--len >= 0) + reg_w_val(dev, ET_I2C_DATA0 + len, buffer[len]); return 0; } -static int Et_i2cread(struct usb_device *dev, __u8 reg, __u8 *buffer, - __u16 length, __u8 mode) +static int Et_i2cread(struct usb_device *dev, __u8 reg, + __u8 *buffer, + __u16 length, __u8 mode) { -/* buffer should be [D0..D7] */ + /* buffer should be [D0..D7] */ int i, j; - __u8 base = 0x40; /* sensor base for the pas106 */ __u8 ptchcount; - __u8 prefetch = 0x02; - - ptchcount = (((length & 0x07) << 4) | (mode & 0x03)); -/* set the base address */ - reg_w(dev, ET_I2C_BASE, &base, 1); -/* set count and prefetch */ - reg_w(dev, ET_I2C_COUNT, &ptchcount, 1); -/* set the register base */ - reg_w(dev, ET_I2C_REG, ®, 1); - reg_w(dev, ET_I2C_PREFETCH, &prefetch, 1); - prefetch = 0x00; - reg_w(dev, ET_I2C_PREFETCH, &prefetch, 1); + + /* set the base address */ + reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ + /* set count and prefetch */ + ptchcount = ((length & 0x07) << 4) | (mode & 0x03); + reg_w_val(dev, ET_I2C_COUNT, ptchcount); + /* set the register base */ + reg_w_val(dev, ET_I2C_REG, reg); + reg_w_val(dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ + reg_w_val(dev, ET_I2C_PREFETCH, 0); j = length - 1; for (i = 0; i < length; i++) { reg_r(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); @@ -299,222 +306,139 @@ static int Et_WaitStatus(struct usb_device *dev) return 0; } -static int Et_videoOff(struct usb_device *dev) +static int et_video(struct usb_device *dev, int on) { int err; - __u8 stopvideo = 0; - reg_w(dev, ET_GPIO_OUT, &stopvideo, 1); + reg_w_val(dev, ET_GPIO_OUT, on + ? 0x10 /* startvideo - set Bit5 */ + : 0); /* stopvideo */ err = Et_WaitStatus(dev); if (!err) - PDEBUG(D_ERR, "timeout Et_waitStatus VideoON"); - return err; -} - -static int Et_videoOn(struct usb_device *dev) -{ - int err; - __u8 startvideo = 0x10; /* set Bit5 */ - - reg_w(dev, ET_GPIO_OUT, &startvideo, 1); - err = Et_WaitStatus(dev); - if (!err) - PDEBUG(D_ERR, "timeout Et_waitStatus VideoOFF"); + PDEBUG(D_ERR, "timeout video on/off"); return err; } static void Et_init2(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 value = 0x00; - __u8 received = 0x00; - __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; + __u8 value; + __u8 received; + static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; PDEBUG(D_STREAM, "Open Init2 ET"); - value = 0x2f; - reg_w(dev, ET_GPIO_DIR_CTRL, &value, 1); - value = 0x10; - reg_w(dev, ET_GPIO_OUT, &value, 1); + reg_w_val(dev, ET_GPIO_DIR_CTRL, 0x2f); + reg_w_val(dev, ET_GPIO_OUT, 0x10); reg_r(dev, ET_GPIO_IN, &received, 1); - value = 0x14; /* 0x14 // 0x16 enabled pattern */ - reg_w(dev, ET_ClCK, &value, 1); - value = 0x1b; - reg_w(dev, ET_CTRL, &value, 1); + reg_w_val(dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ + reg_w_val(dev, ET_CTRL, 0x1b); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) value = ET_COMP_VAL1; /* 320 */ else value = ET_COMP_VAL0; /* 640 */ - reg_w(dev, ET_COMP, &value, 1); - value = 0x1f; - reg_w(dev, ET_MAXQt, &value, 1); - value = 0x04; - reg_w(dev, ET_MINQt, &value, 1); + reg_w_val(dev, ET_COMP, value); + reg_w_val(dev, ET_MAXQt, 0x1f); + reg_w_val(dev, ET_MINQt, 0x04); /* undocumented registers */ - value = 0xff; - reg_w(dev, ET_REG1d, &value, 1); - value = 0xff; - reg_w(dev, ET_REG1e, &value, 1); - value = 0xff; - reg_w(dev, ET_REG1f, &value, 1); - value = 0x35; - reg_w(dev, ET_REG20, &value, 1); - value = 0x01; - reg_w(dev, ET_REG21, &value, 1); - value = 0x00; - reg_w(dev, ET_REG22, &value, 1); - value = 0xff; - reg_w(dev, ET_REG23, &value, 1); - value = 0xff; - reg_w(dev, ET_REG24, &value, 1); - value = 0x0f; - reg_w(dev, ET_REG25, &value, 1); + reg_w_val(dev, ET_REG1d, 0xff); + reg_w_val(dev, ET_REG1e, 0xff); + reg_w_val(dev, ET_REG1f, 0xff); + reg_w_val(dev, ET_REG20, 0x35); + reg_w_val(dev, ET_REG21, 0x01); + reg_w_val(dev, ET_REG22, 0x00); + reg_w_val(dev, ET_REG23, 0xff); + reg_w_val(dev, ET_REG24, 0xff); + reg_w_val(dev, ET_REG25, 0x0f); /* colors setting */ - value = 0x11; - reg_w(dev, 0x30, &value, 1); /* 0x30 */ - value = 0x40; - reg_w(dev, 0x31, &value, 1); - value = 0x00; - reg_w(dev, 0x32, &value, 1); - value = 0x00; - reg_w(dev, ET_O_RED, &value, 1); /* 0x34 */ - value = 0x00; - reg_w(dev, ET_O_GREEN1, &value, 1); - value = 0x00; - reg_w(dev, ET_O_BLUE, &value, 1); - value = 0x00; - reg_w(dev, ET_O_GREEN2, &value, 1); + reg_w_val(dev, 0x30, 0x11); /* 0x30 */ + reg_w_val(dev, 0x31, 0x40); + reg_w_val(dev, 0x32, 0x00); + reg_w_val(dev, ET_O_RED, 0x00); /* 0x34 */ + reg_w_val(dev, ET_O_GREEN1, 0x00); + reg_w_val(dev, ET_O_BLUE, 0x00); + reg_w_val(dev, ET_O_GREEN2, 0x00); /*************/ - value = 0x80; - reg_w(dev, ET_G_RED, &value, 1); /* 0x4d */ - value = 0x80; - reg_w(dev, ET_G_GREEN1, &value, 1); - value = 0x80; - reg_w(dev, ET_G_BLUE, &value, 1); - value = 0x80; - reg_w(dev, ET_G_GREEN2, &value, 1); - value = 0x00; - reg_w(dev, ET_G_GR_H, &value, 1); - value = 0x00; - reg_w(dev, ET_G_GB_H, &value, 1); /* 0x52 */ + reg_w_val(dev, ET_G_RED, 0x80); /* 0x4d */ + reg_w_val(dev, ET_G_GREEN1, 0x80); + reg_w_val(dev, ET_G_BLUE, 0x80); + reg_w_val(dev, ET_G_GREEN2, 0x80); + reg_w_val(dev, ET_G_GR_H, 0x00); + reg_w_val(dev, ET_G_GB_H, 0x00); /* 0x52 */ /* Window control registers */ - - value = 0x80; /* use cmc_out */ - reg_w(dev, 0x61, &value, 1); - - value = 0x02; - reg_w(dev, 0x62, &value, 1); - value = 0x03; - reg_w(dev, 0x63, &value, 1); - value = 0x14; - reg_w(dev, 0x64, &value, 1); - value = 0x0e; - reg_w(dev, 0x65, &value, 1); - value = 0x02; - reg_w(dev, 0x66, &value, 1); - value = 0x02; - reg_w(dev, 0x67, &value, 1); + reg_w_val(dev, 0x61, 0x80); /* use cmc_out */ + reg_w_val(dev, 0x62, 0x02); + reg_w_val(dev, 0x63, 0x03); + reg_w_val(dev, 0x64, 0x14); + reg_w_val(dev, 0x65, 0x0e); + reg_w_val(dev, 0x66, 0x02); + reg_w_val(dev, 0x67, 0x02); /**************************************/ - value = 0x8f; - reg_w(dev, ET_SYNCHRO, &value, 1); /* 0x68 */ - value = 0x69; /* 0x6a //0x69 */ - reg_w(dev, ET_STARTX, &value, 1); - value = 0x0d; /* 0x0d //0x0c */ - reg_w(dev, ET_STARTY, &value, 1); - value = 0x80; - reg_w(dev, ET_WIDTH_LOW, &value, 1); - value = 0xe0; - reg_w(dev, ET_HEIGTH_LOW, &value, 1); - value = 0x60; - reg_w(dev, ET_W_H_HEIGTH, &value, 1); /* 6d */ - value = 0x86; - reg_w(dev, ET_REG6e, &value, 1); - value = 0x01; - reg_w(dev, ET_REG6f, &value, 1); - value = 0x26; - reg_w(dev, ET_REG70, &value, 1); - value = 0x7a; - reg_w(dev, ET_REG71, &value, 1); - value = 0x01; - reg_w(dev, ET_REG72, &value, 1); + reg_w_val(dev, ET_SYNCHRO, 0x8f); /* 0x68 */ + reg_w_val(dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ + reg_w_val(dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ + reg_w_val(dev, ET_WIDTH_LOW, 0x80); + reg_w_val(dev, ET_HEIGTH_LOW, 0xe0); + reg_w_val(dev, ET_W_H_HEIGTH, 0x60); /* 6d */ + reg_w_val(dev, ET_REG6e, 0x86); + reg_w_val(dev, ET_REG6f, 0x01); + reg_w_val(dev, ET_REG70, 0x26); + reg_w_val(dev, ET_REG71, 0x7a); + reg_w_val(dev, ET_REG72, 0x01); /* Clock Pattern registers ***************** */ - value = 0x00; - reg_w(dev, ET_REG73, &value, 1); - value = 0x18; /* 0x28 */ - reg_w(dev, ET_REG74, &value, 1); - value = 0x0f; /* 0x01 */ - reg_w(dev, ET_REG75, &value, 1); + reg_w_val(dev, ET_REG73, 0x00); + reg_w_val(dev, ET_REG74, 0x18); /* 0x28 */ + reg_w_val(dev, ET_REG75, 0x0f); /* 0x01 */ /**********************************************/ - value = 0x20; - reg_w(dev, 0x8a, &value, 1); - value = 0x0f; - reg_w(dev, 0x8d, &value, 1); - value = 0x08; - reg_w(dev, 0x8e, &value, 1); + reg_w_val(dev, 0x8a, 0x20); + reg_w_val(dev, 0x8d, 0x0f); + reg_w_val(dev, 0x8e, 0x08); /**************************************/ - value = 0x08; - reg_w(dev, 0x03, &value, 1); - value = 0x03; - reg_w(dev, ET_PXL_CLK, &value, 1); - value = 0xff; - reg_w(dev, 0x81, &value, 1); - value = 0x00; - reg_w(dev, 0x80, &value, 1); - value = 0xff; - reg_w(dev, 0x81, &value, 1); - value = 0x20; - reg_w(dev, 0x80, &value, 1); - value = 0x01; - reg_w(dev, 0x03, &value, 1); - value = 0x00; - reg_w(dev, 0x03, &value, 1); - value = 0x08; - reg_w(dev, 0x03, &value, 1); + reg_w_val(dev, 0x03, 0x08); + reg_w_val(dev, ET_PXL_CLK, 0x03); + reg_w_val(dev, 0x81, 0xff); + reg_w_val(dev, 0x80, 0x00); + reg_w_val(dev, 0x81, 0xff); + reg_w_val(dev, 0x80, 0x20); + reg_w_val(dev, 0x03, 0x01); + reg_w_val(dev, 0x03, 0x00); + reg_w_val(dev, 0x03, 0x08); /********************************************/ - /* reg_r(dev,0x0,ET_I2C_BASE,&received,1); +/* reg_r(dev, ET_I2C_BASE, &received, 1); always 0x40 as the pas106 ??? */ /* set the sensor */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { - value = 0x04; /* 320 */ - reg_w(dev, ET_PXL_CLK, &value, 1); - /* now set by fifo the FormatLine setting */ - reg_w(dev, 0x62, FormLine, 6); - } else { /* 640 */ - /* setting PixelClock - 0x03 mean 24/(3+1) = 6 Mhz - 0x05 -> 24/(5+1) = 4 Mhz - 0x0b -> 24/(11+1) = 2 Mhz - 0x17 -> 24/(23+1) = 1 Mhz - */ - value = 0x1e; /* 0x17 */ - reg_w(dev, ET_PXL_CLK, &value, 1); - /* now set by fifo the FormatLine setting */ - reg_w(dev, 0x62, FormLine, 6); - } + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + value = 0x04; /* 320 */ + else /* 640 */ + value = 0x1e; /* 0x17 * setting PixelClock + * 0x03 mean 24/(3+1) = 6 Mhz + * 0x05 -> 24/(5+1) = 4 Mhz + * 0x0b -> 24/(11+1) = 2 Mhz + * 0x17 -> 24/(23+1) = 1 Mhz + */ + reg_w_val(dev, ET_PXL_CLK, value); + /* now set by fifo the FormatLine setting */ + reg_w(dev, 0x62, FormLine, 6); /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ - value = 0x47; /* 0x47; */ - reg_w(dev, 0x81, &value, 1); - value = 0x40; /* 0x40; */ - reg_w(dev, 0x80, &value, 1); + reg_w_val(dev, 0x81, 0x47); /* 0x47; */ + reg_w_val(dev, 0x80, 0x40); /* 0x40; */ /* Pedro change */ /* Brightness change Brith+ decrease value */ /* Brigth- increase value */ /* original value = 0x70; */ - value = 0x30; /* 0x20; */ - reg_w(dev, 0x81, &value, 1); /* set brightness */ - value = 0x20; /* 0x20; */ - reg_w(dev, 0x80, &value, 1); + reg_w_val(dev, 0x81, 0x30); /* 0x20; - set brightness */ + reg_w_val(dev, 0x80, 0x20); /* 0x20; */ } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - static __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; + __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; __u8 i2cflags = 0x01; /* __u8 green = 0; */ __u8 colors = sd->colors; @@ -525,7 +449,7 @@ static void setcolors(struct gspca_dev *gspca_dev) /* I2cc[1] = I2cc[2] = green; */ if (sd->sensor == SENSOR_PAS106) { Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); - Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof(I2cc), 1); + Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof I2cc, 1); } /* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", I2cc[3], I2cc[0], green); */ @@ -534,11 +458,11 @@ static void setcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - /* __u8 valblue = 0; */ +/* __u8 valblue; */ __u8 valred; if (sd->sensor == SENSOR_PAS106) { - /* Et_i2cread(gspca_dev->dev,PAS106_REG9,&valblue,1,1); */ +/* Et_i2cread(gspca_dev->dev, PAS106_REG9, &valblue, 1, 1); */ Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1); sd->colors = valred & 0x0f; } @@ -547,126 +471,87 @@ static void getcolors(struct gspca_dev *gspca_dev) static void Et_init1(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 value = 0x00; - __u8 received = 0x00; -/* __u8 I2c0 [] ={0x0a,0x12,0x05,0x22,0xac,0x00,0x01,0x00}; */ + __u8 value; + __u8 received; +/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; /* try 1/120 0x6d 0xcd 0x40 */ -/* __u8 I2c0 [] ={0x0a,0x12,0x05,0xfe,0xfe,0xc0,0x01,0x00}; +/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00}; * 1/60000 hmm ?? */ PDEBUG(D_STREAM, "Open Init1 ET"); - value = 7; - reg_w(dev, ET_GPIO_DIR_CTRL, &value, 1); + reg_w_val(dev, ET_GPIO_DIR_CTRL, 7); reg_r(dev, ET_GPIO_IN, &received, 1); - value = 1; - reg_w(dev, ET_RESET_ALL, &value, 1); - value = 0; - reg_w(dev, ET_RESET_ALL, &value, 1); - value = 0x10; - reg_w(dev, ET_ClCK, &value, 1); - value = 0x19; - reg_w(dev, ET_CTRL, &value, 1); + reg_w_val(dev, ET_RESET_ALL, 1); + reg_w_val(dev, ET_RESET_ALL, 0); + reg_w_val(dev, ET_ClCK, 0x10); + reg_w_val(dev, ET_CTRL, 0x19); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) value = ET_COMP_VAL1; else value = ET_COMP_VAL0; - PDEBUG(D_STREAM, "Open mode %d Compression %d", gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode, value); - reg_w(dev, ET_COMP, &value, 1); - value = 0x1d; - reg_w(dev, ET_MAXQt, &value, 1); - value = 0x02; - reg_w(dev, ET_MINQt, &value, 1); + reg_w_val(dev, ET_COMP, value); + reg_w_val(dev, ET_MAXQt, 0x1d); + reg_w_val(dev, ET_MINQt, 0x02); /* undocumented registers */ - value = 0xff; - reg_w(dev, ET_REG1d, &value, 1); - value = 0xff; - reg_w(dev, ET_REG1e, &value, 1); - value = 0xff; - reg_w(dev, ET_REG1f, &value, 1); - value = 0x35; - reg_w(dev, ET_REG20, &value, 1); - value = 0x01; - reg_w(dev, ET_REG21, &value, 1); - value = 0x00; - reg_w(dev, ET_REG22, &value, 1); - value = 0xf7; - reg_w(dev, ET_REG23, &value, 1); - value = 0xff; - reg_w(dev, ET_REG24, &value, 1); - value = 0x07; - reg_w(dev, ET_REG25, &value, 1); + reg_w_val(dev, ET_REG1d, 0xff); + reg_w_val(dev, ET_REG1e, 0xff); + reg_w_val(dev, ET_REG1f, 0xff); + reg_w_val(dev, ET_REG20, 0x35); + reg_w_val(dev, ET_REG21, 0x01); + reg_w_val(dev, ET_REG22, 0x00); + reg_w_val(dev, ET_REG23, 0xf7); + reg_w_val(dev, ET_REG24, 0xff); + reg_w_val(dev, ET_REG25, 0x07); /* colors setting */ - value = 0x80; - reg_w(dev, ET_G_RED, &value, 1); - value = 0x80; - reg_w(dev, ET_G_GREEN1, &value, 1); - value = 0x80; - reg_w(dev, ET_G_BLUE, &value, 1); - value = 0x80; - reg_w(dev, ET_G_GREEN2, &value, 1); - value = 0x00; - reg_w(dev, ET_G_GR_H, &value, 1); - value = 0x00; - reg_w(dev, ET_G_GB_H, &value, 1); + reg_w_val(dev, ET_G_RED, 0x80); + reg_w_val(dev, ET_G_GREEN1, 0x80); + reg_w_val(dev, ET_G_BLUE, 0x80); + reg_w_val(dev, ET_G_GREEN2, 0x80); + reg_w_val(dev, ET_G_GR_H, 0x00); + reg_w_val(dev, ET_G_GB_H, 0x00); /* Window control registers */ - value = 0xf0; - reg_w(dev, ET_SYNCHRO, &value, 1); - value = 0x56; /* 0x56 */ - reg_w(dev, ET_STARTX, &value, 1); - value = 0x05; /* 0x04 */ - reg_w(dev, ET_STARTY, &value, 1); - value = 0x60; - reg_w(dev, ET_WIDTH_LOW, &value, 1); - value = 0x20; - reg_w(dev, ET_HEIGTH_LOW, &value, 1); - value = 0x50; - reg_w(dev, ET_W_H_HEIGTH, &value, 1); - value = 0x86; - reg_w(dev, ET_REG6e, &value, 1); - value = 0x01; - reg_w(dev, ET_REG6f, &value, 1); - value = 0x86; - reg_w(dev, ET_REG70, &value, 1); - value = 0x14; - reg_w(dev, ET_REG71, &value, 1); - value = 0x00; - reg_w(dev, ET_REG72, &value, 1); + reg_w_val(dev, ET_SYNCHRO, 0xf0); + reg_w_val(dev, ET_STARTX, 0x56); /* 0x56 */ + reg_w_val(dev, ET_STARTY, 0x05); /* 0x04 */ + reg_w_val(dev, ET_WIDTH_LOW, 0x60); + reg_w_val(dev, ET_HEIGTH_LOW, 0x20); + reg_w_val(dev, ET_W_H_HEIGTH, 0x50); + reg_w_val(dev, ET_REG6e, 0x86); + reg_w_val(dev, ET_REG6f, 0x01); + reg_w_val(dev, ET_REG70, 0x86); + reg_w_val(dev, ET_REG71, 0x14); + reg_w_val(dev, ET_REG72, 0x00); /* Clock Pattern registers */ - value = 0x00; - reg_w(dev, ET_REG73, &value, 1); - value = 0x00; - reg_w(dev, ET_REG74, &value, 1); - value = 0x0a; - reg_w(dev, ET_REG75, &value, 1); - value = 0x04; - reg_w(dev, ET_I2C_CLK, &value, 1); - value = 0x01; - reg_w(dev, ET_PXL_CLK, &value, 1); + reg_w_val(dev, ET_REG73, 0x00); + reg_w_val(dev, ET_REG74, 0x00); + reg_w_val(dev, ET_REG75, 0x0a); + reg_w_val(dev, ET_I2C_CLK, 0x04); + reg_w_val(dev, ET_PXL_CLK, 0x01); /* set the sensor */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { I2c0[0] = 0x06; - Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); - Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); + Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); + Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); value = 0x06; Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); - Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); + Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1); /* value = 0x1f; */ value = 0x04; Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); } else { I2c0[0] = 0x0a; - Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof(I2c0), 1); - Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof(I2c2), 1); + Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); + Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); value = 0x0a; Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); - Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof(I2c3), 1); + Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1); value = 0x04; /* value = 0x10; */ Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); @@ -720,10 +605,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; } - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; + sd->autogain = AUTOGAIN_DEF; return 0; } @@ -732,18 +617,13 @@ static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - int err; - __u8 value; - PDEBUG(D_STREAM, "Initialize ET1"); if (sd->sensor == SENSOR_PAS106) Et_init1(gspca_dev); else Et_init2(gspca_dev); - value = 0x08; - reg_w(dev, ET_RESET_ALL, &value, 1); - err = Et_videoOff(dev); - PDEBUG(D_STREAM, "Et_Init_VideoOff %d", err); + reg_w_val(dev, ET_RESET_ALL, 0x08); + et_video(dev, 0); /* video off */ return 0; } @@ -752,27 +632,19 @@ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - int err; - __u8 value; if (sd->sensor == SENSOR_PAS106) Et_init1(gspca_dev); else Et_init2(gspca_dev); - value = 0x08; - reg_w(dev, ET_RESET_ALL, &value, 1); - err = Et_videoOn(dev); - PDEBUG(D_STREAM, "Et_VideoOn %d", err); + reg_w_val(dev, ET_RESET_ALL, 0x08); + et_video(dev, 1); /* video on */ } static void sd_stopN(struct gspca_dev *gspca_dev) { - int err; - - err = Et_videoOff(gspca_dev->dev); - PDEBUG(D_STREAM, "Et_VideoOff %d", err); - + et_video(gspca_dev->dev, 0); /* video off */ } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -790,7 +662,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 brightness = sd->brightness; for (i = 0; i < 4; i++) - reg_w(gspca_dev->dev, (ET_O_RED + i), &brightness, 1); + reg_w_val(gspca_dev->dev, (ET_O_RED + i), brightness); } static void getbrightness(struct gspca_dev *gspca_dev) @@ -798,7 +670,7 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; int brightness = 0; - __u8 value = 0; + __u8 value; for (i = 0; i < 4; i++) { reg_r(gspca_dev->dev, (ET_O_RED + i), &value, 1); @@ -895,7 +767,7 @@ static void setautogain(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index b36913017d7b..ad4721b06920 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -247,7 +247,7 @@ static void isoc_transfer(struct gspca_dev *gspca_dev) struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, struct gspca_frame *frame, - __u8 *data, + const __u8 *data, int len) { int i, j; @@ -1053,7 +1053,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct gspca_dev *gspca_dev = priv; - struct ctrl *ctrls; + const struct ctrl *ctrls; int i, ret; for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; @@ -1079,7 +1079,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, { struct gspca_dev *gspca_dev = priv; - struct ctrl *ctrls; + const struct ctrl *ctrls; int i, ret; for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 9c894daf356a..0d23e0a90c77 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -9,25 +9,6 @@ #include #include -/* values in 2.6.27 */ -#ifndef V4L2_PIX_FMT_SPCA501 -#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') -#endif -#ifndef V4L2_PIX_FMT_SPCA561 -#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') -#endif - -/* values in 2.6.26 */ -#ifndef V4L2_CID_POWER_LINE_FREQUENCY -#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) -#endif -#ifndef V4L2_CID_WHITE_BALANCE_TEMPERATURE -#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE + 26) -#endif -#ifndef V4L2_CID_SHARPNESS -#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27) -#endif - #ifdef CONFIG_VIDEO_ADV_DEBUG /* GSPCA our debug messages */ extern int gspca_debug; @@ -76,7 +57,6 @@ struct cam_mode { short width; short height; short mode; /* subdriver value */ - short reserved; /* subdriver value */ }; struct cam { char *dev_name; @@ -110,9 +90,9 @@ struct ctrl { /* subdriver description */ struct sd_desc { /* information */ - char *name; /* sub-driver name */ + const char *name; /* sub-driver name */ /* controls */ - struct ctrl *ctrls; + const struct ctrl *ctrls; int nctrls; /* operations */ cam_cf_op config; /* called on probe */ @@ -195,6 +175,6 @@ void gspca_disconnect(struct usb_interface *intf); struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, int packet_type, struct gspca_frame *frame, - __u8 *data, + const __u8 *data, int len); #endif /* GSPCAV2_H */ diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 6556e0a330fa..c70ccc8fe68b 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); @@ -140,7 +140,8 @@ static void sd_start(struct gspca_dev *gspca_dev) __u16 MI_buf[242]; int h_size, v_size; int intpipe; - /* struct usb_device *dev = pcam->dev; */ +/* struct usb_device *dev = pcam->dev; */ + memset(data, 0, sizeof data); memset(MI_buf, 0, sizeof MI_buf); @@ -351,7 +352,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -389,7 +390,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -404,7 +405,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, {} }; diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 7d6237f18ba0..d92729ac41f0 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("OV519 USB Camera Driver"); @@ -266,15 +266,15 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) static int reg_w(struct sd *sd, __u16 index, __u8 value) { int ret; - __u8 buf[4]; + __u8 data; - buf[0] = value; + data = value; ret = usb_control_msg(sd->gspca_dev.dev, usb_sndctrlpipe(sd->gspca_dev.dev, 0), 1, /* REQ_IO (ov518/519) */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, - &buf[0], 1, 500); + &data, 1, 500); if (ret < 0) PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); return ret; @@ -285,16 +285,16 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) static int reg_r(struct sd *sd, __u16 index) { int ret; - __u8 buf[4]; + __u8 data; ret = usb_control_msg(sd->gspca_dev.dev, usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1, /* REQ_IO */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, &buf[0], 1, 500); + 0, index, &data, 1, 500); if (ret >= 0) - ret = buf[0]; + ret = data; else PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); return ret; @@ -302,7 +302,7 @@ static int reg_r(struct sd *sd, __u16 index) /* Read 8 values from a OV519 register */ static int reg_r8(struct sd *sd, - __u16 index) + __u16 index) { int ret; __u8 buf[8]; @@ -528,7 +528,7 @@ struct ov_i2c_regvals { }; static int write_regvals(struct sd *sd, - struct ov_regvals *regvals, + const struct ov_regvals *regvals, int n) { int rc; @@ -543,7 +543,7 @@ static int write_regvals(struct sd *sd, } static int write_i2c_regvals(struct sd *sd, - struct ov_i2c_regvals *regvals, + const struct ov_i2c_regvals *regvals, int n) { int rc; @@ -569,7 +569,7 @@ static int write_i2c_regvals(struct sd *sd, static int ov8xx0_configure(struct sd *sd) { int rc; - static struct ov_i2c_regvals norm_8610[] = { + static const struct ov_i2c_regvals norm_8610[] = { { 0x12, 0x80 }, { 0x00, 0x00 }, { 0x01, 0x80 }, @@ -707,7 +707,7 @@ static int ov7xx0_configure(struct sd *sd) * 0x05 (old driver setting): very overexposed, too much * contrast */ - static struct ov_i2c_regvals norm_7610[] = { + static const struct ov_i2c_regvals norm_7610[] = { { 0x10, 0xff }, { 0x16, 0x06 }, { 0x28, 0x24 }, @@ -737,7 +737,7 @@ static int ov7xx0_configure(struct sd *sd) { 0x0d, 0x24 }, }; - static struct ov_i2c_regvals norm_7620[] = { + static const struct ov_i2c_regvals norm_7620[] = { { 0x00, 0x00 }, /* gain */ { 0x01, 0x80 }, /* blue gain */ { 0x02, 0x80 }, /* red gain */ @@ -804,14 +804,14 @@ static int ov7xx0_configure(struct sd *sd) }; /* 7640 and 7648. The defaults should be OK for most registers. */ - static struct ov_i2c_regvals norm_7640[] = { + static const struct ov_i2c_regvals norm_7640[] = { { 0x12, 0x80 }, { 0x12, 0x14 }, }; /* 7670. Defaults taken from OmniVision provided data, * as provided by Jonathan Corbet of OLPC */ - static struct ov_i2c_regvals norm_7670[] = { + static const struct ov_i2c_regvals norm_7670[] = { { OV7670_REG_COM7, OV7670_COM7_RESET }, { OV7670_REG_TSLB, 0x04 }, /* OV */ { OV7670_REG_COM7, OV7670_COM7_FMT_VGA }, /* VGA */ @@ -1075,7 +1075,7 @@ static int ov7xx0_configure(struct sd *sd) static int ov6xx0_configure(struct sd *sd) { int rc; - static struct ov_i2c_regvals norm_6x20[] = { + static const struct ov_i2c_regvals norm_6x20[] = { { 0x12, 0x80 }, /* reset */ { 0x11, 0x01 }, { 0x03, 0x60 }, @@ -1118,7 +1118,7 @@ static int ov6xx0_configure(struct sd *sd) /* Toggle 0x12[2] off and on here? */ }; - static struct ov_i2c_regvals norm_6x30[] = { + static const struct ov_i2c_regvals norm_6x30[] = { { 0x12, 0x80 }, /* Reset */ { 0x00, 0x1f }, /* Gain */ { 0x01, 0x99 }, /* Blue gain */ @@ -1284,7 +1284,7 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; /* (from ov519_configure) */ - static struct ov_regvals init_519[] = { + static const struct ov_regvals init_519[] = { { 0x5a, 0x6d }, /* EnableSystem */ /* jfm trace usbsnoop3-1.txt */ /* jfm 53 = fb */ @@ -1302,8 +1302,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* windows reads 0x55 at this point*/ }; - if (write_regvals(sd, init_519, - sizeof init_519 / sizeof init_519[0])) + if (write_regvals(sd, init_519, ARRAY_SIZE(init_519))) goto error; /* jfm: not seen in windows trace */ if (ov519_init_compression(sd)) @@ -1389,7 +1388,7 @@ static int sd_open(struct gspca_dev *gspca_dev) static int ov519_mode_init_regs(struct sd *sd, int width, int height) { - static struct ov_regvals mode_init_519_ov7670[] = { + static const struct ov_regvals mode_init_519_ov7670[] = { { 0x5d, 0x03 }, /* Turn off suspend mode */ { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ { 0x54, 0x0f }, /* bit2 (jpeg enable) */ @@ -1412,7 +1411,7 @@ static int ov519_mode_init_regs(struct sd *sd, /* windows reads 0x55 at this point, why? */ }; - static struct ov_regvals mode_init_519[] = { + static const struct ov_regvals mode_init_519[] = { { 0x5d, 0x03 }, /* Turn off suspend mode */ { 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ { 0x54, 0x0f }, /* bit2 (jpeg enable) */ @@ -1448,12 +1447,11 @@ static int ov519_mode_init_regs(struct sd *sd, /******** Set the mode ********/ if (sd->sensor != SEN_OV7670) { if (write_regvals(sd, mode_init_519, - sizeof mode_init_519 / sizeof mode_init_519[0])) + ARRAY_SIZE(mode_init_519))) return -EIO; } else { if (write_regvals(sd, mode_init_519_ov7670, - sizeof mode_init_519_ov7670 - / sizeof mode_init_519_ov7670[0])) + ARRAY_SIZE(mode_init_519_ov7670))) return -EIO; } @@ -1883,7 +1881,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { /* Header of ov519 is 16 bytes: @@ -1982,7 +1980,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) case SEN_OV6630: i2c_w_mask(sd, OV7610_REG_CNT, val >> 4, 0x0f); case SEN_OV8610: { - static __u8 ctab[] = { + static const __u8 ctab[] = { 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f }; @@ -1991,7 +1989,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) break; } case SEN_OV7620: { - static __u8 ctab[] = { + static const __u8 ctab[] = { 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff }; @@ -2104,7 +2102,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -2119,7 +2117,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 84986684c4db..7e067456e62b 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -716,7 +716,7 @@ static int pac207_decode_frame_data(struct gspca_dev *gspca_dev, static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, - unsigned char *data, + __u8 *data, int len) { unsigned char *sof; @@ -754,8 +754,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, n = pac207_decode_frame_data(gspca_dev, frame, data, len); if (n) - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, NULL, 0); + gspca_frame_add(gspca_dev, LAST_PACKET, + frame, NULL, 0); } static void setbrightness(struct gspca_dev *gspca_dev) @@ -879,7 +879,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -895,7 +895,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")}, {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 14cc49a4c2cc..c2d4b6a4dcf4 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); @@ -37,7 +37,6 @@ struct sd { int avg_lum; unsigned char brightness; -#define BRIGHTNESS_MAX 0x20 unsigned char contrast; unsigned char colors; unsigned char autogain; @@ -58,21 +57,21 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, +#define BRIGHTNESS_MAX 0x20 .maximum = BRIGHTNESS_MAX, .step = 1, - .default_value = 0x10, +#define BRIGHTNESS_DEF 0x10 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -81,12 +80,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -95,12 +94,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define COLOR_DEF 127 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, -#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, @@ -109,7 +108,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, @@ -124,7 +124,7 @@ static struct cam_mode vga_mode[] = { #define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ -const unsigned char pac7311_jpeg_header[] = { +static const __u8 pac7311_jpeg_header[] = { 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x03, 0x20, 0xff, 0xc0, 0x00, 0x11, 0x08, @@ -195,8 +195,8 @@ const unsigned char pac7311_jpeg_header[] = { }; static void reg_w(struct usb_device *dev, - __u16 index, - char *buffer, __u16 len) + __u16 index, + const char *buffer, __u16 len) { __u8 tmpbuf[8]; @@ -263,10 +263,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; + sd->autogain = AUTOGAIN_DEF; return 0; } @@ -278,7 +278,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*jfm: inverted?*/ brightness = BRIGHTNESS_MAX - sd->brightness; pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); - /* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ +/* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ pac7311_reg_write(gspca_dev->dev, 0x0f, brightness); /* load registers to sensor (Bit 0, auto clear) */ pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); @@ -502,7 +502,7 @@ static void setautogain(struct gspca_dev *gspca_dev, int luma) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4f23b16c89a8..eb5e1bfd7911 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); @@ -74,7 +74,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -83,12 +82,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 0xffff, .step = 1, - .default_value = 0x7fff, +#define BRIGHTNESS_DEF 0x7fff + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -97,12 +96,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 127, .step = 1, - .default_value = 63, +#define CONTRAST_DEF 63 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -111,12 +110,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define COLOR_DEF 127 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, -#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, @@ -125,7 +124,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, @@ -139,7 +139,7 @@ static struct cam_mode vga_mode[] = { }; /*Data from sn9c102p+hv71331r */ -static __u8 sn_hv7131[] = { +static const __u8 sn_hv7131[] = { 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ @@ -150,7 +150,7 @@ static __u8 sn_hv7131[] = { /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ }; -static __u8 sn_mi0360[] = { +static const __u8 sn_mi0360[] = { 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, @@ -161,7 +161,7 @@ static __u8 sn_mi0360[] = { /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ }; -static __u8 sn_mo4000[] = { +static const __u8 sn_mo4000[] = { 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, @@ -174,13 +174,13 @@ static __u8 sn_mo4000[] = { 0xd3, 0xdf, 0xea, 0xf5 }; -static __u8 sn_ov7648[] = { +static const __u8 sn_ov7648[] = { 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static __u8 sn_ov7660[] = { +static const __u8 sn_ov7660[] = { /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81, /* reg9 rega regb regc regd rege regf reg10 reg11*/ @@ -192,7 +192,7 @@ static __u8 sn_ov7660[] = { }; /* sequence specific to the sensors - !! index = SENSOR_xxx */ -static __u8 *sn_tb[] = { +static const __u8 *sn_tb[] = { sn_hv7131, sn_mi0360, sn_mo4000, @@ -200,28 +200,28 @@ static __u8 *sn_tb[] = { sn_ov7660 }; -static __u8 regsn20[] = { +static const __u8 regsn20[] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; -static __u8 regsn20_sn9c325[] = { +static const __u8 regsn20_sn9c325[] = { 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 }; -static __u8 reg84[] = { +static const __u8 reg84[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f, 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f, /* 0x00, 0x00, 0x00, 0x00, 0x00 */ 0xf7, 0x0f, 0x0a, 0x00, 0x00 }; -static __u8 reg84_sn9c325[] = { +static const __u8 reg84_sn9c325[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, 0xf8, 0x0f, 0x00, 0x00, 0x00 }; -static __u8 hv7131r_sensor_init[][8] = { +static const __u8 hv7131r_sensor_init[][8] = { {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10}, {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10}, {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10}, @@ -250,9 +250,9 @@ static __u8 hv7131r_sensor_init[][8] = { {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10}, {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10}, - {0, 0, 0, 0, 0, 0, 0, 0} + {} }; -static __u8 mi0360_sensor_init[][8] = { +static const __u8 mi0360_sensor_init[][8] = { {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10}, {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -304,9 +304,9 @@ static __u8 mi0360_sensor_init[][8] = { /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */ {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */ {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */ - {0, 0, 0, 0, 0, 0, 0, 0} + {} }; -static __u8 mo4000_sensor_init[][8] = { +static const __u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}, @@ -327,9 +327,9 @@ static __u8 mo4000_sensor_init[][8] = { {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10}, - {0, 0, 0, 0, 0, 0, 0, 0} + {} }; -static __u8 ov7660_sensor_init[][8] = { +static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, /* Outformat ?? rawRGB */ @@ -420,12 +420,12 @@ static __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10}, /* here may start the isoc exchanges */ - {0, 0, 0, 0, 0, 0, 0, 0} + {} }; /* reg0x04 reg0x07 reg 0x10 */ /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */ -static __u8 ov7648_sensor_init[][8] = { +static const __u8 ov7648_sensor_init[][8] = { {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00}, @@ -478,10 +478,10 @@ static __u8 ov7648_sensor_init[][8] = { {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */ {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/ /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */ - {0, 0, 0, 0, 0, 0, 0, 0} + {} }; -static __u8 qtable4[] = { +static const __u8 qtable4[] = { 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0A, 0x11, 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15, @@ -518,27 +518,36 @@ static void reg_w(struct usb_device *dev, const __u8 *buffer, int len) { - __u8 tmpbuf[64]; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - if (len > sizeof tmpbuf) { - PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); - return; + if (len < 16) { + __u8 tmpbuf[16]; + + memcpy(tmpbuf, buffer, len); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, 0, + tmpbuf, len, + 500); + } else { + __u8 *tmpbuf; + + tmpbuf = kmalloc(len, GFP_KERNEL); + memcpy(tmpbuf, buffer, len); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, 0, + tmpbuf, len, + 500); + kfree(tmpbuf); } -#endif - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0x08, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - value, 0, - tmpbuf, len, - 500); } /* write 2 bytes */ static void i2c_w2(struct gspca_dev *gspca_dev, - __u8 *buffer) + const __u8 *buffer) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; @@ -557,7 +566,7 @@ static void i2c_w2(struct gspca_dev *gspca_dev, } /* write 8 bytes */ -static void i2c_w8(struct usb_device *dev, __u8 *buffer) +static void i2c_w8(struct usb_device *dev, const __u8 *buffer) { reg_w(dev, 0x08, buffer, 8); msleep(1); @@ -565,7 +574,7 @@ static void i2c_w8(struct usb_device *dev, __u8 *buffer) /* read 5 bytes */ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, - __u8 *buffer) + __u8 *buffer) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; @@ -591,7 +600,7 @@ static int probesensor(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; __u8 reg02; - static __u8 datasend[] = { 2, 0 }; + static const __u8 datasend[] = { 2, 0 }; /* reg val1 val2 val3 val4 */ __u8 datarecd[6]; @@ -618,18 +627,18 @@ static int probesensor(struct gspca_dev *gspca_dev) } static int configure_gpio(struct gspca_dev *gspca_dev, - __u8 *sn9c1xx) + const __u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; __u8 data; __u8 regF1; - __u8 *reg9a; - static __u8 reg9a_def[] = + const __u8 *reg9a; + static const __u8 reg9a_def[] = {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; - static __u8 reg9a_sn9c120[] = /* from win trace */ + static const __u8 reg9a_sn9c120[] = /* from win trace */ {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; - static __u8 reg9a_sn9c325[] = + static const __u8 reg9a_sn9c325[] = {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; @@ -697,7 +706,7 @@ static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; struct usb_device *dev = gspca_dev->dev; - static __u8 SetSensorClk[] = /* 0x08 Mclk */ + static const __u8 SetSensorClk[] = /* 0x08 Mclk */ { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; while (hv7131r_sensor_init[i][0]) { @@ -971,11 +980,12 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + sd->qindex = 4; /* set the quantization table */ - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; + sd->autogain = AUTOGAIN_DEF; return 0; } @@ -984,7 +994,7 @@ static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; -/* __u8 *sn9c1xx; */ +/* const __u8 *sn9c1xx; */ __u8 regF1; __u8 regGpio[] = { 0x29, 0x74 }; @@ -1036,11 +1046,11 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, unsigned int expo) { struct sd *sd = (struct sd *) gspca_dev; - static __u8 doit[] = /* update sensor */ + static const __u8 doit[] = /* update sensor */ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 }; - static __u8 sensorgo[] = /* sensor on */ + static const __u8 sensorgo[] = /* sensor on */ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 }; - static __u8 gainMo[] = + static const __u8 gainMo[] = { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d }; switch (sd->sensor) { @@ -1164,14 +1174,15 @@ static void sd_start(struct gspca_dev *gspca_dev) __u8 data; __u8 reg1; __u8 reg17; - __u8 *sn9c1xx; + const __u8 *sn9c1xx; int mode; - static __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; - static __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; - static __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; - static __u8 CA_sn9c120[] = { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ - static __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ - static __u8 CE_sn9c325[] = + static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; + static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; + static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; + static const __u8 CA_sn9c120[] = + { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */ + static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */ + static const __u8 CE_sn9c325[] = { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */ sn9c1xx = sn_tb[(int) sd->sensor]; @@ -1311,13 +1322,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - static __u8 stophv7131[] = + static const __u8 stophv7131[] = { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; - static __u8 stopmi0360[] = + static const __u8 stopmi0360[] = { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; __u8 regF1; __u8 data; - __u8 *sn9c1xx; + const __u8 *sn9c1xx; data = 0x0b; switch (sd->sensor) { @@ -1392,7 +1403,7 @@ static void setautogain(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -1567,7 +1578,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -1582,7 +1593,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 1db5b33ad85e..3a42506830f8 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char packet[ISO_MAX_SIZE + 128]; + __u8 packet[ISO_MAX_SIZE + 128]; /* !! no more than 128 ff in an ISO packet */ unsigned char brightness; @@ -70,44 +70,44 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, - .maximum = 0xff, + .maximum = 255, .step = 1, - .default_value = 0x7f, +#define BRIGHTNESS_DEF 127 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Contrast", .minimum = 0, - .maximum = 255, + .maximum = 63, .step = 1, - .default_value = 127, +#define CONTRAST_DEF 31 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Color", .minimum = 0, - .maximum = 255, + .maximum = 63, .step = 1, - .default_value = 127, +#define COLOR_DEF 31 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, @@ -139,7 +139,7 @@ static struct cam_mode sif_mode[] = { #define SPCA500_OFFSET_DATA 16 -static __u16 spca500_visual_defaults[][3] = { +static const __u16 spca500_visual_defaults[][3] = { {0x00, 0x0003, 0x816b}, /* SSI not active sync with vsync, * hue (H byte) = 0, * saturation/hue enable, @@ -161,10 +161,9 @@ static __u16 spca500_visual_defaults[][3] = { {0x00, 0x0001, 0x8202}, /* clock rate compensation = 1/25 sec/frame */ {0x0c, 0x0004, 0x0000}, /* set interface */ - - {0, 0, 0} + {} }; -static __u16 Clicksmart510_defaults[][3] = { +static const __u16 Clicksmart510_defaults[][3] = { {0x00, 0x00, 0x8211}, {0x00, 0x01, 0x82c0}, {0x00, 0x10, 0x82cb}, @@ -293,7 +292,7 @@ static __u16 Clicksmart510_defaults[][3] = { {} }; -static unsigned char qtable_creative_pccam[2][64] = { +static const __u8 qtable_creative_pccam[2][64] = { { /* Q-table Y-components */ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, @@ -314,7 +313,7 @@ static unsigned char qtable_creative_pccam[2][64] = { 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} }; -static unsigned char qtable_kodak_ez200[2][64] = { +static const __u8 qtable_kodak_ez200[2][64] = { { /* Q-table Y-components */ 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06, 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06, @@ -335,7 +334,7 @@ static unsigned char qtable_kodak_ez200[2][64] = { 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a} }; -static unsigned char qtable_pocketdv[2][64] = { +static const __u8 qtable_pocketdv[2][64] = { { /* Q-table Y-components start registers 0x8800 */ 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18, 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16, @@ -357,7 +356,7 @@ static unsigned char qtable_pocketdv[2][64] = { 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} }; -static void spca5xxRegRead(struct usb_device *dev, +static void reg_r(struct usb_device *dev, __u16 index, __u8 *buffer, __u16 length) { @@ -369,25 +368,24 @@ static void spca5xxRegRead(struct usb_device *dev, index, buffer, length, 500); } -static int reg_write(struct usb_device *dev, +static int reg_w(struct usb_device *dev, __u16 req, __u16 index, __u16 value) { int ret; + PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); - PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x, 0x%x", - index, value, ret); if (ret < 0) PDEBUG(D_ERR, "reg write: error %d", ret); return ret; } /* returns: negative is error, pos or zero is data */ -static int reg_read(struct usb_device *dev, +static int reg_r_12(struct usb_device *dev, __u16 req, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */ @@ -405,7 +403,7 @@ static int reg_read(struct usb_device *dev, buf, length, 500); /* timeout */ if (ret < 0) { - PDEBUG(D_ERR, "reg_read err %d", ret); + PDEBUG(D_ERR, "reg_r_12 err %d", ret); return -1; } return (buf[1] << 8) + buf[0]; @@ -416,13 +414,13 @@ static int reg_read(struct usb_device *dev, * a reg_read call. * Returns: negative is error or timeout, zero is success. */ -static int reg_readwait(struct usb_device *dev, +static int reg_r_wait(struct usb_device *dev, __u16 reg, __u16 index, __u16 value) { int ret, cnt = 20; while (--cnt > 0) { - ret = reg_read(dev, reg, index, 1); + ret = reg_r_12(dev, reg, index, 1); if (ret == value) return 0; msleep(50); @@ -431,13 +429,13 @@ static int reg_readwait(struct usb_device *dev, } static int write_vector(struct gspca_dev *gspca_dev, - __u16 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + ret = reg_w(dev, data[i][0], data[i][2], data[i][1]); if (ret < 0) return ret; i++; @@ -449,21 +447,21 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, unsigned int request, unsigned int ybase, unsigned int cbase, - unsigned char qtable[2][64]) + const __u8 qtable[2][64]) { struct usb_device *dev = gspca_dev->dev; int i, err; /* loop over y components */ for (i = 0; i < 64; i++) { - err = reg_write(dev, request, ybase + i, qtable[0][i]); + err = reg_w(dev, request, ybase + i, qtable[0][i]); if (err < 0) return err; } /* loop over c components */ for (i = 0; i < 64; i++) { - err = reg_write(dev, request, cbase + i, qtable[1][i]); + err = reg_w(dev, request, cbase + i, qtable[1][i]); if (err < 0) return err; } @@ -474,8 +472,8 @@ static void spca500_ping310(struct gspca_dev *gspca_dev) { __u8 Data[2]; - spca5xxRegRead(gspca_dev->dev, 0x0d04, Data, 2); - PDEBUG(D_PACK, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", + reg_r(gspca_dev->dev, 0x0d04, Data, 2); + PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", Data[0], Data[1]); } @@ -483,26 +481,26 @@ static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) { __u8 Data[2]; - spca5xxRegRead(gspca_dev->dev, 0x0d05, Data, 2); - PDEBUG(D_PACK, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", Data[0], - Data[1]); - reg_write(gspca_dev->dev, 0x00, 0x8167, 0x5a); + reg_r(gspca_dev->dev, 0x0d05, Data, 2); + PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", + Data[0], Data[1]); + reg_w(gspca_dev->dev, 0x00, 0x8167, 0x5a); spca500_ping310(gspca_dev); - reg_write(gspca_dev->dev, 0x00, 0x8168, 0x22); - reg_write(gspca_dev->dev, 0x00, 0x816a, 0xc0); - reg_write(gspca_dev->dev, 0x00, 0x816b, 0x0b); - reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); - reg_write(gspca_dev->dev, 0x00, 0x8157, 0x5b); - reg_write(gspca_dev->dev, 0x00, 0x8158, 0x5b); - reg_write(gspca_dev->dev, 0x00, 0x813f, 0x03); - reg_write(gspca_dev->dev, 0x00, 0x8151, 0x4a); - reg_write(gspca_dev->dev, 0x00, 0x8153, 0x78); - reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x8168, 0x22); + reg_w(gspca_dev->dev, 0x00, 0x816a, 0xc0); + reg_w(gspca_dev->dev, 0x00, 0x816b, 0x0b); + reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); + reg_w(gspca_dev->dev, 0x00, 0x8157, 0x5b); + reg_w(gspca_dev->dev, 0x00, 0x8158, 0x5b); + reg_w(gspca_dev->dev, 0x00, 0x813f, 0x03); + reg_w(gspca_dev->dev, 0x00, 0x8151, 0x4a); + reg_w(gspca_dev->dev, 0x00, 0x8153, 0x78); + reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x04); /* 00 for adjust shutter */ - reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); - reg_write(gspca_dev->dev, 0x00, 0x8169, 0x25); - reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x02); + reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); + reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x02); } static void spca500_setmode(struct gspca_dev *gspca_dev, @@ -511,14 +509,14 @@ static void spca500_setmode(struct gspca_dev *gspca_dev, int mode; /* set x multiplier */ - reg_write(gspca_dev->dev, 0, 0x8001, xmult); + reg_w(gspca_dev->dev, 0, 0x8001, xmult); /* set y multiplier */ - reg_write(gspca_dev->dev, 0, 0x8002, ymult); + reg_w(gspca_dev->dev, 0, 0x8002, ymult); /* use compressed mode, VGA, with mode specific subsample */ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; - reg_write(gspca_dev->dev, 0, 0x8003, mode << 4); + reg_w(gspca_dev->dev, 0, 0x8003, mode << 4); } static int spca500_full_reset(struct gspca_dev *gspca_dev) @@ -526,20 +524,20 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev) int err; /* send the reset command */ - err = reg_write(gspca_dev->dev, 0xe0, 0x0001, 0x0000); + err = reg_w(gspca_dev->dev, 0xe0, 0x0001, 0x0000); if (err < 0) return err; /* wait for the reset to complete */ - err = reg_readwait(gspca_dev->dev, 0x06, 0x0000, 0x0000); + err = reg_r_wait(gspca_dev->dev, 0x06, 0x0000, 0x0000); if (err < 0) return err; - err = reg_write(gspca_dev->dev, 0xe0, 0x0000, 0x0000); + err = reg_w(gspca_dev->dev, 0xe0, 0x0000, 0x0000); if (err < 0) return err; - err = reg_readwait(gspca_dev->dev, 0x06, 0, 0); + err = reg_r_wait(gspca_dev->dev, 0x06, 0, 0); if (err < 0) { - PDEBUG(D_ERR, "reg_readwait() failed"); + PDEBUG(D_ERR, "reg_r_wait() failed"); return err; } /* all ok */ @@ -562,7 +560,7 @@ static int spca500_synch310(struct gspca_dev *gspca_dev) } spca500_ping310(gspca_dev); - spca5xxRegRead(gspca_dev->dev, 0x0d00, &Data, 1); + reg_r(gspca_dev->dev, 0x0d00, &Data, 1); /* need alt setting here */ PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); @@ -586,12 +584,12 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) /* some unknow command from Aiptek pocket dv and family300 */ - reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); - reg_write(gspca_dev->dev, 0x00, 0x0d03, 0x00); - reg_write(gspca_dev->dev, 0x00, 0x0d02, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x0d03, 0x00); + reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); @@ -599,22 +597,22 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); /* set qtable index */ - reg_write(gspca_dev->dev, 0x00, 0x8880, 2); + reg_w(gspca_dev->dev, 0x00, 0x8880, 2); /* family cam Quicksmart stuff */ - reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ - reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ - reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); /*Start init sequence or stream */ - reg_write(gspca_dev->dev, 0, 0x8003, 0x00); + reg_w(gspca_dev->dev, 0, 0x8003, 0x00); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); msleep(2000); - if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); } /* this function is called at probe time */ @@ -734,9 +732,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; } sd->qindex = 5; - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; return 0; } @@ -771,7 +769,7 @@ static void sd_start(struct gspca_dev *gspca_dev) } /* is there a sensor here ? */ - spca5xxRegRead(gspca_dev->dev, 0x8a04, &Data, 1); + reg_r(gspca_dev->dev, 0x8a04, &Data, 1); PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data); PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X", gspca_dev->curr_mode, xmult, ymult); @@ -782,33 +780,33 @@ static void sd_start(struct gspca_dev *gspca_dev) spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); - reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ - reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); msleep(500); - if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_readwait() failed"); + if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_r_wait() failed"); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); spca500_synch310(gspca_dev); write_vector(gspca_dev, spca500_visual_defaults); spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); PDEBUG(D_ERR, "failed to enable drop packet"); - reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev->dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); @@ -816,16 +814,16 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ - reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_readwait() failed"); + if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_r_wait() failed"); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); break; case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ case IntelPocketPCCamera: /* FIXME: Temporary fix for @@ -838,10 +836,10 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ - err = reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + err = reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); if (err < 0) PDEBUG(D_ERR, "failed to enable drop packet"); - reg_write(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev->dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); @@ -849,18 +847,18 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); - reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); + reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_readwait() failed"); + if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_r_wait() failed"); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); - /* write_vector(gspca_dev, spca500_visual_defaults); */ +/* write_vector(gspca_dev, spca500_visual_defaults); */ break; case KodakEZ200: /* Kodak EZ200 */ @@ -869,8 +867,8 @@ static void sd_start(struct gspca_dev *gspca_dev) if (err < 0) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); - reg_write(gspca_dev->dev, 0x00, 0x8880, 0); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x8880, 0); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_kodak_ez200); @@ -878,18 +876,18 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); - reg_write(gspca_dev->dev, 0x20, 0x0001, 0x0004); + reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - if (reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - PDEBUG(D_ERR, "reg_readwait() failed"); + if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + PDEBUG(D_ERR, "reg_r_wait() failed"); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); - /* write_vector(gspca_dev, spca500_visual_defaults); */ +/* write_vector(gspca_dev, spca500_visual_defaults); */ break; case BenqDC1016: @@ -902,56 +900,56 @@ static void sd_start(struct gspca_dev *gspca_dev) case ToptroIndus: case AgfaCl20: spca500_reinit(gspca_dev); - reg_write(gspca_dev->dev, 0x00, 0x0d01, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_write(gspca_dev->dev, 0x00, 0x8880, 2); + reg_w(gspca_dev->dev, 0x00, 0x8880, 2); /* familycam Quicksmart pocketDV stuff */ - reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ - reg_write(gspca_dev->dev, 0x00, 0x820f, 0x01); + reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ - reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); + reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); break; case LogitechTraveler: case LogitechClickSmart510: - reg_write(gspca_dev->dev, 0x02, 0x00, 0x00); + reg_w(gspca_dev->dev, 0x02, 0x00, 0x00); /* enable drop packet */ - reg_write(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_write(gspca_dev->dev, 0x00, 0x8880, 3); - reg_write(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); /* Init SDRAM - needed for SDRAM access */ - reg_write(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); - reg_readwait(gspca_dev->dev, 0, 0x8000, 0x44); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); - spca5xxRegRead(gspca_dev->dev, 0x816b, &Data, 1); - reg_write(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev->dev, 0x816b, &Data, 1); + reg_w(gspca_dev->dev, 0x00, 0x816b, Data); write_vector(gspca_dev, Clicksmart510_defaults); break; } @@ -959,13 +957,13 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - __u8 data = 0; + __u8 data; - reg_write(gspca_dev->dev, 0, 0x8003, 0x00); + reg_w(gspca_dev->dev, 0, 0x8003, 0x00); /* switch to video camera mode */ - reg_write(gspca_dev->dev, 0x00, 0x8000, 0x0004); - spca5xxRegRead(gspca_dev->dev, 0x8000, &data, 1); + reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_r(gspca_dev->dev, 0x8000, &data, 1); PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data); } @@ -979,13 +977,13 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; int i; - unsigned char *s, *d; - static unsigned char ffd9[] = {0xff, 0xd9}; + __u8 *s, *d; + static __u8 ffd9[] = {0xff, 0xd9}; /* frames are jpeg 4.1.1 without 0xff escape */ if (data[0] == 0xff) { @@ -997,9 +995,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, ffd9, 2); /* put the JPEG header in the new frame */ - jpeg_put_header(gspca_dev, frame, - ((struct sd *) gspca_dev)->qindex, - 0x22); + jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22); data += SPCA500_OFFSET_DATA; len -= SPCA500_OFFSET_DATA; @@ -1031,43 +1027,52 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_write(gspca_dev->dev, 0x00, 0x8167, + reg_w(gspca_dev->dev, 0x00, 0x8167, (__u8) (sd->brightness - 128)); } static void getbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; - sd->brightness = reg_read(gspca_dev->dev, 0x00, 0x8167, 1) + 128; + ret = reg_r_12(gspca_dev->dev, 0x00, 0x8167, 1); + if (ret >= 0) + sd->brightness = ret + 128; } static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_write(gspca_dev->dev, 0x00, 0x8168, sd->contrast >> 2); + reg_w(gspca_dev->dev, 0x00, 0x8168, sd->contrast); } static void getcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; - sd->contrast = reg_read(gspca_dev->dev, 0x0, 0x8168, 1) << 2; + ret = reg_r_12(gspca_dev->dev, 0x0, 0x8168, 1); + if (ret >= 0) + sd->contrast = ret; } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_write(gspca_dev->dev, 0x00, 0x8169, sd->colors >> 2); + reg_w(gspca_dev->dev, 0x00, 0x8169, sd->colors); } static void getcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + int ret; - sd->colors = reg_read(gspca_dev->dev, 0x0, 0x8169, 1) << 2; + ret = reg_r_12(gspca_dev->dev, 0x0, 0x8169, 1); + if (ret >= 0) + sd->colors = ret; } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -1131,7 +1136,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) static struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, - .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], + .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .open = sd_open, .start = sd_start, @@ -1143,7 +1148,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index c6468cf3506a..417fbe2214be 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); @@ -151,7 +151,7 @@ static struct cam_mode vga_mode[] = { #define SPCA501_A33 0x10 /* Data for video camera initialization before capturing */ -static __u16 spca501_open_data[][3] = { +static const __u16 spca501_open_data[][3] = { /* bmRequest,value,index */ {0x2, 0x50, 0x00}, /* C/S enable soft reset */ @@ -257,7 +257,7 @@ static __u16 spca501_open_data[][3] = { */ /* Data for chip initialization (set default values) */ -static __u16 spca501_init_data[][3] = { +static const __u16 spca501_init_data[][3] = { /* Set all the values to powerup defaults */ /* bmRequest,value,index */ {0x0, 0xAA, 0x00}, @@ -544,7 +544,7 @@ static __u16 spca501_init_data[][3] = { * Capture and decoding by Colin Peart. * This is is for the 3com HomeConnect Lite which is spca501a based. */ -static __u16 spca501_3com_open_data[][3] = { +static const __u16 spca501_3com_open_data[][3] = { /* bmRequest,value,index */ {0x2, 0x0050, 0x0000}, /* C/S Enable TG soft reset, timing mode=010 */ {0x2, 0x0043, 0x0000}, /* C/S Disable TG soft reset, timing mode=010 */ @@ -639,7 +639,7 @@ static __u16 spca501_3com_open_data[][3] = { * 2) Understand why some values seem to appear more than once * 3) Write a small comment for each line of the following arrays. */ -static __u16 spca501c_arowana_open_data[][3] = { +static const __u16 spca501c_arowana_open_data[][3] = { /* bmRequest,value,index */ {0x02, 0x0007, 0x0005}, {0x02, 0xa048, 0x0000}, @@ -661,7 +661,7 @@ static __u16 spca501c_arowana_open_data[][3] = { {} }; -static __u16 spca501c_arowana_init_data[][3] = { +static const __u16 spca501c_arowana_init_data[][3] = { /* bmRequest,value,index */ {0x02, 0x0007, 0x0005}, {0x02, 0xa048, 0x0000}, @@ -1595,7 +1595,7 @@ static __u16 spca501c_arowana_init_data[][3] = { /* Unknow camera from Ori Usbid 0x0000:0x0000 */ /* Based on snoops from Ori Cohen */ -static __u16 spca501c_mysterious_open_data[][3] = { +static const __u16 spca501c_mysterious_open_data[][3] = { {0x02, 0x000f, 0x0005}, {0x02, 0xa048, 0x0000}, {0x05, 0x0022, 0x0004}, @@ -1646,7 +1646,7 @@ static __u16 spca501c_mysterious_open_data[][3] = { }; /* Based on snoops from Ori Cohen */ -static __u16 spca501c_mysterious_init_data[][3] = { +static const __u16 spca501c_mysterious_init_data[][3] = { /* Part 3 */ /* TG registers */ /* {0x00, 0x0000, 0x0000}, */ @@ -1839,7 +1839,7 @@ static int reg_read(struct usb_device *dev, } static int write_vector(struct gspca_dev *gspca_dev, - __u16 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -2001,7 +2001,6 @@ static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - PDEBUG(D_STREAM, "SPCA501 init"); switch (sd->subtype) { case ThreeComHomeConnectLite: /* Special handling for 3com data */ @@ -2050,7 +2049,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_write(dev, SPCA501_REG_CTLRL, 0x01, 0x02); /* HDG atleast the Intel CreateAndShare needs to have one of its - * brightness / contrast / color set otherwise it assumes wath seems + * brightness / contrast / color set otherwise it assumes what seems * max contrast. Note that strange enough setting any of these is * enough to fix the max contrast problem, to be sure we set all 3 */ setbrightness(gspca_dev); @@ -2159,7 +2158,7 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -2174,7 +2173,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index d8ff121c2c5a..30d174fc4b9c 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); @@ -91,7 +91,7 @@ static struct cam_mode vga_mode[] = { /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static __u16 spca505_init_data[][3] = { +static const __u16 spca505_init_data[][3] = { /* line bmRequest,value,index */ /* 1819 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3}, @@ -130,7 +130,7 @@ static __u16 spca505_init_data[][3] = { /* * Data to initialize the camera using the internal CCD */ -static __u16 spca505_open_data_ccd[][3] = { +static const __u16 spca505_open_data_ccd[][3] = { /* line bmRequest,value,index */ /* Internal CCD data set */ /* 1891 */ {0x3, 0x04, 0x01}, @@ -319,7 +319,7 @@ static __u16 spca505_open_data_ccd[][3] = { /* * Data to initialize a SPCA505. Common to the CCD and external modes */ -static __u16 spca505b_init_data[][3] = { +static const __u16 spca505b_init_data[][3] = { /* start */ {0x02, 0x00, 0x00}, /* init */ {0x02, 0x00, 0x01}, @@ -383,7 +383,7 @@ static __u16 spca505b_init_data[][3] = { /* * Data to initialize the camera using the internal CCD */ -static __u16 spca505b_open_data_ccd[][3] = { +static const __u16 spca505b_open_data_ccd[][3] = { /* {0x02,0x00,0x00}, */ {0x03, 0x04, 0x01}, /* rst */ @@ -579,7 +579,7 @@ static int reg_read(struct usb_device *dev, __u16 length) /* wLength (1 or 2 only) */ { int ret; - unsigned char buf[4]; + __u8 buf[4]; buf[1] = 0; ret = usb_control_msg(dev, @@ -599,7 +599,7 @@ static int reg_read(struct usb_device *dev, } static int write_vector(struct gspca_dev *gspca_dev, - __u16 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -801,7 +801,7 @@ static void yyuv_decode(unsigned char *out, static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -878,7 +878,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -893,7 +893,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, {} diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 2ccd877b998d..3b54f41d21c1 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); @@ -92,7 +92,7 @@ static struct cam_mode sif_mode[] = { * Initialization data: this is the first set-up data written to the * device (before the open data). */ -static __u16 spca508_init_data[][3] = +static const __u16 spca508_init_data[][3] = #define IGN(x) /* nothing */ { /* line URB value, index */ @@ -584,7 +584,7 @@ static __u16 spca508_init_data[][3] = /* * Initialization data for Intel EasyPC Camera CS110 */ -static __u16 spca508cs110_init_data[][3] = { +static const __u16 spca508cs110_init_data[][3] = { {0x0000, 0x870b}, /* Reset CTL3 */ {0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */ {0x0000, 0x8111}, /* Normal operation on reset */ @@ -668,7 +668,7 @@ static __u16 spca508cs110_init_data[][3] = { {} }; -static __u16 spca508_sightcam_init_data[][3] = { +static const __u16 spca508_sightcam_init_data[][3] = { /* This line seems to setup the frame/canvas */ /*368 */ {0x000f, 0x8402}, @@ -752,7 +752,7 @@ static __u16 spca508_sightcam_init_data[][3] = { {0, 0} }; -static __u16 spca508_sightcam2_init_data[][3] = { +static const __u16 spca508_sightcam2_init_data[][3] = { /* 35 */ {0x0020, 0x8112}, /* 36 */ {0x000f, 0x8402}, @@ -1099,7 +1099,7 @@ static __u16 spca508_sightcam2_init_data[][3] = { /* * Initialization data for Creative Webcam Vista */ -static __u16 spca508_vista_init_data[][3] = { +static const __u16 spca508_vista_init_data[][3] = { {0x0008, 0x8200}, /* Clear register */ {0x0000, 0x870b}, /* Reset CTL3 */ {0x0020, 0x8112}, /* Video Drop packet enable */ @@ -1441,7 +1441,7 @@ static int reg_read(struct usb_device *dev, } static int write_vector(struct gspca_dev *gspca_dev, - __u16 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -1639,7 +1639,7 @@ static void yuvy_decode(unsigned char *out, static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -1717,7 +1717,7 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -1732,7 +1732,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index dbd1648a655f..8e39cbdda2a5 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); @@ -148,7 +148,8 @@ static void reg_w_val(struct usb_device *dev, __u16 index, __u16 value) PDEBUG(D_ERR, "reg write: error %d", ret); } -static void write_vector(struct gspca_dev *gspca_dev, __u16 data[][2]) +static void write_vector(struct gspca_dev *gspca_dev, + const __u16 data[][2]) { struct usb_device *dev = gspca_dev->dev; int i; @@ -171,13 +172,16 @@ static void reg_r(struct usb_device *dev, } static void reg_w_buf(struct usb_device *dev, - __u16 index, __u8 *buffer, __u16 length) + __u16 index, const __u8 *buffer, __u16 len) { + __u8 tmpbuf[8]; + + memcpy(tmpbuf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, 500); + index, tmpbuf, len, 500); } static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) @@ -227,7 +231,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) return ((int) value << 8) | vallsb; } -static __u16 spca561_init_data[][2] = { +static const __u16 spca561_init_data[][2] = { {0x0000, 0x8114}, /* Software GPIO output data */ {0x0001, 0x8114}, /* Software GPIO output data */ {0x0000, 0x8112}, /* Some kind of reset */ @@ -437,7 +441,7 @@ static void sensor_reset(struct gspca_dev *gspca_dev) } /******************** QC Express etch2 stuff ********************/ -static __u16 Pb100_1map8300[][2] = { +static const __u16 Pb100_1map8300[][2] = { /* reg, value */ {0x8320, 0x3304}, @@ -452,14 +456,14 @@ static __u16 Pb100_1map8300[][2] = { {0x8302, 0x000e}, {} }; -static __u16 Pb100_2map8300[][2] = { +static const __u16 Pb100_2map8300[][2] = { /* reg, value */ {0x8339, 0x0000}, {0x8307, 0x00aa}, {} }; -static __u16 spca561_161rev12A_data1[][2] = { +static const __u16 spca561_161rev12A_data1[][2] = { {0x21, 0x8118}, {0x01, 0x8114}, {0x00, 0x8112}, @@ -467,7 +471,7 @@ static __u16 spca561_161rev12A_data1[][2] = { {0x04, 0x8802}, /* windows uses 08 */ {} }; -static __u16 spca561_161rev12A_data2[][2] = { +static const __u16 spca561_161rev12A_data2[][2] = { {0x21, 0x8118}, {0x10, 0x8500}, {0x07, 0x8601}, @@ -513,7 +517,7 @@ static __u16 spca561_161rev12A_data2[][2] = { }; static void sensor_mapwrite(struct gspca_dev *gspca_dev, - __u16 sensormap[][2]) + const __u16 sensormap[][2]) { int i = 0; __u8 usbval[2]; @@ -956,7 +960,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -971,7 +975,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 6832fe0f3403..ad59c5ab5d90 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -23,8 +23,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -54,7 +54,6 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -63,12 +62,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define BRIGHTNESS_DEF 127 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -77,26 +76,26 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", + .name = "Color", .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define COLOR_DEF 127 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, -#define SD_FREQ 3 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, @@ -105,7 +104,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 1, .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ .step = 1, - .default_value = 1, +#define FREQ_DEF 1 + .default_value = FREQ_DEF, }, .set = sd_setfreq, .get = sd_getfreq, @@ -296,10 +296,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0]; - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; - sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; + sd->lightfreq = FREQ_DEF; return 0; } @@ -408,7 +408,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { static unsigned char ffd9[] = {0xff, 0xd9}; @@ -518,10 +518,10 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy(menu->name, "50 Hz"); + strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy(menu->name, "60 Hz"); + strcpy((char *) menu->name, "60 Hz"); return 0; } break; diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 113c07106924..f2d033508581 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1) -static const char version[] = "2.1.1"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); @@ -35,7 +35,7 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - unsigned char packet[ISO_MAX_SIZE + 128]; + __u8 packet[ISO_MAX_SIZE + 128]; /* !! no more than 128 ff in an ISO packet */ unsigned char brightness; @@ -156,7 +156,7 @@ static struct cam_mode vga_mode2[] = { #define SPCA536_OFFSET_FRAMSEQ 1 /* Initialisation data for the Creative PC-CAM 600 */ -static __u16 spca504_pccam600_init_data[][3] = { +static const __u16 spca504_pccam600_init_data[][3] = { /* {0xa0, 0x0000, 0x0503}, * capture mode */ {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, @@ -186,7 +186,7 @@ static __u16 spca504_pccam600_init_data[][3] = { /* Creative PC-CAM 600 specific open data, sent before using the * generic initialisation data from spca504_open_data. */ -static __u16 spca504_pccam600_open_data[][3] = { +static const __u16 spca504_pccam600_open_data[][3] = { {0x00, 0x0001, 0x2501}, {0x20, 0x0500, 0x0001}, /* snapshot mode */ {0x00, 0x0003, 0x2880}, @@ -195,7 +195,7 @@ static __u16 spca504_pccam600_open_data[][3] = { }; /* Initialisation data for the logitech clicksmart 420 */ -static __u16 spca504A_clicksmart420_init_data[][3] = { +static const __u16 spca504A_clicksmart420_init_data[][3] = { /* {0xa0, 0x0000, 0x0503}, * capture mode */ {0x00, 0x0000, 0x2000}, {0x00, 0x0013, 0x2301}, @@ -226,7 +226,7 @@ static __u16 spca504A_clicksmart420_init_data[][3] = { }; /* clicksmart 420 open data ? */ -static __u16 spca504A_clicksmart420_open_data[][3] = { +static const __u16 spca504A_clicksmart420_open_data[][3] = { {0x00, 0x0001, 0x2501}, {0x20, 0x0502, 0x0000}, {0x06, 0x0000, 0x0000}, @@ -373,7 +373,7 @@ static __u16 spca504A_clicksmart420_open_data[][3] = { {} }; -static unsigned char qtable_creative_pccam[2][64] = { +static const __u8 qtable_creative_pccam[2][64] = { { /* Q-table Y-components */ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, @@ -398,7 +398,7 @@ static unsigned char qtable_creative_pccam[2][64] = { * except for one byte. Possibly a typo? * NWG: 18/05/2003. */ -static unsigned char qtable_spca504_default[2][64] = { +static const __u8 qtable_spca504_default[2][64] = { { /* Q-table Y-components */ 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12, 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11, @@ -512,7 +512,7 @@ static int reg_read(struct usb_device *dev, } static int write_vector(struct gspca_dev *gspca_dev, - __u16 data[][3]) + const __u16 data[][3]) { struct usb_device *dev = gspca_dev->dev; int ret, i = 0; @@ -534,7 +534,7 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, unsigned int request, unsigned int ybase, unsigned int cbase, - unsigned char qtable[2][64]) + const __u8 qtable[2][64]) { struct usb_device *dev = gspca_dev->dev; int i, err; @@ -1242,7 +1242,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -1530,7 +1530,7 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -1545,7 +1545,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index de43118dec7a..4e69a8e16357 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -26,13 +26,8 @@ #define MODULE_NAME "t613" #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; - -struct control_menu_info { - int value; - char name[32]; -}; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; #define MAX_GAMMA 0x10 /* 0 to 15 */ @@ -227,19 +222,16 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct control_menu_info effects_control[] = { - {0, "Normal"}, - {1, "Emboss"}, /* disabled */ - {2, "Monochrome"}, - {3, "Sepia"}, - {4, "Sketch"}, - {5, "Sun Effect"}, /* disabled */ - {6, "Negative"}, +static char *effects_control[] = { + "Normal", + "Emboss", /* disabled */ + "Monochrome", + "Sepia", + "Sketch", + "Sun Effect", /* disabled */ + "Negative", }; -#define NUM_EFFECTS_CONTROL \ - (sizeof(effects_control)/sizeof(effects_control[0])) - static struct cam_mode vga_mode_t16[] = { {V4L2_PIX_FMT_JPEG, 160, 120, 4}, {V4L2_PIX_FMT_JPEG, 176, 144, 3}, @@ -252,7 +244,7 @@ static struct cam_mode vga_mode_t16[] = { #define MAX_EFFECTS 7 /* easily done by soft, this table could be removed, * i keep it here just in case */ -unsigned char effects_table[MAX_EFFECTS][6] = { +static const __u8 effects_table[MAX_EFFECTS][6] = { {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */ {0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */ {0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */ @@ -262,7 +254,7 @@ unsigned char effects_table[MAX_EFFECTS][6] = { {0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */ }; -unsigned char gamma_table[MAX_GAMMA][34] = { +static const __u8 gamma_table[MAX_GAMMA][34] = { {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9, 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb, @@ -345,7 +337,7 @@ unsigned char gamma_table[MAX_GAMMA][34] = { 0xA0, 0xFF} }; -static __u8 tas5130a_sensor_init[][8] = { +static const __u8 tas5130a_sensor_init[][8] = { {0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09}, {0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09}, {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09}, @@ -366,22 +358,41 @@ static void t16RegRead(struct usb_device *dev, static void t16RegWrite(struct usb_device *dev, __u16 value, - __u16 index, __u8 *buffer, __u16 len) + __u16 index, + const __u8 *buffer, __u16 len) { - __u8 tmpbuf[70]; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - if (len > sizeof tmpbuf) { - PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + if (buffer == NULL) { + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, index, + NULL, 0, 500); return; } -#endif - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), - 0, /* request */ - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, tmpbuf, len, 500); + if (len < 16) { + __u8 tmpbuf[16]; + + memcpy(tmpbuf, buffer, len); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, index, + tmpbuf, len, 500); + } else { + __u8 *tmpbuf; + + tmpbuf = kmalloc(len, GFP_KERNEL); + memcpy(tmpbuf, buffer, len); + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, index, + tmpbuf, len, 500); + kfree(tmpbuf); + } } /* this function is called at probe time */ @@ -421,18 +432,18 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) int i = 0; __u8 test_byte; - static unsigned char read_indexs[] = + static const __u8 read_indexs[] = { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5, 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 }; - static unsigned char n1[6] = + static const __u8 n1[6] = {0x08, 0x03, 0x09, 0x03, 0x12, 0x04}; - static unsigned char n2[2] = + static const __u8 n2[2] = {0x08, 0x00}; - static unsigned char nset[6] = + static const __u8 nset[6] = { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 }; - static unsigned char n3[6] = + static const __u8 n3[6] = {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04}; - static unsigned char n4[0x46] = + static const __u8 n4[0x46] = {0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c, 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68, 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1, @@ -442,40 +453,40 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68, 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40, 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46}; - static unsigned char nset4[18] = { + static const __u8 nset4[18] = { 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8, 0xe8, 0xe0 }; /* ojo puede ser 0xe6 en vez de 0xe9 */ - static unsigned char nset2[20] = { + static const __u8 nset2[20] = { 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27, 0xd8, 0xc8, 0xd9, 0xfc }; - static unsigned char missing[8] = + static const __u8 missing[8] = { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; - static unsigned char nset3[18] = { + static const __u8 nset3[18] = { 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8, 0xcf, 0xe0 }; - static unsigned char nset5[4] = + static const __u8 nset5[4] = { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */ - static unsigned char nset6[34] = { + static const __u8 nset6[34] = { 0x90, 0x00, 0x91, 0x1c, 0x92, 0x30, 0x93, 0x43, 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84, 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd, 0x9c, 0xca, 0x9d, 0xd8, 0x9e, 0xe5, 0x9f, 0xf2, 0xa0, 0xff }; /* Gamma */ - static unsigned char nset7[4] = + static const __u8 nset7[4] = { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */ - static unsigned char nset9[4] = + static const __u8 nset9[4] = { 0x0b, 0x04, 0x0a, 0x78 }; - static unsigned char nset8[6] = + static const __u8 nset8[6] = { 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 }; - static unsigned char nset10[6] = + static const __u8 nset10[6] = { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; t16RegWrite(dev, 0x01, 0x0000, n1, 0x06); @@ -493,31 +504,31 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); t16RegRead(dev, 0x0080, &test_byte, 1); - t16RegWrite(dev, 0x00, 0x2c80, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x2c80, NULL, 0x0); t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); - t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); - t16RegWrite(dev, 0x00, 0x3880, 0x00, 0x0); - t16RegWrite(dev, 0x00, 0x338e, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x338e, NULL, 0x0); t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04); - t16RegWrite(dev, 0x00, 0x00a9, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x00a9, NULL, 0x0); t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22); - t16RegWrite(dev, 0x00, 0x86bb, 0x00, 0x0); - t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x86bb, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x0); t16RegWrite(dev, 0x01, 0x0000, missing, 0x08); - t16RegWrite(dev, 0x00, 0x2087, 0x00, 0x0); - t16RegWrite(dev, 0x00, 0x2088, 0x00, 0x0); - t16RegWrite(dev, 0x00, 0x2089, 0x00, 0x0); + t16RegWrite(dev, 0x00, 0x2087, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x2088, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x2089, NULL, 0x0); t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04); t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06); t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06); t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04); - t16RegWrite(dev, 0x00, 0x2880, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0x2880, NULL, 0x00); t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); @@ -530,7 +541,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; unsigned int brightness; - unsigned char set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; + __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; brightness = sd->brightness; if (brightness < 7) { @@ -548,7 +559,7 @@ static void setflip(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - unsigned char flipcmd[8] = + __u8 flipcmd[8] = { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; if (sd->mirror == 1) @@ -570,9 +581,9 @@ static void seteffect(struct gspca_dev *gspca_dev) } if (sd->effect == 1 || sd->effect == 4) - t16RegWrite(dev, 0x00, 0x4aa6, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x00); else - t16RegWrite(dev, 0x00, 0xfaa6, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0x00); } static void setwhitebalance(struct gspca_dev *gspca_dev) @@ -580,7 +591,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - unsigned char white_balance[8] = + __u8 white_balance[8] = { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; if (sd->whitebalance == 1) @@ -613,18 +624,17 @@ static void setcontrast(struct gspca_dev *gspca_dev) else reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); - t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); - + t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - __u16 reg_to_write = 0x00; + __u16 reg_to_write; reg_to_write = 0xc0bb + sd->colors * 0x100; - t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0); + t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); } static void setgamma(struct gspca_dev *gspca_dev) @@ -635,11 +645,11 @@ static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - __u16 reg_to_write = 0x00; + __u16 reg_to_write; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - t16RegWrite(dev, 0x00, reg_to_write, 0x00, 0x00); + t16RegWrite(dev, 0x00, reg_to_write, NULL, 0x00); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -655,6 +665,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; + *val = sd->brightness; return *val; } @@ -677,7 +688,6 @@ static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val) return *val; } - static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; @@ -811,9 +821,9 @@ static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) sd->autogain = val; if (val != 0) - t16RegWrite(dev, 0x00, 0xf48e, 0x00, 0); + t16RegWrite(dev, 0x00, 0xf48e, NULL, 0); else - t16RegWrite(dev, 0x00, 0xb48e, 0x00, 0); + t16RegWrite(dev, 0x00, 0xb48e, NULL, 0); return 0; } @@ -831,12 +841,12 @@ static void sd_start(struct gspca_dev *gspca_dev) int mode; __u8 test_byte; - static __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; + static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; - static __u8 t3[] = + static const __u8 t3[] = { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06, 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; - static __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; + static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode; switch (mode) { @@ -860,16 +870,16 @@ static void sd_start(struct gspca_dev *gspca_dev) t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00); /* just in case and to keep sync with logs (for mine) */ t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00); /* just in case and to keep sync with logs (for mine) */ t16RegWrite(dev, 0x01, 0x0000, t1, 4); t16RegWrite(dev, 0x01, 0x0000, t2, 6); t16RegRead(dev, 0x0012, &test_byte, 0x1); t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); - t16RegWrite(dev, 0x00, 0x0013, 0x00, 0x00); + t16RegWrite(dev, 0x00, 0x0013, NULL, 0x00); t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); /* restart on each start, just in case, sometimes regs goes wrong * when using controls from app */ @@ -892,11 +902,11 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { int sof = 0; - static unsigned char ffd9[] = { 0xff, 0xd9 }; + static __u8 ffd9[] = { 0xff, 0xd9 }; if (data[0] == 0x5a) { /* Control Packet, after this came the header again, @@ -935,27 +945,26 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { - memset(menu->name, 0, sizeof menu->name); - switch (menu->id) { case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy(menu->name, "50 Hz"); + strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy(menu->name, "60 Hz"); + strcpy((char *) menu->name, "60 Hz"); return 0; } break; case V4L2_CID_EFFECTS: - if (menu->index < 0 || menu->index >= NUM_EFFECTS_CONTROL) - return -EINVAL; - strncpy((char *) menu->name, - effects_control[menu->index].name, 32); + if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) { + strncpy((char *) menu->name, + effects_control[menu->index], 32); + return 0; + } break; } - return 0; + return -EINVAL; } /* this function is called at open time */ @@ -966,7 +975,7 @@ static int sd_open(struct gspca_dev *gspca_dev) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -982,11 +991,10 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, {} }; - MODULE_DEVICE_TABLE(usb, device_table); /* -- device connect -- */ diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 6da5280b5433..8561234d65e2 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("TV8532 USB Camera Driver"); @@ -152,7 +152,7 @@ static struct cam_mode sif_mode[] = { #define TV8532_AD_ROWBEGIN_L 0x14 #define TV8532_AD_ROWBEGIN_H 0x15 -static __u32 tv_8532_eeprom_data[] = { +static const __u32 tv_8532_eeprom_data[] = { /* add dataL dataM dataH */ 0x00010001, 0x01018011, 0x02050014, 0x0305001c, 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b, @@ -243,7 +243,7 @@ static int sd_config(struct gspca_dev *gspca_dev, static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 data = 0; + __u8 data; /* __u16 vid, pid; */ reg_r(dev, 0x0001, &data); @@ -275,7 +275,7 @@ static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) static void tv_8532_setReg(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 data = 0; + __u8 data; __u8 value[2] = { 0, 0 }; data = ADCBEGINL; @@ -320,7 +320,7 @@ static void tv_8532_setReg(struct gspca_dev *gspca_dev) static void tv_8532_PollReg(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 data = 0; + __u8 data; int i; /* strange polling from tgc */ @@ -338,9 +338,9 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev) static int sd_open(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 data = 0; - __u8 dataStart = 0; - __u8 value[2] = { 0, 0 }; + __u8 data; + __u8 dataStart; + __u8 value[2]; data = 0x32; reg_w(dev, TV8532_AD_SLOPE, &data, 1); @@ -646,7 +646,7 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -661,7 +661,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 8b5f6d17d2a5..4144e11c60bb 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); @@ -97,7 +97,7 @@ static struct cam_mode vc0323_mode[] = { {V4L2_PIX_FMT_JPEG, 640, 480, 0}, }; -static __u8 mi1310_socinitVGA_JPG[][4] = { +static const __u8 mi1310_socinitVGA_JPG[][4] = { {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, {0xb3, 0x00, 0x64, 0xcc}, @@ -249,7 +249,7 @@ static __u8 mi1310_socinitVGA_JPG[][4] = { {0x03, 0x03, 0xc0, 0xbb}, {}, }; -static __u8 mi1310_socinitQVGA_JPG[][4] = { +static const __u8 mi1310_socinitQVGA_JPG[][4] = { {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc}, {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc}, {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc}, @@ -323,14 +323,14 @@ static __u8 mi1310_socinitQVGA_JPG[][4] = { {}, }; -static __u8 mi1320_gamma[17] = { +static const __u8 mi1320_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff }; -static __u8 mi1320_matrix[9] = { +static const __u8 mi1320_matrix[9] = { 0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52 }; -static __u8 mi1320_initVGA_data[][4] = { +static const __u8 mi1320_initVGA_data[][4] = { {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, @@ -409,7 +409,7 @@ static __u8 mi1320_initVGA_data[][4] = { {0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, {} }; -static __u8 mi1320_initQVGA_data[][4] = { +static const __u8 mi1320_initQVGA_data[][4] = { {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd}, @@ -478,15 +478,15 @@ static __u8 mi1320_initQVGA_data[][4] = { {} }; -static __u8 po3130_gamma[17] = { +static const __u8 po3130_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff }; -static __u8 po3130_matrix[9] = { +static const __u8 po3130_matrix[9] = { 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 }; -static __u8 po3130_initVGA_data[][4] = { +static const __u8 po3130_initVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, @@ -569,7 +569,7 @@ static __u8 po3130_initVGA_data[][4] = { {0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc}, {} }; -static __u8 po3130_rundata[][4] = { +static const __u8 po3130_rundata[][4] = { {0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa}, {0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa}, {0x00, 0x44, 0x40, 0xaa}, @@ -584,7 +584,7 @@ static __u8 po3130_rundata[][4] = { {} }; -static __u8 po3130_initQVGA_data[][4] = { +static const __u8 po3130_initQVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc}, {0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, @@ -670,16 +670,16 @@ static __u8 po3130_initQVGA_data[][4] = { {} }; -static __u8 hv7131r_gamma[17] = { +static const __u8 hv7131r_gamma[17] = { /* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */ 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1, 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff }; -static __u8 hv7131r_matrix[9] = { +static const __u8 hv7131r_matrix[9] = { 0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63 }; -static __u8 hv7131r_initVGA_data[][4] = { +static const __u8 hv7131r_initVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, @@ -722,7 +722,7 @@ static __u8 hv7131r_initVGA_data[][4] = { {} }; -static __u8 hv7131r_initQVGA_data[][4] = { +static const __u8 hv7131r_initQVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, {0xb3, 0x00, 0x24, 0xcc}, @@ -777,14 +777,14 @@ static __u8 hv7131r_initQVGA_data[][4] = { {} }; -static __u8 ov7660_gamma[17] = { +static const __u8 ov7660_gamma[17] = { 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff }; -static __u8 ov7660_matrix[9] = { +static const __u8 ov7660_matrix[9] = { 0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62 }; -static __u8 ov7660_initVGA_data[][4] = { +static const __u8 ov7660_initVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, @@ -842,7 +842,7 @@ static __u8 ov7660_initVGA_data[][4] = { {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, {} }; -static __u8 ov7660_initQVGA_data[][4] = { +static const __u8 ov7660_initQVGA_data[][4] = { {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc}, {0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc}, @@ -911,26 +911,26 @@ static __u8 ov7660_initQVGA_data[][4] = { {0x00, 0x00, 0x00, 0x00} }; -static __u8 ov7660_50HZ[][4] = { +static const __u8 ov7660_50HZ[][4] = { {0x00, 0x3b, 0x08, 0xaa}, {0x00, 0x9d, 0x40, 0xaa}, {0x00, 0x13, 0xa7, 0xaa}, {0x00, 0x00, 0x00, 0x00} }; -static __u8 ov7660_60HZ[][4] = { +static const __u8 ov7660_60HZ[][4] = { {0x00, 0x3b, 0x00, 0xaa}, {0x00, 0x9e, 0x40, 0xaa}, {0x00, 0x13, 0xa7, 0xaa}, {} }; -static __u8 ov7660_NoFliker[][4] = { +static const __u8 ov7660_NoFliker[][4] = { {0x00, 0x13, 0x87, 0xaa}, {} }; -static __u8 ov7670_initVGA_JPG[][4] = { +static const __u8 ov7670_initVGA_JPG[][4] = { {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, @@ -1058,7 +1058,7 @@ static __u8 ov7670_initVGA_JPG[][4] = { {}, }; -static __u8 ov7670_initQVGA_JPG[][4] = { +static const __u8 ov7670_initQVGA_JPG[][4] = { {0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, {0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd}, @@ -1200,7 +1200,7 @@ struct sensor_info { __u8 op; }; -static struct sensor_info sensor_info_data[] = { +static const struct sensor_info sensor_info_data[] = { /* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */ {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01}, {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05}, @@ -1282,7 +1282,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) int i; __u8 data; __u16 value; - struct sensor_info *ptsensor_info; + const struct sensor_info *ptsensor_info; reg_r(dev, 0xa1, 0xbfcf, &data, 1); PDEBUG(D_PROBE, "check sensor header %d", data); @@ -1309,7 +1309,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) } static __u8 i2c_write(struct usb_device *dev, - __u8 reg, __u8 *val, __u8 size) + __u8 reg, const __u8 *val, __u8 size) { __u8 retbyte; @@ -1341,7 +1341,7 @@ static __u8 i2c_write(struct usb_device *dev, } static void put_tab_to_reg(struct gspca_dev *gspca_dev, - __u8 *tab, __u8 tabsize, __u16 addr) + const __u8 *tab, __u8 tabsize, __u16 addr) { int j; __u16 ad = addr; @@ -1351,7 +1351,7 @@ static void put_tab_to_reg(struct gspca_dev *gspca_dev, } static void usb_exchange(struct gspca_dev *gspca_dev, - __u8 data[][4]) + const __u8 data[][4]) { struct usb_device *dev = gspca_dev->dev; int i = 0; @@ -1511,7 +1511,7 @@ static void setautogain(struct gspca_dev *gspca_dev) static void setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - static __u8 (*ov7660_freq_tb[3])[4] = + static const __u8 (*ov7660_freq_tb[3])[4] = {ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ}; if (sd->sensor != SENSOR_OV7660) @@ -1523,8 +1523,8 @@ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; /* __u8 tmp2; */ - __u8 *GammaT = NULL; - __u8 *MatrixT = NULL; + const __u8 *GammaT = NULL; + const __u8 *MatrixT = NULL; int mode; /* Assume start use the good resolution from gspca_dev->mode */ @@ -1673,7 +1673,7 @@ static void sd_close(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso pkt length */ { struct sd *sd = (struct sd *) gspca_dev; @@ -1739,13 +1739,13 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy(menu->name, "NoFliker"); + strcpy((char *) menu->name, "NoFliker"); return 0; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy(menu->name, "50 Hz"); + strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy(menu->name, "60 Hz"); + strcpy((char *) menu->name, "60 Hz"); return 0; } break; @@ -1754,7 +1754,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), @@ -1770,7 +1770,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index ccd24cb92b3f..878344e4d2ec 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); @@ -190,7 +190,7 @@ struct usb_action { __u16 idx; }; -static struct usb_action cs2102_Initial[] = { +static const struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, {0xa0, 0x01, 0x0000}, @@ -320,7 +320,7 @@ static struct usb_action cs2102_Initial[] = { {} }; -static struct usb_action cs2102_InitialScale[] = { +static const struct usb_action cs2102_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, {0xa0, 0x01, 0x0000}, @@ -449,7 +449,7 @@ static struct usb_action cs2102_InitialScale[] = { {0xa0, 0x40, 0x0118}, {} }; -static struct usb_action cs2102_50HZ[] = { +static const struct usb_action cs2102_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -474,7 +474,7 @@ static struct usb_action cs2102_50HZ[] = { {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ {} }; -static struct usb_action cs2102_50HZScale[] = { +static const struct usb_action cs2102_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -499,7 +499,7 @@ static struct usb_action cs2102_50HZScale[] = { {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ {} }; -static struct usb_action cs2102_60HZ[] = { +static const struct usb_action cs2102_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -524,7 +524,7 @@ static struct usb_action cs2102_60HZ[] = { {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ {} }; -static struct usb_action cs2102_60HZScale[] = { +static const struct usb_action cs2102_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -549,7 +549,7 @@ static struct usb_action cs2102_60HZScale[] = { {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ {} }; -static struct usb_action cs2102_NoFliker[] = { +static const struct usb_action cs2102_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -574,7 +574,7 @@ static struct usb_action cs2102_NoFliker[] = { {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ {} }; -static struct usb_action cs2102_NoFlikerScale[] = { +static const struct usb_action cs2102_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ @@ -601,7 +601,7 @@ static struct usb_action cs2102_NoFlikerScale[] = { }; /* CS2102_KOCOM */ -static struct usb_action cs2102K_Initial[] = { +static const struct usb_action cs2102K_Initial[] = { {0xa0, 0x11, 0x0002}, {0xa0, 0x03, 0x0008}, {0xa0, 0x08, 0x0010}, @@ -860,7 +860,7 @@ static struct usb_action cs2102K_Initial[] = { {} }; -static struct usb_action cs2102K_InitialScale[] = { +static const struct usb_action cs2102K_InitialScale[] = { {0xa0, 0x11, 0x0002}, {0xa0, 0x00, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -1437,7 +1437,7 @@ static struct usb_action cs2102K_InitialScale[] = { {} }; -static struct usb_action gc0305_Initial[] = { /* 640x480 */ +static const struct usb_action gc0305_Initial[] = { /* 640x480 */ {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -1501,7 +1501,7 @@ static struct usb_action gc0305_Initial[] = { /* 640x480 */ {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ {} }; -static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ +static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -1564,7 +1564,7 @@ static struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ {} }; -static struct usb_action gc0305_50HZ[] = { +static const struct usb_action gc0305_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */ @@ -1587,7 +1587,7 @@ static struct usb_action gc0305_50HZ[] = { /* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ {} }; -static struct usb_action gc0305_60HZ[] = { +static const struct usb_action gc0305_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */ @@ -1611,7 +1611,7 @@ static struct usb_action gc0305_60HZ[] = { {} }; -static struct usb_action gc0305_NoFliker[] = { +static const struct usb_action gc0305_NoFliker[] = { {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ @@ -1635,7 +1635,7 @@ static struct usb_action gc0305_NoFliker[] = { }; /* play poker with registers at your own risk !! */ -static struct usb_action hdcs2020xx_Initial[] = { +static const struct usb_action hdcs2020xx_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x03, 0x0008}, {0xa0, 0x0e, 0x0010}, @@ -1780,7 +1780,7 @@ static struct usb_action hdcs2020xx_Initial[] = { {} }; -static struct usb_action hdcs2020xx_InitialScale[] = { +static const struct usb_action hdcs2020xx_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x03, 0x0008}, {0xa0, 0x0e, 0x0010}, @@ -1922,7 +1922,7 @@ static struct usb_action hdcs2020xx_InitialScale[] = { /* {0xa0, 0x18, 0x00fe}, */ {} }; -static struct usb_action hdcs2020xb_Initial[] = { +static const struct usb_action hdcs2020xb_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x11, 0x0002}, {0xa0, 0x03, 0x0008}, /* qtable 0x05 */ @@ -2054,7 +2054,7 @@ static struct usb_action hdcs2020xb_Initial[] = { {0xa0, 0x40, 0x0118}, {} }; -static struct usb_action hdcs2020xb_InitialScale[] = { +static const struct usb_action hdcs2020xb_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x00, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -2182,7 +2182,7 @@ static struct usb_action hdcs2020xb_InitialScale[] = { {0xa0, 0x40, 0x0118}, {} }; -static struct usb_action hdcs2020b_50HZ[] = { +static const struct usb_action hdcs2020b_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ @@ -2203,7 +2203,7 @@ static struct usb_action hdcs2020b_50HZ[] = { {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ {} }; -static struct usb_action hdcs2020b_60HZ[] = { +static const struct usb_action hdcs2020b_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ @@ -2224,7 +2224,7 @@ static struct usb_action hdcs2020b_60HZ[] = { {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ {} }; -static struct usb_action hdcs2020b_NoFliker[] = { +static const struct usb_action hdcs2020b_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ @@ -2246,7 +2246,7 @@ static struct usb_action hdcs2020b_NoFliker[] = { {} }; -static struct usb_action hv7131bxx_Initial[] = { +static const struct usb_action hv7131bxx_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x10, 0x0002}, {0xa0, 0x00, 0x0010}, @@ -2354,7 +2354,7 @@ static struct usb_action hv7131bxx_Initial[] = { {} }; -static struct usb_action hv7131bxx_InitialScale[] = { +static const struct usb_action hv7131bxx_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x00, 0x0002}, {0xa0, 0x00, 0x0010}, @@ -2460,7 +2460,7 @@ static struct usb_action hv7131bxx_InitialScale[] = { {} }; -static struct usb_action hv7131cxx_Initial[] = { +static const struct usb_action hv7131cxx_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x10, 0x0002}, {0xa0, 0x01, 0x0010}, @@ -2554,7 +2554,7 @@ static struct usb_action hv7131cxx_Initial[] = { {} }; -static struct usb_action hv7131cxx_InitialScale[] = { +static const struct usb_action hv7131cxx_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x00, 0x0002}, /* diff */ @@ -2655,7 +2655,7 @@ static struct usb_action hv7131cxx_InitialScale[] = { {} }; -static struct usb_action icm105axx_Initial[] = { +static const struct usb_action icm105axx_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x10, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -2832,7 +2832,7 @@ static struct usb_action icm105axx_Initial[] = { {} }; -static struct usb_action icm105axx_InitialScale[] = { +static const struct usb_action icm105axx_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x00, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -3011,7 +3011,7 @@ static struct usb_action icm105axx_InitialScale[] = { {0xa0, 0x40, 0x0118}, {} }; -static struct usb_action icm105a_50HZ[] = { +static const struct usb_action icm105a_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ @@ -3042,7 +3042,7 @@ static struct usb_action icm105a_50HZ[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {} }; -static struct usb_action icm105a_50HZScale[] = { +static const struct usb_action icm105a_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ @@ -3075,7 +3075,7 @@ static struct usb_action icm105a_50HZScale[] = { {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ {} }; -static struct usb_action icm105a_60HZ[] = { +static const struct usb_action icm105a_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ @@ -3106,7 +3106,7 @@ static struct usb_action icm105a_60HZ[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {} }; -static struct usb_action icm105a_60HZScale[] = { +static const struct usb_action icm105a_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ @@ -3139,7 +3139,7 @@ static struct usb_action icm105a_60HZScale[] = { {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ {} }; -static struct usb_action icm105a_NoFliker[] = { +static const struct usb_action icm105a_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ @@ -3170,7 +3170,7 @@ static struct usb_action icm105a_NoFliker[] = { {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ {} }; -static struct usb_action icm105a_NoFlikerScale[] = { +static const struct usb_action icm105a_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ @@ -3204,7 +3204,7 @@ static struct usb_action icm105a_NoFlikerScale[] = { {} }; -static struct usb_action MC501CB_InitialScale[] = { +static const struct usb_action MC501CB_InitialScale[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x00, 0x0002}, /* 00,02,00,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -3324,7 +3324,7 @@ static struct usb_action MC501CB_InitialScale[] = { {} }; -static struct usb_action MC501CB_Initial[] = { /* 320x240 */ +static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -3443,7 +3443,7 @@ static struct usb_action MC501CB_Initial[] = { /* 320x240 */ {} }; -static struct usb_action MC501CB_50HZ[] = { +static const struct usb_action MC501CB_50HZ[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */ @@ -3460,7 +3460,7 @@ static struct usb_action MC501CB_50HZ[] = { {} }; -static struct usb_action MC501CB_50HZScale[] = { +static const struct usb_action MC501CB_50HZScale[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */ @@ -3477,7 +3477,7 @@ static struct usb_action MC501CB_50HZScale[] = { {} }; -static struct usb_action MC501CB_60HZ[] = { +static const struct usb_action MC501CB_60HZ[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ @@ -3494,7 +3494,7 @@ static struct usb_action MC501CB_60HZ[] = { {} }; -static struct usb_action MC501CB_60HZScale[] = { +static const struct usb_action MC501CB_60HZScale[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ @@ -3511,7 +3511,7 @@ static struct usb_action MC501CB_60HZScale[] = { {} }; -static struct usb_action MC501CB_NoFliker[] = { +static const struct usb_action MC501CB_NoFliker[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x0018}, /* 00,36,18,aa */ @@ -3528,7 +3528,7 @@ static struct usb_action MC501CB_NoFliker[] = { {} }; -static struct usb_action MC501CB_NoFlikerScale[] = { +static const struct usb_action MC501CB_NoFlikerScale[] = { {0xaa, 0x03, 0x0003}, /* 00,03,03,aa */ {0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */ {0xaa, 0x36, 0x0030}, /* 00,36,30,aa */ @@ -3541,7 +3541,7 @@ static struct usb_action MC501CB_NoFlikerScale[] = { }; /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ -static struct usb_action OV7620_mode0[] = { +static const struct usb_action OV7620_mode0[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x40, 0x0002}, /* 00,02,40,cc */ {0xa0, 0x00, 0x0008}, /* 00,08,00,cc */ @@ -3612,7 +3612,7 @@ static struct usb_action OV7620_mode0[] = { }; /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ -static struct usb_action OV7620_mode1[] = { +static const struct usb_action OV7620_mode1[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x50, 0x0002}, /* 00,02,50,cc */ {0xa0, 0x03, 0x0008}, /* 00,08,00,cc */ /* mx change? */ @@ -3683,7 +3683,7 @@ static struct usb_action OV7620_mode1[] = { }; /* from zs211.inf - HKR,%OV7620%\AE,50HZ */ -static struct usb_action OV7620_50HZ[] = { +static const struct usb_action OV7620_50HZ[] = { {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ @@ -3702,7 +3702,7 @@ static struct usb_action OV7620_50HZ[] = { }; /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ -static struct usb_action OV7620_60HZ[] = { +static const struct usb_action OV7620_60HZ[] = { {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ @@ -3724,7 +3724,7 @@ static struct usb_action OV7620_60HZ[] = { }; /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ -static struct usb_action OV7620_NoFliker[] = { +static const struct usb_action OV7620_NoFliker[] = { {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ @@ -3743,7 +3743,7 @@ static struct usb_action OV7620_NoFliker[] = { {} }; -static struct usb_action ov7630c_Initial[] = { +static const struct usb_action ov7630c_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x10, 0x0002}, {0xa0, 0x01, 0x0000}, @@ -3900,7 +3900,7 @@ static struct usb_action ov7630c_Initial[] = { {} }; -static struct usb_action ov7630c_InitialScale[] = { +static const struct usb_action ov7630c_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x00, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -4057,7 +4057,7 @@ static struct usb_action ov7630c_InitialScale[] = { {} }; -static struct usb_action pas106b_Initial_com[] = { +static const struct usb_action pas106b_Initial_com[] = { /* Sream and Sensor specific */ {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */ /* System */ @@ -4071,7 +4071,7 @@ static struct usb_action pas106b_Initial_com[] = { {} }; -static struct usb_action pas106b_Initial[] = { /* 176x144 */ +static const struct usb_action pas106b_Initial[] = { /* 176x144 */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ /* Sream and Sensor specific */ @@ -4189,7 +4189,7 @@ static struct usb_action pas106b_Initial[] = { /* 176x144 */ {} }; -static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ +static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ /* JPEG control */ {0xa0, 0x03, 0x0008}, /* ClockSetting */ /* Sream and Sensor specific */ @@ -4312,7 +4312,7 @@ static struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xa0, 0xff, 0x0018}, /* Frame adjust */ {} }; -static struct usb_action pas106b_50HZ[] = { +static const struct usb_action pas106b_50HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ {0xa0, 0x54, 0x0192}, /* 01,92,54,cc */ @@ -4328,7 +4328,7 @@ static struct usb_action pas106b_50HZ[] = { {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ {} }; -static struct usb_action pas106b_60HZ[] = { +static const struct usb_action pas106b_60HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ {0xa0, 0x2e, 0x0192}, /* 01,92,2e,cc */ @@ -4344,7 +4344,7 @@ static struct usb_action pas106b_60HZ[] = { {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ {} }; -static struct usb_action pas106b_NoFliker[] = { +static const struct usb_action pas106b_NoFliker[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ {0xa0, 0x50, 0x0192}, /* 01,92,50,cc */ @@ -4361,7 +4361,7 @@ static struct usb_action pas106b_NoFliker[] = { {} }; -static struct usb_action pb03303x_Initial[] = { +static const struct usb_action pb03303x_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x03, 0x0008}, {0xa0, 0x0a, 0x0010}, @@ -4507,7 +4507,7 @@ static struct usb_action pb03303x_Initial[] = { {} }; -static struct usb_action pb03303x_InitialScale[] = { +static const struct usb_action pb03303x_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x03, 0x0008}, {0xa0, 0x0a, 0x0010}, @@ -4655,7 +4655,7 @@ static struct usb_action pb03303x_InitialScale[] = { {0xa0, 0x42, 0x0180}, {} }; -static struct usb_action pb0330xx_Initial[] = { +static const struct usb_action pb0330xx_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, {0xa0, 0x01, 0x0000}, @@ -4770,7 +4770,7 @@ static struct usb_action pb0330xx_Initial[] = { {} }; -static struct usb_action pb0330xx_InitialScale[] = { +static const struct usb_action pb0330xx_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, {0xa0, 0x01, 0x0000}, @@ -4883,7 +4883,7 @@ static struct usb_action pb0330xx_InitialScale[] = { /* {0xa0, 0x00, 0x0007}, */ {} }; -static struct usb_action pb0330_50HZ[] = { +static const struct usb_action pb0330_50HZ[] = { {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ {0xa0, 0xee, 0x0192}, /* 01,92,ee,cc */ @@ -4899,7 +4899,7 @@ static struct usb_action pb0330_50HZ[] = { {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ {} }; -static struct usb_action pb0330_50HZScale[] = { +static const struct usb_action pb0330_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ @@ -4916,7 +4916,7 @@ static struct usb_action pb0330_50HZScale[] = { {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ {} }; -static struct usb_action pb0330_60HZ[] = { +static const struct usb_action pb0330_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ @@ -4933,7 +4933,7 @@ static struct usb_action pb0330_60HZ[] = { {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ {} }; -static struct usb_action pb0330_60HZScale[] = { +static const struct usb_action pb0330_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ @@ -4950,7 +4950,7 @@ static struct usb_action pb0330_60HZScale[] = { {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ {} }; -static struct usb_action pb0330_NoFliker[] = { +static const struct usb_action pb0330_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ @@ -4967,7 +4967,7 @@ static struct usb_action pb0330_NoFliker[] = { {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ {} }; -static struct usb_action pb0330_NoFlikerScale[] = { +static const struct usb_action pb0330_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ @@ -4986,7 +4986,7 @@ static struct usb_action pb0330_NoFlikerScale[] = { }; /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ -static struct usb_action PO2030_mode0[] = { +static const struct usb_action PO2030_mode0[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x04, 0x0002}, /* 00,02,04,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -5063,7 +5063,7 @@ static struct usb_action PO2030_mode0[] = { }; /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ -static struct usb_action PO2030_mode1[] = { +static const struct usb_action PO2030_mode1[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ @@ -5139,7 +5139,7 @@ static struct usb_action PO2030_mode1[] = { {} }; -static struct usb_action PO2030_50HZ[] = { +static const struct usb_action PO2030_50HZ[] = { {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ @@ -5161,7 +5161,7 @@ static struct usb_action PO2030_50HZ[] = { {} }; -static struct usb_action PO2030_60HZ[] = { +static const struct usb_action PO2030_60HZ[] = { {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ @@ -5183,7 +5183,7 @@ static struct usb_action PO2030_60HZ[] = { {} }; -static struct usb_action PO2030_NoFliker[] = { +static const struct usb_action PO2030_NoFliker[] = { {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ @@ -5195,7 +5195,7 @@ static struct usb_action PO2030_NoFliker[] = { }; /* TEST */ -static struct usb_action tas5130CK_Initial[] = { +static const struct usb_action tas5130CK_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x01, 0x003b}, {0xa0, 0x0e, 0x003a}, @@ -5398,7 +5398,7 @@ static struct usb_action tas5130CK_Initial[] = { {} }; -static struct usb_action tas5130CK_InitialScale[] = { +static const struct usb_action tas5130CK_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x01, 0x003b}, {0xa0, 0x0e, 0x003a}, @@ -5606,7 +5606,7 @@ static struct usb_action tas5130CK_InitialScale[] = { {} }; -static struct usb_action tas5130cxx_Initial[] = { +static const struct usb_action tas5130cxx_Initial[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x50, 0x0002}, {0xa0, 0x03, 0x0008}, @@ -5695,7 +5695,7 @@ static struct usb_action tas5130cxx_Initial[] = { {0xa0, 0x42, 0x0180}, {} }; -static struct usb_action tas5130cxx_InitialScale[] = { +static const struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x01, 0x0000}, {0xa0, 0x01, 0x0000}, {0xa0, 0x40, 0x0002}, @@ -5785,7 +5785,7 @@ static struct usb_action tas5130cxx_InitialScale[] = { {0xa0, 0x42, 0x0180}, {} }; -static struct usb_action tas5130cxx_50HZ[] = { +static const struct usb_action tas5130cxx_50HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */ @@ -5808,7 +5808,7 @@ static struct usb_action tas5130cxx_50HZ[] = { {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ {} }; -static struct usb_action tas5130cxx_50HZScale[] = { +static const struct usb_action tas5130cxx_50HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ @@ -5831,7 +5831,7 @@ static struct usb_action tas5130cxx_50HZScale[] = { {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ {} }; -static struct usb_action tas5130cxx_60HZ[] = { +static const struct usb_action tas5130cxx_60HZ[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */ @@ -5854,7 +5854,7 @@ static struct usb_action tas5130cxx_60HZ[] = { {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ {} }; -static struct usb_action tas5130cxx_60HZScale[] = { +static const struct usb_action tas5130cxx_60HZScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ @@ -5877,7 +5877,7 @@ static struct usb_action tas5130cxx_60HZScale[] = { {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ {} }; -static struct usb_action tas5130cxx_NoFliker[] = { +static const struct usb_action tas5130cxx_NoFliker[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */ @@ -5901,7 +5901,7 @@ static struct usb_action tas5130cxx_NoFliker[] = { {} }; -static struct usb_action tas5130cxx_NoFlikerScale[] = { +static const struct usb_action tas5130cxx_NoFlikerScale[] = { {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */ @@ -5925,7 +5925,7 @@ static struct usb_action tas5130cxx_NoFlikerScale[] = { {} }; -static struct usb_action tas5130c_vf0250_Initial[] = { +static const struct usb_action tas5130c_vf0250_Initial[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ @@ -5989,7 +5989,7 @@ static struct usb_action tas5130c_vf0250_Initial[] = { {} }; -static struct usb_action tas5130c_vf0250_InitialScale[] = { +static const struct usb_action tas5130c_vf0250_InitialScale[] = { {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ @@ -6053,7 +6053,7 @@ static struct usb_action tas5130c_vf0250_InitialScale[] = { {} }; /* "50HZ" light frequency banding filter */ -static struct usb_action tas5130c_vf0250_50HZ[] = { +static const struct usb_action tas5130c_vf0250_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ @@ -6078,7 +6078,7 @@ static struct usb_action tas5130c_vf0250_50HZ[] = { }; /* "50HZScale" light frequency banding filter */ -static struct usb_action tas5130c_vf0250_50HZScale[] = { +static const struct usb_action tas5130c_vf0250_50HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ @@ -6103,7 +6103,7 @@ static struct usb_action tas5130c_vf0250_50HZScale[] = { }; /* "60HZ" light frequency banding filter */ -static struct usb_action tas5130c_vf0250_60HZ[] = { +static const struct usb_action tas5130c_vf0250_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ @@ -6128,7 +6128,7 @@ static struct usb_action tas5130c_vf0250_60HZ[] = { }; /* "60HZScale" light frequency banding ilter */ -static struct usb_action tas5130c_vf0250_60HZScale[] = { +static const struct usb_action tas5130c_vf0250_60HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ @@ -6153,7 +6153,7 @@ static struct usb_action tas5130c_vf0250_60HZScale[] = { }; /* "NoFliker" light frequency banding flter */ -static struct usb_action tas5130c_vf0250_NoFliker[] = { +static const struct usb_action tas5130c_vf0250_NoFliker[] = { {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ @@ -6176,7 +6176,7 @@ static struct usb_action tas5130c_vf0250_NoFliker[] = { }; /* "NoFlikerScale" light frequency banding filter */ -static struct usb_action tas5130c_vf0250_NoFlikerScale[] = { +static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ @@ -6272,7 +6272,7 @@ static __u8 i2c_write(struct usb_device *dev, } static void usb_exchange(struct usb_device *dev, - struct usb_action *action) + const struct usb_action *action) { __u8 buffread; @@ -6304,12 +6304,12 @@ static void setmatrix(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i; - __u8 *matrix; - static __u8 gc0305_matrix[9] = + const __u8 *matrix; + static const __u8 gc0305_matrix[9] = {0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50}; - static __u8 ov7620_matrix[9] = + static const __u8 ov7620_matrix[9] = {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; - static __u8 po2030_matrix[9] = + static const __u8 po2030_matrix[9] = {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; switch (sd->sensor) { @@ -6361,7 +6361,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; int sharpness; __u8 retbyte; - static __u8 sharpness_tb[][2] = { + static const __u8 sharpness_tb[][2] = { {0x02, 0x03}, {0x04, 0x07}, {0x08, 0x0f}, @@ -6380,55 +6380,55 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - __u8 *Tgamma, *Tgradient; + const __u8 *Tgamma, *Tgradient; int g, i, k; - static __u8 kgamma_tb[16] = /* delta for contrast */ + static const __u8 kgamma_tb[16] = /* delta for contrast */ {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; - static __u8 kgrad_tb[16] = + static const __u8 kgrad_tb[16] = {0x1b, 0x06, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x04}; - static __u8 Tgamma_1[16] = + static const __u8 Tgamma_1[16] = {0x00, 0x00, 0x03, 0x0d, 0x1b, 0x2e, 0x45, 0x5f, 0x79, 0x93, 0xab, 0xc1, 0xd4, 0xe5, 0xf3, 0xff}; - static __u8 Tgradient_1[16] = + static const __u8 Tgradient_1[16] = {0x00, 0x01, 0x05, 0x0b, 0x10, 0x15, 0x18, 0x1a, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x0f, 0x0d, 0x06}; - static __u8 Tgamma_2[16] = + static const __u8 Tgamma_2[16] = {0x01, 0x0c, 0x1f, 0x3a, 0x53, 0x6d, 0x85, 0x9c, 0xb0, 0xc2, 0xd1, 0xde, 0xe9, 0xf2, 0xf9, 0xff}; - static __u8 Tgradient_2[16] = + static const __u8 Tgradient_2[16] = {0x05, 0x0f, 0x16, 0x1a, 0x19, 0x19, 0x17, 0x15, 0x12, 0x10, 0x0e, 0x0b, 0x09, 0x08, 0x06, 0x03}; - static __u8 Tgamma_3[16] = + static const __u8 Tgamma_3[16] = {0x04, 0x16, 0x30, 0x4e, 0x68, 0x81, 0x98, 0xac, 0xbe, 0xcd, 0xda, 0xe4, 0xed, 0xf5, 0xfb, 0xff}; - static __u8 Tgradient_3[16] = + static const __u8 Tgradient_3[16] = {0x0c, 0x16, 0x1b, 0x1c, 0x19, 0x18, 0x15, 0x12, 0x10, 0x0d, 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03}; - static __u8 Tgamma_4[16] = + static const __u8 Tgamma_4[16] = {0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8, 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff}; - static __u8 Tgradient_4[16] = + static const __u8 Tgradient_4[16] = {0x26, 0x22, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0d, 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02}; - static __u8 Tgamma_5[16] = + static const __u8 Tgamma_5[16] = {0x20, 0x4b, 0x6e, 0x8d, 0xa3, 0xb5, 0xc5, 0xd2, 0xdc, 0xe5, 0xec, 0xf2, 0xf6, 0xfa, 0xfd, 0xff}; - static __u8 Tgradient_5[16] = + static const __u8 Tgradient_5[16] = {0x37, 0x26, 0x20, 0x1a, 0x14, 0x10, 0x0e, 0x0b, 0x09, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x02}; - static __u8 Tgamma_6[16] = /* ?? was gamma 5 */ + static const __u8 Tgamma_6[16] = /* ?? was gamma 5 */ {0x24, 0x44, 0x64, 0x84, 0x9d, 0xb2, 0xc4, 0xd3, 0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff}; - static __u8 Tgradient_6[16] = + static const __u8 Tgradient_6[16] = {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e, 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01}; - static __u8 *gamma_tb[] = { + static const __u8 *gamma_tb[] = { 0, Tgamma_1, Tgamma_2, Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6 }; - static __u8 *gradient_tb[] = { + static const __u8 *gradient_tb[] = { 0, Tgradient_1, Tgradient_2, Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 }; @@ -6529,8 +6529,8 @@ static int setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; int i, mode; - struct usb_action *zc3_freq; - static struct usb_action *freq_tb[SENSOR_MAX][6] = { + const struct usb_action *zc3_freq; + static const struct usb_action *freq_tb[SENSOR_MAX][6] = { /* SENSOR_CS2102 0 */ {cs2102_NoFliker, cs2102_NoFlikerScale, cs2102_50HZ, cs2102_50HZScale, @@ -6952,7 +6952,7 @@ static int sd_config(struct gspca_dev *gspca_dev, int sensor; __u8 bsensor; int vga = 1; /* 1: vga, 0: sif */ - static __u8 gamma[SENSOR_MAX] = { + static const __u8 gamma[SENSOR_MAX] = { 5, /* SENSOR_CS2102 0 */ 5, /* SENSOR_CS2102K 1 */ 4, /* SENSOR_GC0305 2 */ @@ -7145,10 +7145,10 @@ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; - struct usb_action *zc3_init; + const struct usb_action *zc3_init; int mode; __u8 retbyte; - static struct usb_action *init_tb[SENSOR_MAX][2] = { + static const struct usb_action *init_tb[SENSOR_MAX][2] = { {cs2102_InitialScale, cs2102_Initial}, /* 0 */ {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ {gc0305_Initial, gc0305_InitialScale}, /* 2 */ @@ -7451,13 +7451,13 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, case V4L2_CID_POWER_LINE_FREQUENCY: switch (menu->index) { case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ - strcpy(menu->name, "NoFliker"); + strcpy((char *) menu->name, "NoFliker"); return 0; case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy(menu->name, "50 Hz"); + strcpy((char *) menu->name, "50 Hz"); return 0; case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ - strcpy(menu->name, "60 Hz"); + strcpy((char *) menu->name, "60 Hz"); return 0; } break; @@ -7465,7 +7465,7 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, return -EINVAL; } -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], @@ -7480,7 +7480,7 @@ static struct sd_desc sd_desc = { }; #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, -- cgit v1.2.3 From 24c530b4abb979f9e79298f0b4c4e83781a0e4c3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 4 Jul 2008 17:55:18 -0300 Subject: V4L/DVB (8196): gspca: Correct sizeimage in vidioc_s/try/g_fmt_cap Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index ad4721b06920..f6d216316b11 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -43,8 +43,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 2) -static const char version[] = "2.1.2"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) +static const char version[] = "2.1.4"; static int video_nr = -1; @@ -391,14 +391,20 @@ static __u32 get_v4l2_depth(__u32 pixfmt) return 24; } -static int gspca_get_buff_size(struct gspca_dev *gspca_dev) +static int gspca_get_buff_size(struct gspca_dev *gspca_dev, int mode) { unsigned int size; - size = gspca_dev->width * gspca_dev->height - * get_v4l2_depth(gspca_dev->pixfmt) / 8; + size = gspca_dev->cam.cam_mode[mode].width * + gspca_dev->cam.cam_mode[mode].height * + get_v4l2_depth(gspca_dev->cam.cam_mode[mode].pixfmt) / 8; if (!size) return -ENOMEM; + + /* if compressed (JPEG), reduce the buffer size */ + if (gspca_is_compressed(gspca_dev->cam.cam_mode[mode].pixfmt)) + size = (size * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ + return size; } @@ -409,15 +415,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev, unsigned int frsz; int i; - frsz = gspca_get_buff_size(gspca_dev); + frsz = gspca_get_buff_size(gspca_dev, gspca_dev->curr_mode); if (frsz < 0) return frsz; PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); if (count > GSPCA_MAX_FRAMES) count = GSPCA_MAX_FRAMES; - /* if compressed (JPEG), reduce the buffer size */ - if (gspca_is_compressed(gspca_dev->pixfmt)) - frsz = (frsz * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ frsz = PAGE_ALIGN(frsz); PDEBUG(D_STREAM, "new fr_sz: %d", frsz); gspca_dev->frsz = frsz; @@ -796,8 +799,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, fmt->fmt.pix.field = V4L2_FIELD_NONE; fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) * fmt->fmt.pix.width / 8; - fmt->fmt.pix.sizeimage = fmt->fmt.pix.bytesperline - * fmt->fmt.pix.height; + fmt->fmt.pix.sizeimage = gspca_get_buff_size(gspca_dev, + gspca_dev->curr_mode); /* (should be in the subdriver) */ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; fmt->fmt.pix.priv = 0; @@ -807,7 +810,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, struct v4l2_format *fmt) { - int w, h, mode, mode2, frsz; + int w, h, mode, mode2; if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -849,12 +852,10 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, } fmt->fmt.pix.width = gspca_dev->cam.cam_mode[mode].width; fmt->fmt.pix.height = gspca_dev->cam.cam_mode[mode].height; + fmt->fmt.pix.field = V4L2_FIELD_NONE; fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) * fmt->fmt.pix.width / 8; - frsz = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height; - if (gspca_is_compressed(fmt->fmt.pix.pixelformat)) - frsz = (frsz * comp_fac) / 100; - fmt->fmt.pix.sizeimage = frsz; + fmt->fmt.pix.sizeimage = gspca_get_buff_size(gspca_dev, mode); return mode; /* used when s_fmt */ } -- cgit v1.2.3 From ab8f12cf8e3d33adec382585f9f60f8686a372c3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 4 Jul 2008 18:29:32 -0300 Subject: V4L/DVB (8197): gspca: pac207 frames no more decoded in the subdriver. videodev2: New pixfmt pac207: Remove the specific decoding. main: get_buff_size operation added for the subdriver. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 7 +- drivers/media/video/gspca/gspca.h | 2 + drivers/media/video/gspca/pac207.c | 353 +++++-------------------------------- include/linux/videodev2.h | 3 +- 4 files changed, 53 insertions(+), 312 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index f6d216316b11..708270a46e1f 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -321,6 +321,7 @@ static int gspca_is_compressed(__u32 format) case V4L2_PIX_FMT_MJPEG: case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SPCA561: + case V4L2_PIX_FMT_PAC207: return 1; } return 0; @@ -380,7 +381,8 @@ static __u32 get_v4l2_depth(__u32 pixfmt) case V4L2_PIX_FMT_JPEG: case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ - case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed BGGR bayer */ + case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed GBRG bayer */ + case V4L2_PIX_FMT_PAC207: /* 'P207' compressed BGGR bayer */ return 8; } PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", @@ -395,6 +397,9 @@ static int gspca_get_buff_size(struct gspca_dev *gspca_dev, int mode) { unsigned int size; + if (gspca_dev->sd_desc->get_buff_size) + return gspca_dev->sd_desc->get_buff_size(gspca_dev, mode); + size = gspca_dev->cam.cam_mode[mode].width * gspca_dev->cam.cam_mode[mode].height * get_v4l2_depth(gspca_dev->cam.cam_mode[mode].pixfmt) / 8; diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 0d23e0a90c77..05e8ee06071b 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -80,6 +80,7 @@ typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len); +typedef int (*cam_get_buff_size_op) (struct gspca_dev *gspca_dev, int mode); struct ctrl { struct v4l2_queryctrl qctrl; @@ -106,6 +107,7 @@ struct sd_desc { cam_jpg_op get_jcomp; cam_jpg_op set_jcomp; cam_qmnu_op querymenu; + cam_get_buff_size_op get_buff_size; /* optional */ }; /* packet types when moving from iso buf to frame buf */ diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 7e067456e62b..0135ba599e81 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -58,34 +58,10 @@ MODULE_LICENSE("GPL"); before doing any other adjustments */ #define PAC207_AUTOGAIN_IGNORE_FRAMES 3 -enum pac207_line_state { - LINE_HEADER1, - LINE_HEADER2, - LINE_UNCOMPRESSED, - LINE_COMPRESSED, -}; - -struct pac207_decoder_state { - /* generic state */ - u16 line_read; - u16 line_marker; - u8 line_state; - u8 header_read; - /* compression state */ - u16 processed_bytes; - u8 remaining_bits; - s8 no_remaining_bits; - u8 get_abs; - u8 discard_byte; - u8 line_decode_buf[352]; -}; - /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - struct pac207_decoder_state decoder_state; - u8 mode; u8 brightness; @@ -94,6 +70,7 @@ struct sd { u8 gain; u8 sof_read; + u8 header_read; u8 autogain_ignore_frames; atomic_t avg_lum; @@ -173,8 +150,8 @@ static struct ctrl sd_ctrls[] = { }; static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, - {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, + {V4L2_PIX_FMT_PAC207, 176, 144, 1}, + {V4L2_PIX_FMT_PAC207, 352, 288, 0}, }; static const __u8 pac207_sensor_init[][8] = { @@ -361,68 +338,17 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* -- convert pixart frames to Bayer -- */ -/* Sonix decompressor struct B.S.(2004) */ -static struct { - u8 is_abs; - u8 len; - s8 val; -} table[256]; - -void init_pixart_decoder(void) +static int sd_get_buff_size_op(struct gspca_dev *gspca_dev, int mode) { - int i, is_abs, val, len; - - for (i = 0; i < 256; i++) { - is_abs = 0; - val = 0; - len = 0; - if ((i & 0xC0) == 0) { - /* code 00 */ - val = 0; - len = 2; - } else if ((i & 0xC0) == 0x40) { - /* code 01 */ - val = -5; - len = 2; - } else if ((i & 0xC0) == 0x80) { - /* code 10 */ - val = 5; - len = 2; - } else if ((i & 0xF0) == 0xC0) { - /* code 1100 */ - val = -10; - len = 4; - } else if ((i & 0xF0) == 0xD0) { - /* code 1101 */ - val = 10; - len = 4; - } else if ((i & 0xF8) == 0xE0) { - /* code 11100 */ - val = -15; - len = 5; - } else if ((i & 0xF8) == 0xE8) { - /* code 11101 */ - val = 15; - len = 5; - } else if ((i & 0xFC) == 0xF0) { - /* code 111100 */ - val = -20; - len = 6; - } else if ((i & 0xFC) == 0xF4) { - /* code 111101 */ - val = 20; - len = 6; - } else if ((i & 0xF8) == 0xF8) { - /* code 11111xxxxxx */ - is_abs = 1; - val = 0; - len = 5; - } - table[i].is_abs = is_abs; - table[i].val = val; - table[i].len = len; + switch (gspca_dev->cam.cam_mode[mode].width) { + case 176: /* 176x144 */ + /* uncompressed, add 2 bytes / line for line header */ + return (176 + 2) * 144; + case 352: /* 352x288 */ + /* compressed */ + return 352 * 288 / 2; } + return -EIO; /* should never happen */ } /* auto gain and exposure algorithm based on the knee algorithm described here: @@ -517,245 +443,52 @@ static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, return NULL; } -static int pac207_decompress_row(struct gspca_dev *gspca_dev, - struct gspca_frame *f, - __u8 *cdata, - int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct pac207_decoder_state *decoder_state = &sd->decoder_state; - unsigned char *outp = decoder_state->line_decode_buf + - decoder_state->line_read; - int val, bitlen, bitpos = -decoder_state->no_remaining_bits; - u8 code; - - /* first two pixels are stored as raw 8-bit */ - while (decoder_state->line_read < 2) { - *outp++ = *cdata++; - decoder_state->line_read++; - len--; - if (len == 0) - return 0; - } - - while (decoder_state->line_read < gspca_dev->width) { - if (bitpos < 0) { - code = decoder_state->remaining_bits << (8 + bitpos) | - cdata[0] >> -bitpos; - } else { - u8 *addr = cdata + bitpos / 8; - code = addr[0] << (bitpos & 7) | - addr[1] >> (8 - (bitpos & 7)); - } - - bitlen = decoder_state->get_abs ? - 6 : table[code].len; - - /* Stop decompressing if we're out of input data */ - if ((bitpos + bitlen) > (len * 8)) - break; - - if (decoder_state->get_abs) { - *outp++ = code & 0xFC; - decoder_state->line_read++; - decoder_state->get_abs = 0; - } else { - if (table[code].is_abs) { - decoder_state->get_abs = 1; - } else { - /* relative to left pixel */ - val = outp[-2] + - table[code].val; - if (val > 0xff) - val = 0xff; - else if (val < 0) - val = 0; - *outp++ = val; - decoder_state->line_read++; - } - } - bitpos += bitlen; - } - - if (decoder_state->line_read == gspca_dev->width) { - int compressed_line_len; - - gspca_frame_add(gspca_dev, INTER_PACKET, f, - decoder_state->line_decode_buf, - gspca_dev->width); - - /* completely decompressed line, round pos to nearest word */ - compressed_line_len = ((decoder_state->processed_bytes * 8 + - bitpos + 15) / 16) * 2; - - len -= compressed_line_len - decoder_state->processed_bytes; - if (len < 0) { - decoder_state->discard_byte = 1; - len = 0; - } - } else { - decoder_state->processed_bytes += len; - decoder_state->remaining_bits = cdata[bitpos/8]; - decoder_state->no_remaining_bits = (8 - bitpos) & 7; - len = 0; - } - - return len; -} - -static void pac207_decode_line_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct pac207_decoder_state *decoder_state = &sd->decoder_state; - - decoder_state->line_read = 0; - decoder_state->line_state = LINE_HEADER1; - decoder_state->processed_bytes = 0; - decoder_state->no_remaining_bits = 0; - decoder_state->get_abs = 0; -} - -static void pac207_decode_frame_init(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct pac207_decoder_state *decoder_state = &sd->decoder_state; - - decoder_state->header_read = 0; - decoder_state->discard_byte = 0; - - pac207_decode_line_init(gspca_dev); -} - -static int pac207_decode_frame_data(struct gspca_dev *gspca_dev, - struct gspca_frame *f, unsigned char *data, int len) -{ - struct sd *sd = (struct sd *) gspca_dev; - struct pac207_decoder_state *decoder_state = &sd->decoder_state; - int needed = 0; - - /* first 11 bytes after sof marker: frame header */ - if (decoder_state->header_read < 11) { - /* get average lumination from frame header (byte 5) */ - if (decoder_state->header_read < 5) { - needed = 5 - decoder_state->header_read; - if (len >= needed) - atomic_set(&sd->avg_lum, data[needed-1]); - } - /* skip the rest of the header */ - needed = 11 - decoder_state->header_read; - if (len <= needed) { - decoder_state->header_read += len; - return 0; - } - data += needed; - len -= needed; - decoder_state->header_read = 11; - } - - while (len) { - if (decoder_state->discard_byte) { - data++; - len--; - decoder_state->discard_byte = 0; - continue; - } - - switch (decoder_state->line_state) { - case LINE_HEADER1: - decoder_state->line_marker = data[0] << 8; - decoder_state->line_state = LINE_HEADER2; - needed = 1; - break; - case LINE_HEADER2: - decoder_state->line_marker |= data[0]; - switch (decoder_state->line_marker) { - case 0x0ff0: - decoder_state->line_state = LINE_UNCOMPRESSED; - break; - case 0x1ee1: - decoder_state->line_state = LINE_COMPRESSED; - break; - default: - PDEBUG(D_STREAM, - "Error unknown line-header %04X", - (int) decoder_state->line_marker); - gspca_dev->last_packet_type = DISCARD_PACKET; - return 0; - } - needed = 1; - break; - case LINE_UNCOMPRESSED: - needed = gspca_dev->width - decoder_state->line_read; - if (needed > len) - needed = len; - gspca_frame_add(gspca_dev, INTER_PACKET, f, data, - needed); - decoder_state->line_read += needed; - break; - case LINE_COMPRESSED: - needed = len - - pac207_decompress_row(gspca_dev, f, data, len); - break; - } - - data += needed; - len -= needed; - - if (decoder_state->line_read == gspca_dev->width) { - if ((f->data_end - f->data) == - (gspca_dev->width * gspca_dev->height)) { - /* eureka we've got a frame */ - return 1; - } - pac207_decode_line_init(gspca_dev); - } - } - - return 0; -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len) { + struct sd *sd = (struct sd *) gspca_dev; unsigned char *sof; - int n; sof = pac207_find_sof(gspca_dev, data, len); - if (sof) { + int n; + /* finish decoding current frame */ - if (gspca_dev->last_packet_type == INTER_PACKET) { - n = sof - data; - if (n > sizeof(pac207_sof_marker)) - n -= sizeof(pac207_sof_marker); - else - n = 0; - n = pac207_decode_frame_data(gspca_dev, frame, - data, n); - if (n) - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - NULL, - 0); - else - PDEBUG(D_STREAM, "Incomplete frame"); - } - pac207_decode_frame_init(gspca_dev); + n = sof - data; + if (n > sizeof pac207_sof_marker) + n -= sizeof pac207_sof_marker; + else + n = 0; + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, n); + sd->header_read = 0; gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); len -= sof - data; data = sof; } + if (sd->header_read < 11) { + int needed; - if (gspca_dev->last_packet_type == DISCARD_PACKET) - return; + /* get average lumination from frame header (byte 5) */ + if (sd->header_read < 5) { + needed = 5 - sd->header_read; + if (len >= needed) + atomic_set(&sd->avg_lum, data[needed - 1]); + } + /* skip the rest of the header */ + needed = 11 - sd->header_read; + if (len <= needed) { + sd->header_read += len; + return; + } + data += needed; + len -= needed; + sd->header_read = 11; + } - n = pac207_decode_frame_data(gspca_dev, frame, data, len); - if (n) - gspca_frame_add(gspca_dev, LAST_PACKET, - frame, NULL, 0); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } static void setbrightness(struct gspca_dev *gspca_dev) @@ -891,6 +624,7 @@ static const struct sd_desc sd_desc = { .close = sd_close, .dq_callback = pac207_do_auto_gain, .pkt_scan = sd_pkt_scan, + .get_buff_size = sd_get_buff_size_op, }; /* -- module initialisation -- */ @@ -927,7 +661,6 @@ static struct usb_driver sd_driver = { /* -- module insert / remove -- */ static int __init sd_mod_init(void) { - init_pixart_decoder(); if (usb_register(&sd_driver) < 0) return -1; PDEBUG(D_PROBE, "v%s registered", version); diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 577f15634791..2e66a95e8d32 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -326,7 +326,8 @@ struct v4l2_pix_format #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E','6','2','5') /* ET61X251 compression */ #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S','5','0','1') /* YUYV per line */ -#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S','5','6','1') /* compressed BGGR bayer */ +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S','5','6','1') /* compressed GBRG bayer */ +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P','2','0','7') /* compressed BGGR bayer */ /* * F O R M A T E N U M E R A T I O N -- cgit v1.2.3 From 46ccdafa71c1c95de002ce7a31e700cf5c8195df Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 4 Jul 2008 18:39:08 -0300 Subject: V4L/DVB (8198): gspca: Frame decoding errors when PAC207 in full daylight. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac207.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 0135ba599e81..ab83d7b69348 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -40,9 +40,17 @@ MODULE_LICENSE("GPL"); #define PAC207_BRIGHTNESS_MAX 255 #define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */ -#define PAC207_EXPOSURE_MIN 4 +/* An exposure value of 4 also works (3 does not) but then we need to lower + the compression balance setting when in 352x288 mode, otherwise the usb + bandwidth is not enough and packets get dropped resulting in corrupt + frames. The problem with this is that when the compression balance gets + lowered below 0x80, the pac207 starts using a different compression + algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix + and currently we do not know how to decompress these lines, so for now + we use a minimum exposure value of 5 */ +#define PAC207_EXPOSURE_MIN 5 #define PAC207_EXPOSURE_MAX 26 -#define PAC207_EXPOSURE_DEFAULT 4 /* power on default: 3 ?? */ +#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 ?? */ #define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */ #define PAC207_GAIN_MIN 0 -- cgit v1.2.3 From efab8211db79d20032fa7d09b8a3671e68a9c5b9 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 5 Jul 2008 06:12:47 -0300 Subject: V4L/DVB (8199): gspca: Compile warnings about NULL ptr. Signed-off-by: Harvey Harrison Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 17 +++++++++-------- drivers/media/video/gspca/t613.c | 36 ++++++++++++++++++------------------ drivers/media/video/gspca/zc3xx.c | 30 +++++++++++++++--------------- 3 files changed, 42 insertions(+), 41 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 708270a46e1f..1225c0fe26f0 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -334,7 +334,7 @@ static void *rvmalloc(unsigned long size) /* size = PAGE_ALIGN(size); (already done) */ mem = vmalloc_32(size); - if (mem != 0) { + if (mem != NULL) { memset(mem, 0, size); adr = (unsigned long) mem; while ((long) size > 0) { @@ -464,7 +464,7 @@ static void frame_free(struct gspca_dev *gspca_dev) int i; PDEBUG(D_STREAM, "frame free"); - if (gspca_dev->frbuf != 0) { + if (gspca_dev->frbuf != NULL) { rvfree(gspca_dev->frbuf, gspca_dev->nframes * gspca_dev->frsz); gspca_dev->frbuf = NULL; @@ -487,7 +487,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev) gspca_dev->urb[i] = NULL; usb_kill_urb(urb); - if (urb->transfer_buffer != 0) + if (urb->transfer_buffer != NULL) usb_buffer_free(gspca_dev->dev, urb->transfer_buffer_length, urb->transfer_buffer, @@ -991,7 +991,7 @@ static int dev_close(struct inode *inode, struct file *file) gspca_dev->sd_desc->close(gspca_dev); mutex_unlock(&gspca_dev->usb_lock); frame_free(gspca_dev); - gspca_dev->capt_file = 0; + gspca_dev->capt_file = NULL; gspca_dev->memory = GSPCA_MEMORY_NO; } file->private_data = NULL; @@ -1165,7 +1165,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, } /* only one file may do capture */ - if ((gspca_dev->capt_file != 0 && gspca_dev->capt_file != file) + if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file) || gspca_dev->streaming) { ret = -EBUSY; goto out; @@ -1173,7 +1173,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rb->count == 0) { /* unrequest? */ frame_free(gspca_dev); - gspca_dev->capt_file = 0; + gspca_dev->capt_file = NULL; } else { gspca_dev->memory = rb->memory; ret = frame_alloc(gspca_dev, rb->count); @@ -1382,7 +1382,7 @@ static int vidiocgmbuf(struct file *file, void *priv, static int dev_mmap(struct file *file, struct vm_area_struct *vma) { struct gspca_dev *gspca_dev = file->private_data; - struct gspca_frame *frame = 0; + struct gspca_frame *frame; struct page *page; unsigned long addr, start, size; int i, ret; @@ -1405,6 +1405,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) goto out; } + frame = NULL; for (i = 0; i < gspca_dev->nframes; ++i) { if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) { PDEBUG(D_STREAM, "mmap bad memory type"); @@ -1416,7 +1417,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) break; } } - if (frame == 0) { + if (frame == NULL) { PDEBUG(D_STREAM, "mmap no frame buffer found"); ret = -EINVAL; goto out; diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 4e69a8e16357..96f01d267475 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -504,31 +504,31 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); t16RegRead(dev, 0x0080, &test_byte, 1); - t16RegWrite(dev, 0x00, 0x2c80, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x2c80, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); - t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0); - t16RegWrite(dev, 0x00, 0x3880, NULL, 0x0); - t16RegWrite(dev, 0x00, 0x338e, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x3880, NULL, 0); + t16RegWrite(dev, 0x00, 0x3880, NULL, 0); + t16RegWrite(dev, 0x00, 0x338e, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04); - t16RegWrite(dev, 0x00, 0x00a9, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x00a9, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22); - t16RegWrite(dev, 0x00, 0x86bb, NULL, 0x0); - t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x86bb, NULL, 0); + t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, missing, 0x08); - t16RegWrite(dev, 0x00, 0x2087, NULL, 0x0); - t16RegWrite(dev, 0x00, 0x2088, NULL, 0x0); - t16RegWrite(dev, 0x00, 0x2089, NULL, 0x0); + t16RegWrite(dev, 0x00, 0x2087, NULL, 0); + t16RegWrite(dev, 0x00, 0x2088, NULL, 0); + t16RegWrite(dev, 0x00, 0x2089, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04); t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06); t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06); t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04); - t16RegWrite(dev, 0x00, 0x2880, NULL, 0x00); + t16RegWrite(dev, 0x00, 0x2880, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); @@ -581,9 +581,9 @@ static void seteffect(struct gspca_dev *gspca_dev) } if (sd->effect == 1 || sd->effect == 4) - t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0x00); + t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); else - t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0x00); + t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0); } static void setwhitebalance(struct gspca_dev *gspca_dev) @@ -649,7 +649,7 @@ static void setsharpness(struct gspca_dev *gspca_dev) reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - t16RegWrite(dev, 0x00, reg_to_write, NULL, 0x00); + t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -870,16 +870,16 @@ static void sd_start(struct gspca_dev *gspca_dev) t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00); + t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); /* just in case and to keep sync with logs (for mine) */ t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, NULL, 0x00); + t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); /* just in case and to keep sync with logs (for mine) */ t16RegWrite(dev, 0x01, 0x0000, t1, 4); t16RegWrite(dev, 0x01, 0x0000, t2, 6); - t16RegRead(dev, 0x0012, &test_byte, 0x1); + t16RegRead(dev, 0x0012, &test_byte, 0x01); t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); - t16RegWrite(dev, 0x00, 0x0013, NULL, 0x00); + t16RegWrite(dev, 0x00, 0x0013, NULL, 0); t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); /* restart on each start, just in case, sometimes regs goes wrong * when using controls from app */ diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 878344e4d2ec..63dd8916d6b6 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -6425,11 +6425,11 @@ static void setcontrast(struct gspca_dev *gspca_dev) {0x18, 0x20, 0x20, 0x1c, 0x16, 0x13, 0x10, 0x0e, 0x0b, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01}; static const __u8 *gamma_tb[] = { - 0, Tgamma_1, Tgamma_2, + NULL, Tgamma_1, Tgamma_2, Tgamma_3, Tgamma_4, Tgamma_5, Tgamma_6 }; static const __u8 *gradient_tb[] = { - 0, Tgradient_1, Tgradient_2, + NULL, Tgradient_1, Tgradient_2, Tgradient_3, Tgradient_4, Tgradient_5, Tgradient_6 }; #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -6544,21 +6544,21 @@ static int setlightfreq(struct gspca_dev *gspca_dev) gc0305_50HZ, gc0305_50HZ, gc0305_60HZ, gc0305_60HZ}, /* SENSOR_HDCS2020 3 */ - {0, 0, - 0, 0, - 0, 0}, + {NULL, NULL, + NULL, NULL, + NULL, NULL}, /* SENSOR_HDCS2020b 4 */ {hdcs2020b_NoFliker, hdcs2020b_NoFliker, hdcs2020b_50HZ, hdcs2020b_50HZ, hdcs2020b_60HZ, hdcs2020b_60HZ}, /* SENSOR_HV7131B 5 */ - {0, 0, - 0, 0, - 0, 0}, + {NULL, NULL, + NULL, NULL, + NULL, NULL}, /* SENSOR_HV7131C 6 */ - {0, 0, - 0, 0, - 0, 0}, + {NULL, NULL, + NULL, NULL, + NULL, NULL}, /* SENSOR_ICM105A 7 */ {icm105a_NoFliker, icm105a_NoFlikerScale, icm105a_50HZ, icm105a_50HZScale, @@ -6572,9 +6572,9 @@ static int setlightfreq(struct gspca_dev *gspca_dev) OV7620_50HZ, OV7620_50HZ, OV7620_60HZ, OV7620_60HZ}, /* SENSOR_OV7630C 10 */ - {0, 0, - 0, 0, - 0, 0}, + {NULL, NULL, + NULL, NULL, + NULL, NULL}, /* SENSOR_PAS106 11 */ {pas106b_NoFliker, pas106b_NoFliker, pas106b_50HZ, pas106b_50HZ, @@ -6606,7 +6606,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev) if (!mode) i++; /* 640x480 */ zc3_freq = freq_tb[(int) sd->sensor][i]; - if (zc3_freq != 0) { + if (zc3_freq != NULL) { usb_exchange(gspca_dev->dev, zc3_freq); switch (sd->sensor) { case SENSOR_GC0305: -- cgit v1.2.3 From c2446b3eba97243acbe2ad0939a28b5edb97eae7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 5 Jul 2008 11:49:20 -0300 Subject: V4L/DVB (8201): gspca: v4l2_pix_format in each subdriver. main: Parameter comp_fac removed. main, pac207: get_buff_size op removed. (all) v4l2_pix_format in each subdriver. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 54 ++++++++++----- drivers/media/video/gspca/etoms.c | 42 +++++++---- drivers/media/video/gspca/gspca.c | 134 +++++++----------------------------- drivers/media/video/gspca/gspca.h | 13 +--- drivers/media/video/gspca/mars.c | 18 +++-- drivers/media/video/gspca/ov519.c | 32 ++++++--- drivers/media/video/gspca/pac207.c | 33 ++++----- drivers/media/video/gspca/pac7311.c | 26 +++++-- drivers/media/video/gspca/sonixb.c | 41 ++++++++--- drivers/media/video/gspca/sonixj.c | 26 +++++-- drivers/media/video/gspca/spca500.c | 34 ++++++--- drivers/media/video/gspca/spca501.c | 26 +++++-- drivers/media/video/gspca/spca505.c | 38 +++++++--- drivers/media/video/gspca/spca506.c | 52 +++++++++----- drivers/media/video/gspca/spca508.c | 32 ++++++--- drivers/media/video/gspca/spca561.c | 32 ++++++--- drivers/media/video/gspca/stk014.c | 18 +++-- drivers/media/video/gspca/sunplus.c | 60 ++++++++++++---- drivers/media/video/gspca/t613.c | 38 +++++++--- drivers/media/video/gspca/tv8532.c | 20 ++++-- drivers/media/video/gspca/vc032x.c | 34 ++++++--- drivers/media/video/gspca/zc3xx.c | 36 +++++++--- 22 files changed, 519 insertions(+), 320 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 6d50247b7ad2..b5481017dd4f 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -25,8 +25,8 @@ #define CONEX_CAM 1 /* special JPEG header */ #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); @@ -52,7 +52,6 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -61,12 +60,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 0xd4, +#define BRIGHTNESS_DEF 0xd4 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 { { .id = V4L2_CID_CONTRAST, @@ -75,12 +74,12 @@ static struct ctrl sd_ctrls[] = { .minimum = 0x0a, .maximum = 0x1f, .step = 1, - .default_value = 0x0c, +#define CONTRAST_DEF 0x0c + .default_value = CONTRAST_DEF, }, .set = sd_setcontrast, .get = sd_getcontrast, }, -#define SD_COLOR 2 { { .id = V4L2_CID_SATURATION, @@ -89,18 +88,35 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 7, .step = 1, - .default_value = 3, +#define COLOR_DEF 3 + .default_value = COLOR_DEF, }, .set = sd_setcolors, .get = sd_getcolors, }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 176, 144, 3}, - {V4L2_PIX_FMT_JPEG, 320, 240, 2}, - {V4L2_PIX_FMT_JPEG, 352, 288, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 3}, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; static void reg_r(struct usb_device *dev, @@ -269,7 +285,7 @@ static void cx_sensor(struct gspca_dev*gspca_dev) val = 0x03; reg_w(gspca_dev->dev, 0x0092, &val, 1); - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: reg_w(gspca_dev->dev, 0x0071, reg71a, 4); break; @@ -350,7 +366,7 @@ static int cx11646_initsize(struct gspca_dev *gspca_dev) static const __u8 reg17[] = { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: cxinit = cx_inits_640; break; @@ -668,7 +684,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) reg_w(gspca_dev->dev, 0x00c0, &val, 1); reg_r(gspca_dev->dev, 0x0001, &val, 1); length = 8; - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: for (i = 0; i < 27; i++) { if (i == 26) @@ -832,9 +848,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; sd->qindex = 0; /* set the quantization */ - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; - sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->contrast = CONTRAST_DEF; + sd->colors = COLOR_DEF; return 0; } diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index bbbe65923cfc..4db33618af6b 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("Etoms USB Camera Driver"); @@ -114,14 +114,30 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_SBGGR8, 320, 240, 1}, -/* {V4L2_PIX_FMT_SBGGR8, 640, 480, 0}, */ +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, +/* {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, */ }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, - {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; #define ETOMS_ALT_SIZE_1000 12 @@ -334,7 +350,7 @@ static void Et_init2(struct gspca_dev *gspca_dev) reg_w_val(dev, ET_CTRL, 0x1b); /* compression et subsampling */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) value = ET_COMP_VAL1; /* 320 */ else value = ET_COMP_VAL0; /* 640 */ @@ -410,7 +426,7 @@ static void Et_init2(struct gspca_dev *gspca_dev) /* reg_r(dev, ET_I2C_BASE, &received, 1); always 0x40 as the pas106 ??? */ /* set the sensor */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) value = 0x04; /* 320 */ else /* 640 */ value = 0x1e; /* 0x17 * setting PixelClock @@ -487,12 +503,12 @@ static void Et_init1(struct gspca_dev *gspca_dev) reg_w_val(dev, ET_ClCK, 0x10); reg_w_val(dev, ET_CTRL, 0x19); /* compression et subsampling */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) value = ET_COMP_VAL1; else value = ET_COMP_VAL0; PDEBUG(D_STREAM, "Open mode %d Compression %d", - gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode, + gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, value); reg_w_val(dev, ET_COMP, value); reg_w_val(dev, ET_MAXQt, 0x1d); @@ -533,7 +549,7 @@ static void Et_init1(struct gspca_dev *gspca_dev) reg_w_val(dev, ET_I2C_CLK, 0x04); reg_w_val(dev, ET_PXL_CLK, 0x01); /* set the sensor */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { I2c0[0] = 0x06; Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 1225c0fe26f0..cb0aeb0c0a45 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -43,13 +43,11 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; static int video_nr = -1; -static int comp_fac = 30; /* Buffer size ratio when compressed in % */ - #ifdef CONFIG_VIDEO_ADV_DEBUG int gspca_debug = D_ERR | D_PROBE; EXPORT_SYMBOL(gspca_debug); @@ -361,58 +359,6 @@ static void rvfree(void *mem, unsigned long size) vfree(mem); } -static __u32 get_v4l2_depth(__u32 pixfmt) -{ - switch (pixfmt) { -/* case V4L2_PIX_FMT_BGR32: - case V4L2_PIX_FMT_RGB32: - return 32; */ - case V4L2_PIX_FMT_RGB24: /* 'RGB3' */ - case V4L2_PIX_FMT_BGR24: - return 24; -/* case V4L2_PIX_FMT_RGB565: * 'RGBP' */ - case V4L2_PIX_FMT_YUYV: /* 'YUYV' packed 4.2.2 */ - case V4L2_PIX_FMT_YYUV: /* 'YYUV' */ - return 16; - case V4L2_PIX_FMT_YUV420: /* 'YU12' planar 4.2.0 */ - case V4L2_PIX_FMT_SPCA501: /* 'S501' YUYV per line */ - return 12; - case V4L2_PIX_FMT_MJPEG: - case V4L2_PIX_FMT_JPEG: - case V4L2_PIX_FMT_SBGGR8: /* 'BA81' Bayer */ - case V4L2_PIX_FMT_SN9C10X: /* 'S910' SN9C10x compression */ - case V4L2_PIX_FMT_SPCA561: /* 'S561' compressed GBRG bayer */ - case V4L2_PIX_FMT_PAC207: /* 'P207' compressed BGGR bayer */ - return 8; - } - PDEBUG(D_ERR|D_CONF, "Unknown pixel format %c%c%c%c", - pixfmt & 0xff, - (pixfmt >> 8) & 0xff, - (pixfmt >> 16) & 0xff, - pixfmt >> 24); - return 24; -} - -static int gspca_get_buff_size(struct gspca_dev *gspca_dev, int mode) -{ - unsigned int size; - - if (gspca_dev->sd_desc->get_buff_size) - return gspca_dev->sd_desc->get_buff_size(gspca_dev, mode); - - size = gspca_dev->cam.cam_mode[mode].width * - gspca_dev->cam.cam_mode[mode].height * - get_v4l2_depth(gspca_dev->cam.cam_mode[mode].pixfmt) / 8; - if (!size) - return -ENOMEM; - - /* if compressed (JPEG), reduce the buffer size */ - if (gspca_is_compressed(gspca_dev->cam.cam_mode[mode].pixfmt)) - size = (size * comp_fac) / 100 + 600; /* (+ JPEG header sz) */ - - return size; -} - static int frame_alloc(struct gspca_dev *gspca_dev, unsigned int count) { @@ -420,15 +366,14 @@ static int frame_alloc(struct gspca_dev *gspca_dev, unsigned int frsz; int i; - frsz = gspca_get_buff_size(gspca_dev, gspca_dev->curr_mode); - if (frsz < 0) - return frsz; + i = gspca_dev->curr_mode; + frsz = gspca_dev->cam.cam_mode[i].sizeimage; PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); - if (count > GSPCA_MAX_FRAMES) - count = GSPCA_MAX_FRAMES; frsz = PAGE_ALIGN(frsz); PDEBUG(D_STREAM, "new fr_sz: %d", frsz); gspca_dev->frsz = frsz; + if (count > GSPCA_MAX_FRAMES) + count = GSPCA_MAX_FRAMES; if (gspca_dev->memory == V4L2_MEMORY_MMAP) { gspca_dev->frbuf = rvmalloc(frsz * count); if (!gspca_dev->frbuf) { @@ -711,7 +656,7 @@ static void gspca_set_default_mode(struct gspca_dev *gspca_dev) gspca_dev->curr_mode = i; gspca_dev->width = gspca_dev->cam.cam_mode[i].width; gspca_dev->height = gspca_dev->cam.cam_mode[i].height; - gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixfmt; + gspca_dev->pixfmt = gspca_dev->cam.cam_mode[i].pixelformat; } static int wxh_to_mode(struct gspca_dev *gspca_dev, @@ -739,11 +684,13 @@ static int gspca_get_mode(struct gspca_dev *gspca_dev, modeU = modeD = mode; while ((modeU < gspca_dev->cam.nmodes) || modeD >= 0) { if (--modeD >= 0) { - if (gspca_dev->cam.cam_mode[modeD].pixfmt == pixfmt) + if (gspca_dev->cam.cam_mode[modeD].pixelformat + == pixfmt) return modeD; } if (++modeU < gspca_dev->cam.nmodes) { - if (gspca_dev->cam.cam_mode[modeU].pixfmt == pixfmt) + if (gspca_dev->cam.cam_mode[modeU].pixelformat + == pixfmt) return modeU; } } @@ -761,7 +708,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, index = 0; j = 0; for (i = gspca_dev->cam.nmodes; --i >= 0; ) { - fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixfmt; + fmt_tb[index] = gspca_dev->cam.cam_mode[i].pixelformat; j = 0; for (;;) { if (fmt_tb[j] == fmt_tb[index]) @@ -795,20 +742,13 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *fmt) { struct gspca_dev *gspca_dev = priv; + int mode; if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - fmt->fmt.pix.width = gspca_dev->width; - fmt->fmt.pix.height = gspca_dev->height; - fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; - fmt->fmt.pix.field = V4L2_FIELD_NONE; - fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) - * fmt->fmt.pix.width / 8; - fmt->fmt.pix.sizeimage = gspca_get_buff_size(gspca_dev, - gspca_dev->curr_mode); -/* (should be in the subdriver) */ - fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; - fmt->fmt.pix.priv = 0; + mode = gspca_dev->curr_mode; + memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], + sizeof fmt->fmt.pix); return 0; } @@ -833,34 +773,19 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, mode = wxh_to_mode(gspca_dev, w, h); /* OK if right palette */ - if (gspca_dev->cam.cam_mode[mode].pixfmt != fmt->fmt.pix.pixelformat) { + if (gspca_dev->cam.cam_mode[mode].pixelformat + != fmt->fmt.pix.pixelformat) { /* else, search the closest mode with the same pixel format */ mode2 = gspca_get_mode(gspca_dev, mode, fmt->fmt.pix.pixelformat); - if (mode2 >= 0) { + if (mode2 >= 0) mode = mode2; - } else { - - /* no chance, return this mode */ - fmt->fmt.pix.pixelformat = - gspca_dev->cam.cam_mode[mode].pixfmt; -#ifdef CONFIG_VIDEO_ADV_DEBUG - if (gspca_debug & D_CONF) { - PDEBUG_MODE("new format", - fmt->fmt.pix.pixelformat, - gspca_dev->cam.cam_mode[mode].width, - gspca_dev->cam.cam_mode[mode].height); - } -#endif - } +/* else + ; * no chance, return this mode */ } - fmt->fmt.pix.width = gspca_dev->cam.cam_mode[mode].width; - fmt->fmt.pix.height = gspca_dev->cam.cam_mode[mode].height; - fmt->fmt.pix.field = V4L2_FIELD_NONE; - fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) - * fmt->fmt.pix.width / 8; - fmt->fmt.pix.sizeimage = gspca_get_buff_size(gspca_dev, mode); + memcpy(&fmt->fmt.pix, &gspca_dev->cam.cam_mode[mode], + sizeof fmt->fmt.pix); return mode; /* used when s_fmt */ } @@ -883,16 +808,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, struct gspca_dev *gspca_dev = priv; int ret; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - /* if v4l1 got JPEG */ - if (fmt->fmt.pix.pixelformat == 0 - && gspca_dev->streaming) { - fmt->fmt.pix.width = gspca_dev->width; - fmt->fmt.pix.height = gspca_dev->height; - fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; - return 0; - } -#endif if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; @@ -1994,6 +1909,3 @@ MODULE_PARM_DESC(debug, " 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout" " 0x0100: v4l2"); #endif -module_param(comp_fac, int, 0644); -MODULE_PARM_DESC(comp_fac, - "Buffer size ratio when compressed in percent"); diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 05e8ee06071b..945f1ab4c9eb 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -52,15 +52,9 @@ extern int gspca_debug; #define ISO_MAX_SIZE 0x8000 /* max size of one URB buffer (32 Kb) */ /* device information - set at probe time */ -struct cam_mode { - __u32 pixfmt; - short width; - short height; - short mode; /* subdriver value */ -}; struct cam { char *dev_name; - struct cam_mode *cam_mode; /* size nmodes */ + struct v4l2_pix_format *cam_mode; /* size nmodes */ char nmodes; __u8 epaddr; }; @@ -80,7 +74,6 @@ typedef void (*cam_pkt_op) (struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len); -typedef int (*cam_get_buff_size_op) (struct gspca_dev *gspca_dev, int mode); struct ctrl { struct v4l2_queryctrl qctrl; @@ -102,12 +95,12 @@ struct sd_desc { cam_v_op stopN; /* called on stream off - main alt */ cam_v_op stop0; /* called on stream off - alt 0 */ cam_v_op close; /* called on close */ - cam_v_op dq_callback; /* called when a frame has been dequeued */ cam_pkt_op pkt_scan; +/* optional operations */ + cam_v_op dq_callback; /* called when a frame has been dequeued */ cam_jpg_op get_jcomp; cam_jpg_op set_jcomp; cam_qmnu_op querymenu; - cam_get_buff_size_op get_buff_size; /* optional */ }; /* packet types when moving from iso buf to frame buf */ diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index c70ccc8fe68b..23f3dba8012a 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); @@ -42,9 +42,17 @@ struct sd { static struct ctrl sd_ctrls[] = { }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 2}, - {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 589, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, }; /* MI Register table //elvis */ diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index d92729ac41f0..70b4cac37a50 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("OV519 USB Camera Driver"); @@ -126,13 +126,29 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240}, - {V4L2_PIX_FMT_JPEG, 640, 480}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 589, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_JPEG, 176, 144}, - {V4L2_PIX_FMT_JPEG, 352, 288}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 589, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 589, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; /* OV519 Camera interface register numbers */ diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index ab83d7b69348..b580af92d231 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -157,9 +157,18 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_PAC207, 176, 144, 1}, - {V4L2_PIX_FMT_PAC207, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = (176 + 2) * 144, + /* uncompressed, add 2 bytes / line for line header */ + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 / 2, /* compressed */ + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; static const __u8 pac207_sensor_init[][8] = { @@ -346,19 +355,6 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -static int sd_get_buff_size_op(struct gspca_dev *gspca_dev, int mode) -{ - switch (gspca_dev->cam.cam_mode[mode].width) { - case 176: /* 176x144 */ - /* uncompressed, add 2 bytes / line for line header */ - return (176 + 2) * 144; - case 352: /* 352x288 */ - /* compressed */ - return 352 * 288 / 2; - } - return -EIO; /* should never happen */ -} - /* auto gain and exposure algorithm based on the knee algorithm described here: * */ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) @@ -632,7 +628,6 @@ static const struct sd_desc sd_desc = { .close = sd_close, .dq_callback = pac207_do_auto_gain, .pkt_scan = sd_pkt_scan, - .get_buff_size = sd_get_buff_size_op, }; /* -- module initialisation -- */ diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index c2d4b6a4dcf4..1a2347aa7157 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); @@ -116,10 +116,22 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 160, 120, 2}, - {V4L2_PIX_FMT_JPEG, 320, 240, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; #define PAC7311_JPEG_HEADER_SIZE (sizeof pac7311_jpeg_header) /* (594) */ @@ -393,7 +405,7 @@ static void sd_start(struct gspca_dev *gspca_dev) setcolors(gspca_dev); /* set correct resolution */ - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 2: /* 160x120 */ pac7311_reg_write(dev, 0xff, 0x04); pac7311_reg_write(dev, 0x02, 0x03); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 4baac51bf40a..574568736317 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 3) -static const char version[] = "2.1.3"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); @@ -95,15 +95,34 @@ static struct ctrl sd_ctrls[] = { }, }; -/* fixme: should have V4L2_PIX_FMT_SN9C10X */ -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_SN9C10X, 160, 120, 2}, - {V4L2_PIX_FMT_SN9C10X, 320, 240, 1}, - {V4L2_PIX_FMT_SN9C10X, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SN9C10X, 176, 144, 1}, - {V4L2_PIX_FMT_SN9C10X, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; static const __u8 probe_ov7630[] = {0x08, 0x44}; @@ -592,7 +611,7 @@ static void sd_start(struct gspca_dev *gspca_dev) __u8 reg01, reg17; __u8 reg17_19[3]; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (sd->sensor) { case SENSOR_HV7131R: sn9c10x = initHv7131; diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index eb5e1bfd7911..3db6487a705d 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); @@ -132,10 +132,22 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 160, 120, 2}, - {V4L2_PIX_FMT_JPEG, 320, 240, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; /*Data from sn9c102p+hv71331r */ @@ -1232,7 +1244,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x99, &data, 1); } - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; reg1 = 0x02; reg17 = 0x61; switch (sd->sensor) { diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 3a42506830f8..d00f0f76e0e3 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); @@ -114,14 +114,30 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_JPEG, 176, 144, 1}, - {V4L2_PIX_FMT_JPEG, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; /* Frame packet header offsets for the spca500 */ @@ -515,7 +531,7 @@ static void spca500_setmode(struct gspca_dev *gspca_dev, reg_w(gspca_dev->dev, 0, 0x8002, ymult); /* use compressed mode, VGA, with mode specific subsample */ - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; reg_w(gspca_dev->dev, 0, 0x8003, mode << 4); } diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 417fbe2214be..2064dc008af1 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); @@ -101,10 +101,22 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_SPCA501, 160, 120, 2}, - {V4L2_PIX_FMT_SPCA501, 320, 240, 1}, - {V4L2_PIX_FMT_SPCA501, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 3 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; #define SPCA50X_REG_USB 0x2 /* spca505 501 */ @@ -2029,7 +2041,7 @@ static void sd_start(struct gspca_dev *gspca_dev) int mode; /* memorize the wanted pixel format */ - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; /* Enable ISO packet machine CTRL reg=2, * index=1 bitmask=0x2 (bit ordinal 1) */ diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 30d174fc4b9c..5d28d23b8375 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); @@ -66,12 +66,32 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_YUYV, 160, 120, 5}, - {V4L2_PIX_FMT_YUYV, 176, 144, 4}, - {V4L2_PIX_FMT_YUYV, 320, 240, 2}, - {V4L2_PIX_FMT_YUYV, 352, 288, 1}, - {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 160 * 2, + .sizeimage = 160 * 120 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 5}, + {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 176 * 2, + .sizeimage = 176 * 144 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 4}, + {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 352 * 2, + .sizeimage = 352 * 288 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 640 * 2, + .sizeimage = 640 * 480 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; #define SPCA50X_OFFSET_DATA 10 @@ -708,7 +728,7 @@ static void sd_start(struct gspca_dev *gspca_dev) * only once after loading module */ /* stopping usb registers Tomasz change */ reg_write(dev, 0x02, 0x0, 0x0); - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: reg_write(dev, 0x04, 0x00, 0x00); reg_write(dev, 0x04, 0x06, 0x10); diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 614fb3ad7711..2d249b00bdcd 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -25,8 +25,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 0) -static const char version[] = "2.1.0"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); @@ -34,11 +34,11 @@ MODULE_LICENSE("GPL"); /* specific webcam descriptor */ struct sd { - struct gspca_dev gspca_dev; /* !! must be the first item */ + struct gspca_dev gspca_dev; /* !! must be the first item */ int buflen; - unsigned char tmpbuf[640 * 480 * 3]; /* YYUV per line */ - unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ + __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */ + __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */ unsigned char brightness; unsigned char contrast; @@ -117,12 +117,32 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_YUYV, 160, 120, 5}, - {V4L2_PIX_FMT_YUYV, 176, 144, 4}, - {V4L2_PIX_FMT_YUYV, 320, 240, 2}, - {V4L2_PIX_FMT_YUYV, 352, 288, 1}, - {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 160 * 2, + .sizeimage = 160 * 120 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 5}, + {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 176 * 2, + .sizeimage = 176 * 144 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 4}, + {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 352 * 2, + .sizeimage = 352 * 288 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 640 * 2, + .sizeimage = 640 * 480 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; #define SPCA50X_OFFSET_DATA 10 @@ -169,7 +189,7 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) { int retry = 60; - unsigned char Data[2]; + __u8 Data[2]; reg_w(gspca_dev->dev, 0x07, reg, 0x0001); reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); @@ -183,8 +203,8 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) { int retry = 60; - unsigned char Data[2]; - unsigned char value; + __u8 Data[2]; + __u8 value; reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); reg_w(gspca_dev->dev, 0x07, reg, 0x0001); @@ -513,7 +533,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x05, 0x00, 0x0004); reg_w(dev, 0x03, 0x10, 0x0001); reg_w(dev, 0x03, 0x78, 0x0000); - switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: spca506_Setsize(gspca_dev, 0, 0x10, 0x10); break; @@ -593,7 +613,7 @@ static void yyuv_decode(unsigned char *out, static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ - unsigned char *data, /* isoc packet */ + __u8 *data, /* isoc packet */ int len) /* iso packet length */ { struct sd *sd = (struct sd *) gspca_dev; diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 3b54f41d21c1..169238d40c97 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); @@ -69,11 +69,27 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_YUYV, 160, 120, 3}, - {V4L2_PIX_FMT_YUYV, 176, 144, 2}, - {V4L2_PIX_FMT_YUYV, 320, 240, 1}, - {V4L2_PIX_FMT_YUYV, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 160 * 2, + .sizeimage = 160 * 120 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 3}, + {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 176 * 2, + .sizeimage = 176 * 144 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 352 * 2, + .sizeimage = 352 * 288 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; /* Frame packet header offsets for the spca508 */ @@ -1574,7 +1590,7 @@ static void sd_start(struct gspca_dev *gspca_dev) { int mode; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; reg_write(gspca_dev->dev, 0x8500, mode); switch (mode) { case 0: diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 8e39cbdda2a5..f0770ee595d8 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); @@ -97,11 +97,27 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SGBRG8, 160, 120, 3}, - {V4L2_PIX_FMT_SGBRG8, 176, 144, 2}, - {V4L2_PIX_FMT_SPCA561, 320, 240, 1}, - {V4L2_PIX_FMT_SPCA561, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 3}, + {176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 2}, + {320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 4 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 4 / 8, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; /* @@ -655,7 +671,7 @@ static void sd_start(struct gspca_dev *gspca_dev) __u8 Reg8307[] = { 0xaa, 0x00 }; int mode; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (sd->chip_revision) { case Rev072A: switch (mode) { diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index ad59c5ab5d90..d676cd16aa74 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -23,8 +23,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -112,9 +112,17 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240}, - {V4L2_PIX_FMT_JPEG, 640, 480}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; /* -- read a register -- */ diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index f2d033508581..f66594a113a7 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); @@ -126,21 +126,53 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 2}, - {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, }; -static struct cam_mode custom_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 2}, - {V4L2_PIX_FMT_JPEG, 464, 480, 1}, +static struct v4l2_pix_format custom_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {464, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 464, + .sizeimage = 464 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, }; -static struct cam_mode vga_mode2[] = { - {V4L2_PIX_FMT_JPEG, 176, 144, 4}, - {V4L2_PIX_FMT_JPEG, 320, 240, 3}, - {V4L2_PIX_FMT_JPEG, 352, 288, 2}, - {V4L2_PIX_FMT_JPEG, 640, 480, 1}, +static struct v4l2_pix_format vga_mode2[] = { + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 4}, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 3}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, }; #define SPCA50X_OFFSET_DATA 10 @@ -655,7 +687,7 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) __u8 Type; int rc; - Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; Type = 0; switch (sd->bridge) { case BRIDGE_SPCA533: diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 96f01d267475..299f84584e82 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -26,8 +26,8 @@ #define MODULE_NAME "t613" #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; #define MAX_GAMMA 0x10 /* 0 to 15 */ @@ -232,12 +232,32 @@ static char *effects_control[] = { "Negative", }; -static struct cam_mode vga_mode_t16[] = { - {V4L2_PIX_FMT_JPEG, 160, 120, 4}, - {V4L2_PIX_FMT_JPEG, 176, 144, 3}, - {V4L2_PIX_FMT_JPEG, 320, 240, 2}, - {V4L2_PIX_FMT_JPEG, 352, 288, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode_t16[] = { + {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 160, + .sizeimage = 160 * 120 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 4}, + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 3}, + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 2}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; #define T16_OFFSET_DATA 631 @@ -848,7 +868,7 @@ static void sd_start(struct gspca_dev *gspca_dev) 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 }; static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 }; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv; switch (mode) { case 1: /* 352x288 */ t2[1] = 0x40; diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 8561234d65e2..f9bffd67991e 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("TV8532 USB Camera Driver"); @@ -81,9 +81,17 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_SBGGR8, 176, 144, 1}, - {V4L2_PIX_FMT_SBGGR8, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; /* @@ -440,7 +448,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /************************************************/ data = TESTCOMP; /* 0x72 compressed mode */ reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ - if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode) { + if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { /* 176x144 */ data = QCIFLINE; /* 0x84; // CIF | 4 packet */ reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 4144e11c60bb..afbbbd290560 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); @@ -88,13 +88,29 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vc0321_mode[] = { - {V4L2_PIX_FMT_YUYV, 320, 240, 1}, - {V4L2_PIX_FMT_YUYV, 640, 480, 0}, +static struct v4l2_pix_format vc0321_mode[] = { + {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 320 * 2, + .sizeimage = 320 * 240 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 640 * 2, + .sizeimage = 640 * 480 * 2, + .colorspace = V4L2_COLORSPACE_SRGB, + .priv = 0}, }; -static struct cam_mode vc0323_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vc0323_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; static const __u8 mi1310_socinitVGA_JPG[][4] = { @@ -1535,7 +1551,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef); } - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (sd->sensor) { case SENSOR_HV7131R: GammaT = hv7131r_gamma; diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 63dd8916d6b6..eed9a8baf4ee 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 4) -static const char version[] = "2.1.4"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) +static const char version[] = "2.1.5"; MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); @@ -173,14 +173,30 @@ static struct ctrl sd_ctrls[] = { }, }; -static struct cam_mode vga_mode[] = { - {V4L2_PIX_FMT_JPEG, 320, 240, 1}, - {V4L2_PIX_FMT_JPEG, 640, 480, 0}, +static struct v4l2_pix_format vga_mode[] = { + {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 320, + .sizeimage = 320 * 240 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 640, + .sizeimage = 640 * 480 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; -static struct cam_mode sif_mode[] = { - {V4L2_PIX_FMT_JPEG, 176, 144, 1}, - {V4L2_PIX_FMT_JPEG, 352, 288, 0}, +static struct v4l2_pix_format sif_mode[] = { + {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 176, + .sizeimage = 176 * 144 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 1}, + {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, + .bytesperline = 352, + .sizeimage = 352 * 288 * 3 / 8 + 590, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, }; /* usb exchanges */ @@ -6602,7 +6618,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev) }; i = sd->lightfreq * 2; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; if (!mode) i++; /* 640x480 */ zc3_freq = freq_tb[(int) sd->sensor][i]; @@ -7170,7 +7186,7 @@ static void sd_start(struct gspca_dev *gspca_dev) /* 16 */ }; - mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode; + mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; zc3_init = init_tb[(int) sd->sensor][mode]; switch (sd->sensor) { case SENSOR_HV7131B: -- cgit v1.2.3 From 80544d3c7a7ce32084c9137c96488704053772e3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 6 Jul 2008 06:40:55 -0300 Subject: V4L/DVB (8202): gspca: PAC207 frames may be not compressed. pac207: Set the sizeimage to the max value for 352x288. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/pac207.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index b580af92d231..4f197c1f4a76 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -166,7 +166,9 @@ static struct v4l2_pix_format sif_mode[] = { .priv = 1}, {352, 288, V4L2_PIX_FMT_PAC207, V4L2_FIELD_NONE, .bytesperline = 352, - .sizeimage = 352 * 288 / 2, /* compressed */ + /* compressed, but only when needed (not compressed + when the framerate is low) */ + .sizeimage = (352 + 2) * 288, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; -- cgit v1.2.3 From 814429501f65e3482adb8e7678660ceb7a2fc2e6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 6 Jul 2008 07:04:39 -0300 Subject: V4L/DVB (8204): gspca: Cleanup code. spca508: Cleanup code. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/spca508.c | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 169238d40c97..7f262f23841e 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -53,16 +53,16 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", .minimum = 0, - .maximum = 0xff, + .maximum = 255, .step = 1, - .default_value = 0x80, +#define BRIGHTNESS_DEF 128 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, @@ -593,7 +593,7 @@ static const __u16 spca508_init_data[][3] = /* Video drop enable, ISO streaming disable */ /* 53252 2165 */ /* UNKNOWN DIRECTION (URB_FUNCTION_SELECT_INTERFACE: (ALT=0) ) */ - {0, 0} + {} }; @@ -764,8 +764,7 @@ static const __u16 spca508_sightcam_init_data[][3] = { /*542 */ {0x0040, 0x8652}, /*543 */ {0x004c, 0x8653}, /*544 */ {0x0040, 0x8654}, - - {0, 0} + {} }; static const __u16 spca508_sightcam2_init_data[][3] = { @@ -1485,6 +1484,13 @@ static int sd_config(struct gspca_dev *gspca_dev, vendor = id->idVendor; product = id->idProduct; switch (vendor) { + case 0x0130: /* Clone webcam */ +/* switch (product) { */ +/* case 0x0130: */ + sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */ +/* break; */ +/* } */ + break; case 0x041e: /* Creative cameras */ /* switch (product) { */ /* case 0x4018: */ @@ -1506,10 +1512,8 @@ static int sd_config(struct gspca_dev *gspca_dev, /* break; */ /* } */ break; - case 0x0130: /* Clone webcam */ case 0x0af9: /* Hama cameras */ switch (product) { - case 0x0130: case 0x0010: sd->subtype = HamaUSBSightcam; break; @@ -1527,30 +1531,27 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } - /* Read from global register the USB product and vendor IDs, just to */ - /* prove that we can communicate with the device. This works, which */ - /* confirms at we are communicating properly and that the device */ - /* is a 508. */ + /* Read from global register the USB product and vendor IDs, just to + * prove that we can communicate with the device. This works, which + * confirms at we are communicating properly and that the device + * is a 508. */ data1 = reg_read(dev, 0x8104); data2 = reg_read(dev, 0x8105); - PDEBUG(D_PROBE, - "Read from GLOBAL: USB Vendor ID 0x%02x%02x", data2, data1); + PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1); data1 = reg_read(dev, 0x8106); data2 = reg_read(dev, 0x8107); - PDEBUG(D_PROBE, - "Read from GLOBAL: USB Product ID 0x%02x%02x", data2, data1); + PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1); data1 = reg_read(dev, 0x8621); - PDEBUG(D_PROBE, - "Read from GLOBAL: Window 1 average luminance %d", data1); + PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; + cam->nmodes = ARRAY_SIZE(sif_mode); + sd->brightness = BRIGHTNESS_DEF; switch (sd->subtype) { case ViewQuestVQ110: @@ -1699,7 +1700,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; __u8 brightness = sd->brightness; -/* MX seem contrast */ + /* MX seem contrast */ reg_write(gspca_dev->dev, 0x8651, brightness); reg_write(gspca_dev->dev, 0x8652, brightness); reg_write(gspca_dev->dev, 0x8653, brightness); @@ -1749,14 +1750,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")}, {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, - {USB_DEVICE(0x0130, 0x0130), - DVNM("Clone Digital Webcam 11043 (spca508a)")}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From 553b9fa47d67a77f6456bc969891a347bfb323dc Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Sun, 6 Jul 2008 07:27:19 -0300 Subject: V4L/DVB (8205): gspca: Size of frame header adjusted according to sn9c10x in sonixb. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 574568736317..3dbeadf23e19 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -38,6 +38,7 @@ struct sd { unsigned char brightness; unsigned char contrast; + unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 @@ -510,6 +511,7 @@ static int sd_config(struct gspca_dev *gspca_dev, __u16 product; int sif = 0; + sd->fr_h_sz = 12; /* default size of the frame header */ /* vendor = id->idVendor; */ product = id->idProduct; /* switch (vendor) { */ @@ -538,6 +540,7 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x60b0: /* SN9C103 */ sd->sensor = SENSOR_OV7630_3; + sd->fr_h_sz = 18; /* size of frame header */ break; case 0x6024: /* SN9C102 */ case 0x6025: /* SN9C102 */ @@ -551,6 +554,7 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x60af: /* SN9C103 */ sd->sensor = SENSOR_PAS202; + sd->fr_h_sz = 18; /* size of frame header (?) */ break; } /* break; */ @@ -775,6 +779,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, unsigned char *data, /* isoc packet */ int len) /* iso packet length */ { + struct sd *sd; int i; if (len > 6 && len < 24) { @@ -787,8 +792,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[5 + i] == 0x96) { /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - data += i + 12; - len -= i + 12; + sd = (struct sd *) gspca_dev; + data += i + sd->fr_h_sz; + len -= i + sd->fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); return; -- cgit v1.2.3 From 233548a2fd934a0220db8b1521c0bc88c82e5e53 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 4 Jul 2008 00:34:59 -0300 Subject: V4L/DVB (8207): uvcvideo: Fix a buffer overflow in format descriptor parsing Thanks to Oliver Neukum for catching and reporting this bug. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 60ced589f898..86bb16d00173 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -298,7 +298,8 @@ static int uvc_parse_format(struct uvc_device *dev, switch (buffer[2]) { case VS_FORMAT_UNCOMPRESSED: case VS_FORMAT_FRAME_BASED: - if (buflen < 27) { + n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; + if (buflen < n) { uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" "interface %d FORMAT error\n", dev->udev->devnum, -- cgit v1.2.3 From 291358785cde5536d98a4f3cae77efd8ca626486 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 4 Jul 2008 00:35:26 -0300 Subject: V4L/DVB (8208): uvcvideo: Use GFP_NOIO when allocating memory during resume The swap device might still be asleep, so memory allocated in the resume handler must use GFP_NOIO. Thanks to Oliver Neukum for catching and reporting this bug. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_status.c | 2 +- drivers/media/video/uvc/uvc_video.c | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index be9084e5eace..06b47980ed98 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -203,5 +203,5 @@ int uvc_status_resume(struct uvc_device *dev) if (dev->int_urb == NULL) return 0; - return usb_submit_urb(dev->int_urb, GFP_KERNEL); + return usb_submit_urb(dev->int_urb, GFP_NOIO); } diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 6faf1fb21614..8eb5748c446e 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -586,7 +586,7 @@ static void uvc_uninit_video(struct uvc_video_device *video) * is given by the endpoint. */ static int uvc_init_video_isoc(struct uvc_video_device *video, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep, gfp_t gfp_flags) { struct urb *urb; unsigned int npackets, i, j; @@ -611,14 +611,14 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, size = npackets * psize; for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(npackets, GFP_KERNEL); + urb = usb_alloc_urb(npackets, gfp_flags); if (urb == NULL) { uvc_uninit_video(video); return -ENOMEM; } video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); + size, gfp_flags, &urb->transfer_dma); if (video->urb_buffer[i] == NULL) { usb_free_urb(urb); uvc_uninit_video(video); @@ -652,7 +652,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, * given by the endpoint. */ static int uvc_init_video_bulk(struct uvc_video_device *video, - struct usb_host_endpoint *ep) + struct usb_host_endpoint *ep, gfp_t gfp_flags) { struct urb *urb; unsigned int pipe, i; @@ -674,14 +674,14 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); for (i = 0; i < UVC_URBS; ++i) { - urb = usb_alloc_urb(0, GFP_KERNEL); + urb = usb_alloc_urb(0, gfp_flags); if (urb == NULL) { uvc_uninit_video(video); return -ENOMEM; } video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, GFP_KERNEL, &urb->transfer_dma); + size, gfp_flags, &urb->transfer_dma); if (video->urb_buffer[i] == NULL) { usb_free_urb(urb); uvc_uninit_video(video); @@ -702,7 +702,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, /* * Initialize isochronous/bulk URBs and allocate transfer buffers. */ -static int uvc_init_video(struct uvc_video_device *video) +static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) { struct usb_interface *intf = video->streaming->intf; struct usb_host_interface *alts; @@ -747,7 +747,7 @@ static int uvc_init_video(struct uvc_video_device *video) if ((ret = usb_set_interface(video->dev->udev, intfnum, i)) < 0) return ret; - ret = uvc_init_video_isoc(video, ep); + ret = uvc_init_video_isoc(video, ep, gfp_flags); } else { /* Bulk endpoint, proceed to URB initialization. */ ep = uvc_find_endpoint(&intf->altsetting[0], @@ -755,7 +755,7 @@ static int uvc_init_video(struct uvc_video_device *video) if (ep == NULL) return -EIO; - ret = uvc_init_video_bulk(video, ep); + ret = uvc_init_video_bulk(video, ep, gfp_flags); } if (ret < 0) @@ -763,7 +763,7 @@ static int uvc_init_video(struct uvc_video_device *video) /* Submit the URBs. */ for (i = 0; i < UVC_URBS; ++i) { - if ((ret = usb_submit_urb(video->urb[i], GFP_KERNEL)) < 0) { + if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { uvc_printk(KERN_ERR, "Failed to submit URB %u " "(%d).\n", i, ret); uvc_uninit_video(video); @@ -818,7 +818,7 @@ int uvc_video_resume(struct uvc_video_device *video) if (!uvc_queue_streaming(&video->queue)) return 0; - if ((ret = uvc_init_video(video)) < 0) + if ((ret = uvc_init_video(video, GFP_NOIO)) < 0) uvc_queue_enable(&video->queue, 0); return ret; @@ -930,5 +930,5 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) return ret; - return uvc_init_video(video); + return uvc_init_video(video, GFP_KERNEL); } -- cgit v1.2.3 From e01117c81676dc9897f567e32cdc13a26e85280b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 4 Jul 2008 00:36:21 -0300 Subject: V4L/DVB (8209): uvcvideo: Don't free URB buffers on suspend. All submitted URBs must be killed at suspend time, but URB buffers don't have to be freed. Avoiding a free on suspend/reallocate on resume lowers the presure on system memory. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_video.c | 96 ++++++++++++++++++++++++------------- drivers/media/video/uvc/uvcvideo.h | 2 + 2 files changed, 66 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 8eb5748c446e..817af2e36362 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -553,10 +553,57 @@ static void uvc_video_complete(struct urb *urb) } } +/* + * Free transfer buffers. + */ +static void uvc_free_urb_buffers(struct uvc_video_device *video) +{ + unsigned int i; + + for (i = 0; i < UVC_URBS; ++i) { + if (video->urb_buffer[i]) { + usb_buffer_free(video->dev->udev, video->urb_size, + video->urb_buffer[i], video->urb_dma[i]); + video->urb_buffer[i] = NULL; + } + } + + video->urb_size = 0; +} + +/* + * Allocate transfer buffers. This function can be called with buffers + * already allocated when resuming from suspend, in which case it will + * return without touching the buffers. + * + * Return 0 on success or -ENOMEM when out of memory. + */ +static int uvc_alloc_urb_buffers(struct uvc_video_device *video, + unsigned int size) +{ + unsigned int i; + + /* Buffers are already allocated, bail out. */ + if (video->urb_size) + return 0; + + for (i = 0; i < UVC_URBS; ++i) { + video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, + size, GFP_KERNEL, &video->urb_dma[i]); + if (video->urb_buffer[i] == NULL) { + uvc_free_urb_buffers(video); + return -ENOMEM; + } + } + + video->urb_size = size; + return 0; +} + /* * Uninitialize isochronous/bulk URBs and free transfer buffers. */ -static void uvc_uninit_video(struct uvc_video_device *video) +static void uvc_uninit_video(struct uvc_video_device *video, int free_buffers) { struct urb *urb; unsigned int i; @@ -566,19 +613,12 @@ static void uvc_uninit_video(struct uvc_video_device *video) continue; usb_kill_urb(urb); - /* urb->transfer_buffer_length is not touched by USB core, so - * we can use it here as the buffer length. - */ - if (video->urb_buffer[i]) { - usb_buffer_free(video->dev->udev, - urb->transfer_buffer_length, - video->urb_buffer[i], urb->transfer_dma); - video->urb_buffer[i] = NULL; - } - usb_free_urb(urb); video->urb[i] = NULL; } + + if (free_buffers) + uvc_free_urb_buffers(video); } /* @@ -610,18 +650,13 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, size = npackets * psize; + if (uvc_alloc_urb_buffers(video, size) < 0) + return -ENOMEM; + for (i = 0; i < UVC_URBS; ++i) { urb = usb_alloc_urb(npackets, gfp_flags); if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, gfp_flags, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return -ENOMEM; } @@ -632,6 +667,7 @@ static int uvc_init_video_isoc(struct uvc_video_device *video, urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = ep->desc.bInterval; urb->transfer_buffer = video->urb_buffer[i]; + urb->transfer_dma = video->urb_dma[i]; urb->complete = uvc_video_complete; urb->number_of_packets = npackets; urb->transfer_buffer_length = size; @@ -671,20 +707,15 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, if (size > psize * UVC_MAX_ISO_PACKETS) size = psize * UVC_MAX_ISO_PACKETS; + if (uvc_alloc_urb_buffers(video, size) < 0) + return -ENOMEM; + pipe = usb_rcvbulkpipe(video->dev->udev, ep->desc.bEndpointAddress); for (i = 0; i < UVC_URBS; ++i) { urb = usb_alloc_urb(0, gfp_flags); if (urb == NULL) { - uvc_uninit_video(video); - return -ENOMEM; - } - - video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev, - size, gfp_flags, &urb->transfer_dma); - if (video->urb_buffer[i] == NULL) { - usb_free_urb(urb); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return -ENOMEM; } @@ -692,6 +723,7 @@ static int uvc_init_video_bulk(struct uvc_video_device *video, video->urb_buffer[i], size, uvc_video_complete, video); urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = video->urb_dma[i]; video->urb[i] = urb; } @@ -766,7 +798,7 @@ static int uvc_init_video(struct uvc_video_device *video, gfp_t gfp_flags) if ((ret = usb_submit_urb(video->urb[i], gfp_flags)) < 0) { uvc_printk(KERN_ERR, "Failed to submit URB %u " "(%d).\n", i, ret); - uvc_uninit_video(video); + uvc_uninit_video(video, 1); return ret; } } @@ -791,7 +823,7 @@ int uvc_video_suspend(struct uvc_video_device *video) return 0; video->frozen = 1; - uvc_uninit_video(video); + uvc_uninit_video(video, 0); usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); return 0; } @@ -920,7 +952,7 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) int ret; if (!enable) { - uvc_uninit_video(video); + uvc_uninit_video(video, 1); usb_set_interface(video->dev->udev, video->streaming->intfnum, 0); uvc_queue_enable(&video->queue, 0); diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index a995a780db1c..2444b8a9d2a0 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -602,6 +602,8 @@ struct uvc_video_device { struct urb *urb[UVC_URBS]; char *urb_buffer[UVC_URBS]; + dma_addr_t urb_dma[UVC_URBS]; + unsigned int urb_size; __u8 last_fid; }; -- cgit v1.2.3 From f87086e302300fdff1bd32049deb7a7f3e3de7da Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 Jul 2008 00:50:58 -0300 Subject: v4l-dvb: remove legacy checks to allow support for kernels < 2.6.10 Also remove some blank lines that were used to split compat code at -devel tree. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 1 - drivers/media/dvb/dvb-usb/dvb-usb-i2c.c | 4 ---- drivers/media/dvb/ttpci/av7110.c | 4 ---- drivers/media/dvb/ttpci/budget-core.c | 4 ---- drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 4 ---- drivers/media/video/bt8xx/bt832.c | 1 - drivers/media/video/bt8xx/bttv.h | 1 - drivers/media/video/bt8xx/bttvp.h | 3 --- drivers/media/video/cs5345.c | 1 - drivers/media/video/cs53l32a.c | 2 -- drivers/media/video/cx18/cx18-driver.h | 2 -- drivers/media/video/cx18/cx18-i2c.c | 4 ---- drivers/media/video/cx25840/cx25840-core.c | 1 - drivers/media/video/cx88/cx88-alsa.c | 1 - drivers/media/video/cx88/cx88-i2c.c | 1 - drivers/media/video/cx88/cx88-vp3054-i2c.c | 1 - drivers/media/video/em28xx/em28xx-i2c.c | 1 - drivers/media/video/gspca/ov519.c | 1 + drivers/media/video/ivtv/ivtv-driver.h | 1 - drivers/media/video/ivtv/ivtv-i2c.c | 4 ---- drivers/media/video/m52790.c | 1 - drivers/media/video/msp3400-driver.c | 3 +-- drivers/media/video/msp3400-kthreads.c | 1 - drivers/media/video/pwc/pwc-ctrl.c | 2 -- drivers/media/video/pwc/pwc-ioctl.h | 1 - drivers/media/video/saa5246a.c | 1 + drivers/media/video/saa5249.c | 1 + drivers/media/video/saa6588.c | 1 - drivers/media/video/saa7115.c | 2 -- drivers/media/video/saa7127.c | 1 - drivers/media/video/saa7134/saa6752hs.c | 3 +-- drivers/media/video/saa7134/saa7134-alsa.c | 4 ---- drivers/media/video/saa7134/saa7134-cards.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 1 - drivers/media/video/saa7134/saa7134-tvaudio.c | 2 -- drivers/media/video/tda7432.c | 1 + drivers/media/video/tda9840.c | 1 + drivers/media/video/tda9875.c | 2 +- drivers/media/video/tea6415c.c | 1 + drivers/media/video/tea6420.c | 1 + drivers/media/video/tlv320aic23b.c | 1 - drivers/media/video/tuner-core.c | 1 - drivers/media/video/usbvision/usbvision-core.c | 4 ---- drivers/media/video/usbvision/usbvision-i2c.c | 5 ----- drivers/media/video/usbvision/usbvision-video.c | 12 ------------ drivers/media/video/uvc/uvc_ctrl.c | 1 + drivers/media/video/uvc/uvc_driver.c | 1 + drivers/media/video/uvc/uvc_queue.c | 1 + drivers/media/video/uvc/uvc_status.c | 1 + drivers/media/video/uvc/uvc_v4l2.c | 1 + drivers/media/video/uvc/uvc_video.c | 1 + drivers/media/video/uvc/uvcvideo.h | 1 + drivers/media/video/videobuf-dvb.c | 2 -- drivers/media/video/vp27smpx.c | 1 - drivers/media/video/wm8739.c | 1 - drivers/media/video/wm8775.c | 2 -- include/media/pwc-ioctl.h | 3 +-- include/media/v4l2-i2c-drv-legacy.h | 1 - 58 files changed, 19 insertions(+), 95 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 266505207925..03b1165eacbc 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -66,7 +66,6 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, if (ir_codes) memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes)); - dev->keycode = ir->ir_codes; dev->keycodesize = sizeof(IR_KEYTAB_TYPE); dev->keycodemax = IR_KEYTAB_SIZE; diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 23428cd30756..326f7608954b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -20,11 +20,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d) } strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, -#else d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, -#endif d->i2c_adap.algo = d->props.i2c_algo; d->i2c_adap.algo_data = NULL; d->i2c_adap.dev.parent = &d->udev->dev; diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 865c4596b7b7..0777e8f9544b 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c @@ -2471,11 +2471,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, get recognized before the main driver is fully loaded */ saa7146_write(dev, GPIO_CTRL, 0x500000); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 18cac4b12ab2..6f4ddb643fee 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c @@ -497,11 +497,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, if (bi->type != BUDGET_FS_ACTIVY) saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index bc2043e44ebd..156072239374 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -1693,11 +1693,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i i2c_set_adapdata(&ttusb->i2c_adap, ttusb); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL; -#else ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; -#endif ttusb->i2c_adap.algo = &ttusb_dec_algo; ttusb->i2c_adap.algo_data = NULL; ttusb->i2c_adap.dev.parent = &udev->dev; diff --git a/drivers/media/video/bt8xx/bt832.c b/drivers/media/video/bt8xx/bt832.c index f92f06dec0d0..216fc9680e80 100644 --- a/drivers/media/video/bt8xx/bt832.c +++ b/drivers/media/video/bt8xx/bt832.c @@ -179,7 +179,6 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1); - if(! bt832_init(&t->client)) { bt832_detach(&t->client); return -1; diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index f2393202904b..6d93d16c96e4 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -299,7 +299,6 @@ extern int bttv_write_gpio(unsigned int card, /* ---------------------------------------------------------- */ /* sysfs/driver-moded based gpio access interface */ - struct bttv_sub_device { struct device dev; struct bttv_core *core; diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index 955e6bcd8ae0..08ef54a22c9e 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -39,7 +39,6 @@ #include #include #include - #include #include #include @@ -263,12 +262,10 @@ extern struct videobuf_queue_ops bttv_vbi_qops; /* ---------------------------------------------------------- */ /* bttv-gpio.c */ - extern struct bus_type bttv_sub_bus_type; int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_del_devices(struct bttv_core *core); - /* ---------------------------------------------------------- */ /* bttv-driver.c */ diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 03411503457e..1c3fa3a7470a 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -173,4 +173,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .probe = cs5345_probe, .id_table = cs5345_id, }; - diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index d965af860ab2..645b339152d3 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -43,7 +43,6 @@ MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; - I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -189,4 +188,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .probe = cs53l32a_probe, .id_table = cs53l32a_id, }; - diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index b421e0268b00..b78d0e38d53d 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -230,9 +230,7 @@ struct cx18_dvb { struct dvb_net dvbnet; int enabled; int feeding; - struct mutex feedlock; - }; struct cx18; /* forward reference */ diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index 3f972e2db705..6023ba3bd3a6 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c @@ -39,10 +39,6 @@ #define GETSCL_BIT 0x0004 #define GETSDL_BIT 0x0008 -#ifndef I2C_ADAP_CLASS_TV_ANALOG -#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG -#endif - #define CX18_CS5345_I2C_ADDR 0x4c /* This array should match the CX18_HW_ defines */ diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 1da6f134888d..8d5f25caf01b 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -50,7 +50,6 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; - int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 80c8883e54b5..06f171ab6149 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c @@ -82,7 +82,6 @@ typedef struct cx88_audio_dev snd_cx88_card_t; - /**************************************************************************** Module global static vars ****************************************************************************/ diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c index cb6a096069c7..d7406a994f09 100644 --- a/drivers/media/video/cx88/cx88-i2c.c +++ b/drivers/media/video/cx88/cx88-i2c.c @@ -103,7 +103,6 @@ static int attach_inform(struct i2c_client *client) dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n", client->driver->driver.name, client->addr, client->name); - return 0; } diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c index 6ce5af488471..20800425c51e 100644 --- a/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c @@ -30,7 +30,6 @@ #include "cx88.h" #include "cx88-vp3054-i2c.h" - MODULE_DESCRIPTION("driver for cx2388x VP3054 design"); MODULE_AUTHOR("Chris Pascoe "); MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 6a78fd294cab..97853384c943 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c @@ -432,7 +432,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL; } - /* * attach_inform() * gets called when a device attaches to the i2c bus diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 70b4cac37a50..ba245bafcd6f 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -2186,3 +2186,4 @@ module_exit(sd_mod_exit); module_param(frame_rate, int, 0644); MODULE_PARM_DESC(frame_rate, "Frame rate (5, 10, 15, 20 or 30 fps)"); + diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 9d23b1efd36d..a08bb3331cfb 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -635,7 +635,6 @@ struct ivtv { spinlock_t lock; /* lock access to this struct */ struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ - /* Streams */ int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */ struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */ diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index 32129f3ea836..a1b37ff8669c 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -75,10 +75,6 @@ #define IVTV_REG_I2C_GETSCL_OFFSET 0x7008 #define IVTV_REG_I2C_GETSDA_OFFSET 0x700c -#ifndef I2C_ADAP_CLASS_TV_ANALOG -#define I2C_ADAP_CLASS_TV_ANALOG I2C_CLASS_TV_ANALOG -#endif /* I2C_ADAP_CLASS_TV_ANALOG */ - #define IVTV_CS53L32A_I2C_ADDR 0x11 #define IVTV_M52790_I2C_ADDR 0x48 #define IVTV_CX25840_I2C_ADDR 0x44 diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 8e0160d275ca..39bf6b114d50 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -171,4 +171,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = m52790_remove, .id_table = m52790_id, }; - diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 310dbaba55ff..5691e019d195 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -110,6 +110,7 @@ MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); /* Addresses to scan */ static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END }; + I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ @@ -333,7 +334,6 @@ void msp_set_audio(struct i2c_client *client) /* ------------------------------------------------------------------------ */ - static void msp_wake_thread(struct i2c_client *client) { struct msp_state *state = i2c_get_clientdata(client); @@ -1004,7 +1004,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = msp_id, }; - /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 7f5568592793..1622f70e4dd0 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -480,7 +480,6 @@ int msp3400c_thread(void *data) struct msp3400c_carrier_detect *cd; int count, max1, max2, val1, val2, val, i; - v4l_dbg(1, msp_debug, client, "msp3400 daemon started\n"); set_freezable(); for (;;) { diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index ea53316d2111..1cccd5c77048 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -1255,7 +1255,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) exactly the same otherwise. */ - /* define local variable for arg */ #define ARG_DEF(ARG_type, ARG_name)\ ARG_type *ARG_name = arg; @@ -1268,7 +1267,6 @@ int pwc_get_cmos_sensor(struct pwc_device *pdev, int *sensor) /* copy local variable to arg */ #define ARG_OUT(ARG_name) /* nothing */ - int pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) { int ret = 0; diff --git a/drivers/media/video/pwc/pwc-ioctl.h b/drivers/media/video/pwc/pwc-ioctl.h index cec660299768..8c0cae7b3daf 100644 --- a/drivers/media/video/pwc/pwc-ioctl.h +++ b/drivers/media/video/pwc/pwc-ioctl.h @@ -54,7 +54,6 @@ #include #include - /* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 996b49491f5a..03e772130b55 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -66,6 +66,7 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = { I2C_ADDRESS, I2C_CLIENT_END }; + I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index ec8c65dc8408..fde99d9ee71f 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -130,6 +130,7 @@ static struct video_device saa_template; /* Declared near bottom */ /* Addresses to scan */ static unsigned short normal_i2c[] = {34>>1,I2C_CLIENT_END}; + I2C_CLIENT_INSMOD; static struct i2c_client client_template; diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 716ee7f64df3..f05024259f01 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c @@ -31,7 +31,6 @@ #include #include - #include /* Addresses to scan */ diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index 435c083cc542..f0baca71dd3e 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -67,7 +67,6 @@ static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ I2C_CLIENT_END }; - I2C_CLIENT_INSMOD; struct saa711x_state { @@ -1577,4 +1576,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL, .id_table = saa7115_id, }; - diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 79d11a658bdf..7ba10e56c609 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -753,4 +753,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = saa7127_remove, .id_table = saa7127_id, }; - diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index fc32c3f68af1..707be175509d 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -13,7 +13,6 @@ #include #include - #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 #define MPEG_VIDEO_MAX_BITRATE_MAX 27000 #define MPEG_TOTAL_TARGET_BITRATE_MAX 27000 @@ -21,6 +20,7 @@ /* Addresses to scan */ static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END}; + I2C_CLIENT_INSMOD; MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder"); @@ -707,7 +707,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) i2c_attach_client(&h->client); v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); - return 0; } diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index f118de6e3672..9929d20320b4 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -80,7 +80,6 @@ typedef struct snd_card_saa7134 { } snd_card_saa7134_t; - /* * PCM structure */ @@ -1121,6 +1120,3 @@ late_initcall(saa7134_alsa_init); module_exit(saa7134_alsa_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ricardo Cerqueira"); - - - diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 932a93cab3ef..2511d0679c58 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -4220,6 +4220,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, @@ -4246,7 +4247,6 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, .vmux = 1, diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 2c19cd0113c8..cfee84ee7a88 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -150,7 +150,6 @@ void saa7134_set_gpio(struct saa7134_dev *dev, int bit_no, int value) #if defined(CONFIG_MODULES) && defined(MODULE) - static void request_module_async(struct work_struct *work){ struct saa7134_dev* dev = container_of(work, struct saa7134_dev, request_module_wk); if (card_is_empress(dev)) diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c index 4cc3741c5472..c5d0b44c179e 100644 --- a/drivers/media/video/saa7134/saa7134-tvaudio.c +++ b/drivers/media/video/saa7134/saa7134-tvaudio.c @@ -477,7 +477,6 @@ static int tvaudio_thread(void *data) unsigned int i, audio, nscan; int max1,max2,carrier,rx,mode,lastmode,default_carrier; - set_freezable(); for (;;) { @@ -775,7 +774,6 @@ static int tvaudio_thread_ddep(void *data) struct saa7134_dev *dev = data; u32 value, norms; - set_freezable(); for (;;) { tvaudio_sleep(dev,-1); diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index b4d10f7a4e57..ae75c187da79 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -72,6 +72,7 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA7432 >> 1, I2C_CLIENT_END, }; + I2C_CLIENT_INSMOD; /* Structure of address and subaddresses for the tda7432 */ diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 0cee00242782..2437c1a269c5 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -34,6 +34,7 @@ static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); + #define dprintk(args...) \ do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 3c0557130a70..7a8ce8fb46dc 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -30,7 +30,6 @@ #include #include - #include static int debug; /* insmod parameter */ @@ -42,6 +41,7 @@ static unsigned short normal_i2c[] = { I2C_ADDR_TDA9875 >> 1, I2C_CLIENT_END }; + I2C_CLIENT_INSMOD; /* This is a superset of the TDA9875 */ diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 9513d8611e87..421c1445e96c 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -36,6 +36,7 @@ static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); + #define dprintk(args...) \ do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 7fd53367c07c..b5c8957d130e 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -36,6 +36,7 @@ static int debug; /* insmod parameter */ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); + #define dprintk(args...) \ do { if (debug) { printk("%s: %s()[%d]: ", KBUILD_MODNAME, __func__, __LINE__); printk(args); } } while (0) diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c index 28ab9f9d760a..9220378a5637 100644 --- a/drivers/media/video/tlv320aic23b.c +++ b/drivers/media/video/tlv320aic23b.c @@ -39,7 +39,6 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END }; - I2C_CLIENT_INSMOD; /* ----------------------------------------------------------------------- */ diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 0d12ace61665..93d879dc510f 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1298,7 +1298,6 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .id_table = tuner_id, }; - /* * Overrides for Emacs so that we follow Linus's tabbing style. * --------------------------------------------------------------------------- diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index a9c5e5adba3a..abf685464b7c 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c @@ -169,7 +169,6 @@ static void usbvision_rvfree(void *mem, unsigned long size) } - #if ENABLE_HEXDUMP static void usbvision_hexdump(const unsigned char *data, int len) { @@ -2317,7 +2316,6 @@ static void usbvision_powerOffTimer(unsigned long data) del_timer(&usbvision->powerOffTimer); INIT_WORK(&usbvision->powerOffWork, call_usbvision_power_off); (void) schedule_work(&usbvision->powerOffWork); - } void usbvision_init_powerOffTimer(struct usb_usbvision *usbvision) @@ -2518,7 +2516,6 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision) } } - /* Submit all URBs */ for (bufIdx = 0; bufIdx < USBVISION_NUMSBUF; bufIdx++) { errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb, @@ -2564,7 +2561,6 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision) usbvision->sbuf[bufIdx].urb = NULL; } - PDEBUG(DBG_ISOC, "%s: streaming=Stream_Off\n", __func__); usbvision->streaming = Stream_Off; diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c index e2274d77ea29..a6d00858b07e 100644 --- a/drivers/media/video/usbvision/usbvision-i2c.c +++ b/drivers/media/video/usbvision/usbvision-i2c.c @@ -190,7 +190,6 @@ static u32 functionality(struct i2c_adapter *adap) return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR; } - /* -----exported algorithm data: ------------------------------------- */ static struct i2c_algorithm usbvision_algo = { @@ -514,11 +513,7 @@ static struct i2c_adapter i2c_adap_template = { .id = I2C_HW_B_BT848, /* FIXME */ .client_register = attach_inform, .client_unregister = detach_inform, -#ifdef I2C_ADAP_CLASS_TV_ANALOG - .class = I2C_ADAP_CLASS_TV_ANALOG, -#else .class = I2C_CLASS_TV_ANALOG, -#endif }; static struct i2c_client i2c_client_template = { diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index a9e5e08caec5..cd6c41d67899 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -179,7 +179,6 @@ MODULE_ALIAS(DRIVER_ALIAS); /* /sys/bus/usb/drivers/USBVision Video Grabber */ /*****************************************************************************/ - #define YES_NO(x) ((x) ? "Yes" : "No") static inline struct usb_usbvision *cd_to_usbvision(struct device *cd) @@ -370,7 +369,6 @@ static void usbvision_remove_sysfs(struct video_device *vdev) } } - /* * usbvision_open() * @@ -388,7 +386,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) PDEBUG(DBG_IO, "open"); - usbvision_reset_powerOffTimer(usbvision); if (usbvision->user) @@ -442,9 +439,6 @@ static int usbvision_v4l2_open(struct inode *inode, struct file *file) mutex_unlock(&usbvision->lock); } - if (errCode) { - } - /* prepare queues */ usbvision_empty_framequeues(usbvision); @@ -495,8 +489,6 @@ static int usbvision_v4l2_close(struct inode *inode, struct file *file) } PDEBUG(DBG_IO, "success"); - - return 0; } @@ -1346,9 +1338,7 @@ static int usbvision_radio_close(struct inode *inode, struct file *file) usbvision_release(usbvision); } - PDEBUG(DBG_IO, "success"); - return errCode; } @@ -1360,7 +1350,6 @@ static int usbvision_vbi_open(struct inode *inode, struct file *file) { /* TODO */ return -ENODEV; - } static int usbvision_vbi_close(struct inode *inode, struct file *file) @@ -1899,7 +1888,6 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf) } PDEBUG(DBG_PROBE, "success"); - } static struct usb_driver usbvision_driver = { diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f0ee46d15540..3ae95512666f 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -1254,3 +1254,4 @@ void uvc_ctrl_init(void) for (; mapping < mend; ++mapping) uvc_ctrl_add_mapping(mapping); } + diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 86bb16d00173..31a0e706a7f6 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1954,3 +1954,4 @@ MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); + diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 0923f0e3b3d4..7388d0cee3d4 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -475,3 +475,4 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, wake_up(&buf->wait); return nextbuf; } + diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 06b47980ed98..7bfddad37d8c 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -205,3 +205,4 @@ int uvc_status_resume(struct uvc_device *dev) return usb_submit_urb(dev->int_urb, GFP_NOIO); } + diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 2e0a66575bb4..0456bbdcd695 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1103,3 +1103,4 @@ struct file_operations uvc_fops = { .mmap = uvc_v4l2_mmap, .poll = uvc_v4l2_poll, }; + diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 817af2e36362..ad63794fda77 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -964,3 +964,4 @@ int uvc_video_enable(struct uvc_video_device *video, int enable) return uvc_init_video(video, GFP_KERNEL); } + diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 2444b8a9d2a0..bafe3406e305 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -796,3 +796,4 @@ void uvc_video_decode_isight(struct urb *urb, struct uvc_video_device *video, #endif /* __KERNEL__ */ #endif + diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c index 6e4d73ec6855..b56cffcbfd45 100644 --- a/drivers/media/video/videobuf-dvb.c +++ b/drivers/media/video/videobuf-dvb.c @@ -13,7 +13,6 @@ * (at your option) any later version. */ - #include #include #include @@ -257,4 +256,3 @@ EXPORT_SYMBOL(videobuf_dvb_unregister); * compile-command: "make DVB=1" * End: */ - diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index a1f76ee032e7..cbecb3cbbbaa 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -166,4 +166,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = vp27smpx_remove, .id_table = vp27smpx_id, }; - diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index fc50299caa36..7be47a255853 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -327,4 +327,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = wm8739_remove, .id_table = wm8739_id, }; - diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 506378a508b9..c2ab70a04a74 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -42,7 +42,6 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; - I2C_CLIENT_INSMOD; @@ -230,4 +229,3 @@ static struct v4l2_i2c_driver_data v4l2_i2c_data = { .remove = wm8775_remove, .id_table = wm8775_id, }; - diff --git a/include/media/pwc-ioctl.h b/include/media/pwc-ioctl.h index adc1254e887e..0f19779c4634 100644 --- a/include/media/pwc-ioctl.h +++ b/include/media/pwc-ioctl.h @@ -55,8 +55,7 @@ #include #include - - /* Enumeration of image sizes */ +/* Enumeration of image sizes */ #define PSZ_SQCIF 0x00 #define PSZ_QSIF 0x01 #define PSZ_QCIF 0x02 diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h index 878562278b67..975ffbf4e2c5 100644 --- a/include/media/v4l2-i2c-drv-legacy.h +++ b/include/media/v4l2-i2c-drv-legacy.h @@ -68,7 +68,6 @@ static int v4l2_i2c_drv_detach_legacy(struct i2c_client *client) if (err) return err; kfree(client); - return 0; } -- cgit v1.2.3 From c41492c89a00630c7482eae25deaf9af91b73c98 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 7 Jul 2008 08:31:16 -0300 Subject: V4L/DVB (8231): gspca: Do not declare the webcams declared by other drivers. etoms: Do not declare the webcams declared by the driver et61x251. sonixb, sonixj: Do not declare the webcams declared by the driver sn9c102. zc3xx: Do not declare the webcams declared by the driver zc0301. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/etoms.c | 2 ++ drivers/media/video/gspca/sonixb.c | 2 ++ drivers/media/video/gspca/sonixj.c | 4 ++++ drivers/media/video/gspca/vc032x.c | 16 ++++++++-------- drivers/media/video/gspca/zc3xx.c | 23 +++++++++++++++++------ 5 files changed, 33 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 4db33618af6b..1da6a182561f 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -912,7 +912,9 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { +#ifndef CONFIG_USB_ET61X251 {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, +#endif {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, {} }; diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 3dbeadf23e19..95a6a8e98b97 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -858,6 +858,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { +#ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, @@ -874,6 +875,7 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, +#endif {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 3db6487a705d..4cb1421b8807 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1606,11 +1606,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { +#ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, +#endif {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, @@ -1620,10 +1622,12 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, +#ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, +#endif {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index afbbbd290560..7ca6240c64e1 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -1332,20 +1332,20 @@ static __u8 i2c_write(struct usb_device *dev, if (size > 3 || size < 1) return -EINVAL; reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); - reg_w(dev, 0xa0, size , 0xb334); - reg_w(dev, 0xa0, reg , 0xb33a); + reg_w(dev, 0xa0, size, 0xb334); + reg_w(dev, 0xa0, reg, 0xb33a); switch (size) { case 1: - reg_w(dev, 0xa0, val[0] , 0xb336); + reg_w(dev, 0xa0, val[0], 0xb336); break; case 2: - reg_w(dev, 0xa0, val[0] , 0xb336); - reg_w(dev, 0xa0, val[1] , 0xb337); + reg_w(dev, 0xa0, val[0], 0xb336); + reg_w(dev, 0xa0, val[1], 0xb337); break; case 3: - reg_w(dev, 0xa0, val[0] , 0xb336); - reg_w(dev, 0xa0, val[1] , 0xb337); - reg_w(dev, 0xa0, val[2] , 0xb338); + reg_w(dev, 0xa0, val[0], 0xb336); + reg_w(dev, 0xa0, val[1], 0xb337); + reg_w(dev, 0xa0, val[2], 0xb338); break; default: reg_w(dev, 0xa0, 0x01, 0xb334); diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index eed9a8baf4ee..bac45a193653 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7132,10 +7132,10 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->nbalt--; if (vga) { cam->cam_mode = vga_mode; - cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + cam->nmodes = ARRAY_SIZE(vga_mode); } else { cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + cam->nmodes = ARRAY_SIZE(sif_mode); } sd->qindex = 1; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; @@ -7498,21 +7498,26 @@ static const struct sd_desc sd_desc = { #define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")}, {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")}, -/*0x041e, 0x4022*/ +#endif {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")}, {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")}, {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")}, {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")}, +#endif {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")}, {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")}, {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")}, {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")}, +#endif {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")}, {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")}, {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")}, @@ -7521,10 +7526,12 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")}, {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")}, {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")}, - {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, + {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")}, {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")}, +#endif {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")}, {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")}, {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")}, @@ -7537,18 +7544,22 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")}, {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")}, {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")}, {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")}, +#endif {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")}, -/*0x0ac8, 0x0301*/ {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")}, {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")}, +#endif {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")}, +#ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")}, {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")}, -/*0x10fd, 0x804e*/ {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")}, +#endif {} /* end of entry */ }; #undef DVNAME -- cgit v1.2.3 From ac0d6df69bc72eabda944fd14a958074dc08ca0c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 8 Jul 2008 06:58:15 -0300 Subject: V4L/DVB (8232): gspca: Change the USERPTR mechanism. main: Change the packet copy mechanism for userptr. Cannot do reqbufs ioctl when already done and count != 0. Accept count < frame size in read(). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 202 ++++++++++---------------------------- drivers/media/video/gspca/gspca.h | 2 - 2 files changed, 52 insertions(+), 152 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index cb0aeb0c0a45..77e5e4f4335b 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -36,15 +36,14 @@ #include "gspca.h" /* global values */ -#define DEF_NURBS 2 /* default number of URBs (mmap) */ -#define USR_NURBS 5 /* default number of URBs (userptr) */ +#define DEF_NURBS 2 /* default number of URBs */ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 6) +static const char version[] = "2.1.6"; static int video_nr = -1; @@ -153,7 +152,6 @@ static void fill_frame(struct gspca_dev *gspca_dev, } /* resubmit the URB */ -/*fixme: don't do that when userptr and too many URBs sent*/ urb->status = 0; st = usb_submit_urb(urb, GFP_ATOMIC); if (st < 0) @@ -163,18 +161,9 @@ static void fill_frame(struct gspca_dev *gspca_dev, /* * ISOC message interrupt from the USB device * - * Analyse each packet and call the subdriver for copy - * to the frame buffer. - * - * There are 2 functions: - * - the first one (isoc_irq_mmap) is used when the application - * buffers are mapped. The frame detection and copy is done - * at interrupt level. - * - the second one (isoc_irq_user) is used when the application - * buffers are in user space (userptr). The frame detection - * and copy is done by the application. + * Analyse each packet and call the subdriver for copy to the frame buffer. */ -static void isoc_irq_mmap(struct urb *urb +static void isoc_irq(struct urb *urb ) { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; @@ -185,56 +174,11 @@ static void isoc_irq_mmap(struct urb *urb fill_frame(gspca_dev, urb); } -static void isoc_irq_user(struct urb *urb -) -{ - struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - int i; - - PDEBUG(D_PACK, "isoc irq user"); - if (!gspca_dev->streaming) - return; - - i = gspca_dev->urb_in % gspca_dev->nurbs; - if (urb != gspca_dev->urb[i]) { - PDEBUG(D_ERR|D_PACK, "urb out of sequence"); - return; /* should never occur */ - } - - gspca_dev->urb_in++; - atomic_inc(&gspca_dev->nevent); /* new event */ - wake_up_interruptible(&gspca_dev->wq); -/*fixme: submit a new URBs until urb_in == urb_out (% nurbs)*/ -} - -/* - * treat the isoc messages - * - * This routine is called by the application (case userptr). - */ -static void isoc_transfer(struct gspca_dev *gspca_dev) -{ - struct urb *urb; - int i; - - for (;;) { - i = gspca_dev->urb_out; - PDEBUG(D_PACK, "isoc transf i:%d o:%d", gspca_dev->urb_in, i); - if (i == gspca_dev->urb_in) /* isoc message to read */ - break; /* no (more) message */ - atomic_dec(&gspca_dev->nevent); -/*PDEBUG(D_PACK, "isoc_trf nevent: %d", atomic_read(&gspca_dev->nevent));*/ - gspca_dev->urb_out = i + 1; /* message treated */ - urb = gspca_dev->urb[i % gspca_dev->nurbs]; - fill_frame(gspca_dev, urb); - } -} - /* * add data to the current frame * - * This function is called by the subdrivers at interrupt level - * or user level. + * This function is called by the subdrivers at interrupt level. + * * To build a frame, these ones must add * - one FIRST_PACKET * - 0 or many INTER_PACKETs @@ -277,16 +221,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, frame->v4l2_buf.length); packet_type = DISCARD_PACKET; } else { - if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) { - memcpy(frame->data_end, data, len); - } else { - if (copy_to_user(frame->data_end, - data, len) != 0) { - PDEBUG(D_ERR|D_PACK, - "copy to user failed"); - packet_type = DISCARD_PACKET; - } - } + memcpy(frame->data_end, data, len); frame->data_end += len; } } @@ -333,7 +268,6 @@ static void *rvmalloc(unsigned long size) /* size = PAGE_ALIGN(size); (already done) */ mem = vmalloc_32(size); if (mem != NULL) { - memset(mem, 0, size); adr = (unsigned long) mem; while ((long) size > 0) { SetPageReserved(vmalloc_to_page((void *) adr)); @@ -344,14 +278,12 @@ static void *rvmalloc(unsigned long size) return mem; } -static void rvfree(void *mem, unsigned long size) +static void rvfree(void *mem, long size) { unsigned long adr; - if (!mem) - return; adr = (unsigned long) mem; - while ((long) size > 0) { + while (size > 0) { ClearPageReserved(vmalloc_to_page((void *) adr)); adr += PAGE_SIZE; size -= PAGE_SIZE; @@ -370,16 +302,13 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frsz = gspca_dev->cam.cam_mode[i].sizeimage; PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); frsz = PAGE_ALIGN(frsz); - PDEBUG(D_STREAM, "new fr_sz: %d", frsz); gspca_dev->frsz = frsz; if (count > GSPCA_MAX_FRAMES) count = GSPCA_MAX_FRAMES; - if (gspca_dev->memory == V4L2_MEMORY_MMAP) { - gspca_dev->frbuf = rvmalloc(frsz * count); - if (!gspca_dev->frbuf) { - err("frame alloc failed"); - return -ENOMEM; - } + gspca_dev->frbuf = rvmalloc(frsz * count); + if (!gspca_dev->frbuf) { + err("frame alloc failed"); + return -ENOMEM; } gspca_dev->nframes = count; for (i = 0; i < count; i++) { @@ -391,11 +320,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev, frame->v4l2_buf.length = frsz; frame->v4l2_buf.memory = gspca_dev->memory; frame->v4l2_buf.sequence = 0; - if (gspca_dev->memory == V4L2_MEMORY_MMAP) { - frame->data = frame->data_end = + frame->data = frame->data_end = gspca_dev->frbuf + i * frsz; - frame->v4l2_buf.m.offset = i * frsz; - } + frame->v4l2_buf.m.offset = i * frsz; } gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; gspca_dev->last_packet_type = DISCARD_PACKET; @@ -509,7 +436,6 @@ static int create_urbs(struct gspca_dev *gspca_dev, { struct urb *urb; int n, nurbs, i, psize, npkt, bsize; - usb_complete_t usb_complete; /* calculate the packet size and the number of packets */ psize = le16_to_cpu(ep->desc.wMaxPacketSize); @@ -522,14 +448,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, bsize = psize * npkt; PDEBUG(D_STREAM, "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); -/*fixme:don't submit all URBs when userptr*/ - if (gspca_dev->memory != V4L2_MEMORY_USERPTR) { - usb_complete = isoc_irq_mmap; - nurbs = DEF_NURBS; - } else { - usb_complete = isoc_irq_user; - nurbs = USR_NURBS; - } + nurbs = DEF_NURBS; gspca_dev->nurbs = nurbs; for (n = 0; n < nurbs; n++) { urb = usb_alloc_urb(npkt, GFP_KERNEL); @@ -556,7 +475,7 @@ static int create_urbs(struct gspca_dev *gspca_dev, urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; urb->interval = ep->desc.bInterval; - urb->complete = usb_complete; + urb->complete = isoc_irq; urb->number_of_packets = npkt; urb->transfer_buffer_length = bsize; for (i = 0; i < npkt; i++) { @@ -564,7 +483,6 @@ static int create_urbs(struct gspca_dev *gspca_dev, urb->iso_frame_desc[i].offset = psize * i; } } - gspca_dev->urb_in = gspca_dev->urb_out = 0; return 0; } @@ -1063,6 +981,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; switch (rb->memory) { + case GSPCA_MEMORY_READ: case V4L2_MEMORY_MMAP: case V4L2_MEMORY_USERPTR: break; @@ -1072,13 +991,6 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - for (i = 0; i < gspca_dev->nframes; i++) { - if (gspca_dev->frame[i].vma_use_count) { - ret = -EBUSY; - goto out; - } - } - /* only one file may do capture */ if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file) || gspca_dev->streaming) { @@ -1086,10 +998,20 @@ static int vidioc_reqbufs(struct file *file, void *priv, goto out; } - if (rb->count == 0) { /* unrequest? */ + if (rb->count == 0) { /* unrequest */ + for (i = 0; i < gspca_dev->nframes; i++) { + if (gspca_dev->frame[i].vma_use_count) { + ret = -EBUSY; + goto out; + } + } frame_free(gspca_dev); gspca_dev->capt_file = NULL; } else { + if (gspca_dev->nframes != 0) { + ret = -EBUSY; + goto out; + } gspca_dev->memory = rb->memory; ret = frame_alloc(gspca_dev, rb->count); if (ret == 0) { @@ -1301,9 +1223,6 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) struct page *page; unsigned long addr, start, size; int i, ret; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - int compat = 0; -#endif start = vma->vm_start; size = vma->vm_end - vma->vm_start; @@ -1338,11 +1257,11 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) goto out; } #ifdef CONFIG_VIDEO_V4L1_COMPAT - if (i == 0 && size == frame->v4l2_buf.length * gspca_dev->nframes) - compat = 1; - else + /* v4l1 maps all the buffers */ + if (i != 0 + || size != frame->v4l2_buf.length * gspca_dev->nframes) #endif - if (size != frame->v4l2_buf.length) { + if (size != frame->v4l2_buf.length) { PDEBUG(D_STREAM, "mmap bad size"); ret = -EINVAL; goto out; @@ -1368,14 +1287,6 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &gspca_vm_ops; vma->vm_private_data = frame; gspca_vm_open(vma); -#ifdef CONFIG_VIDEO_V4L1_COMPAT - if (compat) { -/*fixme: ugly*/ - for (i = 1; i < gspca_dev->nframes; ++i) - gspca_dev->frame[i].v4l2_buf.flags |= - V4L2_BUF_FLAG_MAPPED; - } -#endif ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); @@ -1393,10 +1304,6 @@ static int frame_wait(struct gspca_dev *gspca_dev, struct gspca_frame *frame; int i, j, ret; - /* if userptr, treat the awaiting URBs */ - if (gspca_dev->memory == V4L2_MEMORY_USERPTR) - isoc_transfer(gspca_dev); - /* check if a frame is ready */ i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; @@ -1421,8 +1328,6 @@ static int frame_wait(struct gspca_dev *gspca_dev, atomic_dec(&gspca_dev->nevent); if (!gspca_dev->streaming || !gspca_dev->present) return -EIO; - if (gspca_dev->memory == V4L2_MEMORY_USERPTR) - isoc_transfer(gspca_dev); i = gspca_dev->fr_o; j = gspca_dev->fr_queue[i]; frame = &gspca_dev->frame[j]; @@ -1455,9 +1360,9 @@ static int vidioc_dqbuf(struct file *file, void *priv, int i, ret; PDEBUG(D_FRAM, "dqbuf"); - if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE - || (v4l2_buf->memory != V4L2_MEMORY_MMAP - && v4l2_buf->memory != V4L2_MEMORY_USERPTR)) + if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (v4l2_buf->memory != gspca_dev->memory) return -EINVAL; if (!gspca_dev->streaming) return -EINVAL; @@ -1475,6 +1380,16 @@ static int vidioc_dqbuf(struct file *file, void *priv, goto out; i = ret; /* frame index */ frame = &gspca_dev->frame[i]; + if (gspca_dev->memory == V4L2_MEMORY_USERPTR) { + if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr, + frame->data, + frame->v4l2_buf.bytesused)) { + PDEBUG(D_ERR|D_STREAM, + "dqbuf cp to user failed"); + ret = -EFAULT; + goto out; + } + } frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); PDEBUG(D_FRAM, "dqbuf %d", i); @@ -1529,8 +1444,6 @@ static int vidioc_qbuf(struct file *file, void *priv, /* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */ if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { - frame->data = frame->data_end = - (__u8 *) v4l2_buf->m.userptr; frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; frame->v4l2_buf.length = v4l2_buf->length; } @@ -1568,7 +1481,7 @@ static int read_alloc(struct gspca_dev *gspca_dev, memset(&rb, 0, sizeof rb); rb.count = gspca_dev->nbufread; rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - rb.memory = V4L2_MEMORY_MMAP; + rb.memory = GSPCA_MEMORY_READ; ret = vidioc_reqbufs(file, gspca_dev, &rb); if (ret != 0) { PDEBUG(D_STREAM, "read reqbuf err %d", ret); @@ -1576,7 +1489,7 @@ static int read_alloc(struct gspca_dev *gspca_dev, } memset(&v4l2_buf, 0, sizeof v4l2_buf); v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buf.memory = V4L2_MEMORY_MMAP; + v4l2_buf.memory = GSPCA_MEMORY_READ; for (i = 0; i < gspca_dev->nbufread; i++) { v4l2_buf.index = i; /*fixme: ugly!*/ @@ -1629,11 +1542,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) goto out; } - /* if userptr, treat the awaiting URBs */ - if (gspca_dev->memory == V4L2_MEMORY_USERPTR - && gspca_dev->capt_file == file) - isoc_transfer(gspca_dev); - i = gspca_dev->fr_o; i = gspca_dev->fr_queue[i]; if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) @@ -1678,7 +1586,7 @@ static ssize_t dev_read(struct file *file, char __user *data, for (;;) { memset(&v4l2_buf, 0, sizeof v4l2_buf); v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buf.memory = V4L2_MEMORY_MMAP; + v4l2_buf.memory = GSPCA_MEMORY_READ; ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf); if (ret != 0) { PDEBUG(D_STREAM, "read dqbuf err %d", ret); @@ -1700,14 +1608,8 @@ static ssize_t dev_read(struct file *file, char __user *data, } /* copy the frame */ - if (count < frame->v4l2_buf.bytesused) { - PDEBUG(D_STREAM, "read bad count: %d < %d", - count, frame->v4l2_buf.bytesused); -/*fixme: special errno?*/ - ret = -EINVAL; - goto out; - } - count = frame->v4l2_buf.bytesused; + if (count > frame->v4l2_buf.bytesused) + count = frame->v4l2_buf.bytesused; ret = copy_to_user(data, frame->data, count); if (ret != 0) { PDEBUG(D_ERR|D_STREAM, diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 945f1ab4c9eb..9b645af81a07 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -156,8 +156,6 @@ struct gspca_dev { char nbufread; /* number of buffers for read() */ char nurbs; /* number of allocated URBs */ char memory; /* memory type (V4L2_MEMORY_xxx) */ - __u8 urb_in; /* URB pointers - used when !mmap */ - __u8 urb_out; __u8 nbalt; /* number of USB alternate settings */ }; -- cgit v1.2.3 From 6833c917b4de1757febdbf946d709ece6dc7a86f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 7 Jul 2008 23:04:29 -0300 Subject: V4L/DVB (8234): uvcvideo: Make input device support optional UVC devices can report button events. The uvcvideo driver depends on CONFIG_INPUT to report events to the input layer. This patch removes the hard dependency by introducing a new CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV option. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/Kconfig | 17 +++++++++++++++++ drivers/media/video/uvc/uvc_status.c | 17 +++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 drivers/media/video/uvc/Kconfig (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/Kconfig b/drivers/media/video/uvc/Kconfig new file mode 100644 index 000000000000..c2d9760de832 --- /dev/null +++ b/drivers/media/video/uvc/Kconfig @@ -0,0 +1,17 @@ +config USB_VIDEO_CLASS + tristate "USB Video Class (UVC)" + ---help--- + Support for the USB Video Class (UVC). Currently only video + input devices, such as webcams, are supported. + + For more information see: + +config USB_VIDEO_CLASS_INPUT_EVDEV + bool "UVC input events device support" + default y + depends on USB_VIDEO_CLASS && INPUT + ---help--- + This option makes USB Video Class devices register an input device + to report button events. + + If you are in doubt, say Y. diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c index 7bfddad37d8c..75e678ac54eb 100644 --- a/drivers/media/video/uvc/uvc_status.c +++ b/drivers/media/video/uvc/uvc_status.c @@ -22,6 +22,7 @@ /* -------------------------------------------------------------------------- * Input device */ +#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV static int uvc_input_init(struct uvc_device *dev) { struct usb_device *udev = dev->udev; @@ -67,6 +68,19 @@ static void uvc_input_cleanup(struct uvc_device *dev) input_unregister_device(dev->input); } +static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, + int value) +{ + if (dev->input) + input_report_key(dev->input, code, value); +} + +#else +#define uvc_input_init(dev) +#define uvc_input_cleanup(dev) +#define uvc_input_report_key(dev, code, value) +#endif /* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV */ + /* -------------------------------------------------------------------------- * Status interrupt endpoint */ @@ -83,8 +97,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) return; uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len); - if (dev->input) - input_report_key(dev->input, BTN_0, data[3]); + uvc_input_report_key(dev, BTN_0, data[3]); } else { uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " "len %d.\n", data[1], data[2], data[3], len); -- cgit v1.2.3 From bdf2fe4a0b9d23e69c77eaec76212216c9a957ef Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 7 Jul 2008 23:41:40 -0300 Subject: V4L/DVB (8235): uvcvideo : Add support for Medion Akoya Mini E1210 integrated webcam Signed-off-by: Tim Gardner Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 31a0e706a7f6..2c0b16960b25 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1892,6 +1892,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* Medion Akoya Mini E1210 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x5986, + .idProduct = 0x0141, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Acer OrbiCam - Unknown vendor */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- cgit v1.2.3 From 52b5045078b76ee86e210210601d45670eab22f1 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 9 Jul 2008 02:18:49 -0300 Subject: V4L/DVB (8236): cx23885: add support for new revision of FusionHDTV7 Dual Express The new revision of this board uses the same pci subsystem id as the first revision, but uses a S5H1411 demodulator instead of the S5H1409. In the case of the FusionHDTV7 Dual Express, if s5h1409_attach fails, try s5h1411_attach. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/Kconfig | 1 + drivers/media/video/cx23885/cx23885-dvb.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 7bf14c9a15c7..04e9640c2ca4 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -14,6 +14,7 @@ config VIDEO_CX23885 select DVB_DIB7000P if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2131 if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE + select DVB_S5H1411 if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 51dedb182c99..0a2e6558cd66 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -31,6 +31,7 @@ #include #include "s5h1409.h" +#include "s5h1411.h" #include "mt2131.h" #include "tda8290.h" #include "tda18271.h" @@ -174,6 +175,16 @@ static struct s5h1409_config dvico_s5h1409_config = { .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, }; +static struct s5h1411_config dvico_s5h1411_config = { + .output_mode = S5H1411_SERIAL_OUTPUT, + .gpio = S5H1411_GPIO_ON, + .qam_if = S5H1411_IF_44000, + .vsb_if = S5H1411_IF_44000, + .inversion = S5H1411_INVERSION_OFF, + .status_mode = S5H1411_DEMODLOCKING, + .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, +}; + static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { .i2c_address = 0x61, .if_khz = 5380, @@ -475,6 +486,10 @@ static int dvb_register(struct cx23885_tsport *port) port->dvb.frontend = dvb_attach(s5h1409_attach, &dvico_s5h1409_config, &i2c_bus->i2c_adap); + if (port->dvb.frontend == NULL) + port->dvb.frontend = dvb_attach(s5h1411_attach, + &dvico_s5h1411_config, + &i2c_bus->i2c_adap); if (port->dvb.frontend != NULL) dvb_attach(xc5000_attach, port->dvb.frontend, &i2c_bus->i2c_adap, -- cgit v1.2.3 From e2fc00c21124d9d9a8d4f396e5498ea27ddfc8fd Mon Sep 17 00:00:00 2001 From: Massimo Piccioni Date: Fri, 11 Jul 2008 13:48:02 -0300 Subject: V4L/DVB (8244): saa7134: add support for AVerMedia M103 The following patch updates saa7134 driver to add support for AVerMedia M103 MiniPCI DVB-T Hybrid card. Signed-off-by: Massimo Piccioni [mchehab@infradead.org: fixed merge conflicts and a small codingstyle] Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/video/saa7134/saa7134-cards.c | 25 +++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-dvb.c | 10 ++++++++++ drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 37 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index f58192276017..171905e872f1 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -143,3 +143,4 @@ 142 -> Beholder BeholdTV H6 [5ace:6290] 143 -> Beholder BeholdTV M63 [5ace:6191] 144 -> Beholder BeholdTV M6 Extra [5ace:6193] +145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636] diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 2511d0679c58..4e6e5ccaa35e 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -1287,6 +1287,22 @@ struct saa7134_board saa7134_boards[] = { .vmux = 8, }}, }, + [SAA7134_BOARD_AVERMEDIA_M103] = { + /* Massimo Piccioni */ + .name = "AVerMedia MiniPCI DVB-T Hybrid M103", + .audio_clock = 0x187de7, + .tuner_type = TUNER_XC2028, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + } }, + }, [SAA7134_BOARD_NOVAC_PRIMETV7133] = { /* toshii@netbsd.org */ .name = "Noval Prime TV 7133", @@ -5376,6 +5392,12 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x5ace, .subdevice = 0x6290, .driver_data = SAA7134_BOARD_BEHOLD_H6, + }, { + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0xf636, + .driver_data = SAA7134_BOARD_AVERMEDIA_M103, }, { /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -5441,6 +5463,7 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev, saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); saa7134_set_gpio(dev, 23, 1); @@ -5649,6 +5672,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) msleep(10); break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: saa7134_set_gpio(dev, 23, 0); msleep(10); saa7134_set_gpio(dev, 23, 1); @@ -5774,6 +5798,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev) switch (dev->board) { case SAA7134_BOARD_AVERMEDIA_A16D: case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: + case SAA7134_BOARD_AVERMEDIA_M103: ctl.demod = XC3028_FE_ZARLINK456; break; default: diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 341b101b0357..be48b9b66a67 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -1263,6 +1263,7 @@ static int dvb_init(struct saa7134_dev *dev) &avermedia_xc3028_mt352_dev, &dev->i2c_adap); attach_xc3028 = 1; + break; case SAA7134_BOARD_MD7134_BRIDGE_2: dev->dvb.frontend = dvb_attach(tda10086_attach, &sd1878_4m, &dev->i2c_adap); @@ -1290,6 +1291,15 @@ static int dvb_init(struct saa7134_dev *dev) fe->ops.enable_high_lnb_voltage = md8800_set_high_voltage; } break; + case SAA7134_BOARD_AVERMEDIA_M103: + saa7134_set_gpio(dev, 25, 0); + msleep(10); + saa7134_set_gpio(dev, 25, 1); + dev->dvb.frontend = dvb_attach(mt352_attach, + &avermedia_xc3028_mt352_dev, + &dev->i2c_adap); + attach_xc3028 = 1; + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 4e491ad389ac..6e5a4094d6be 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -266,6 +266,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_H6 142 #define SAA7134_BOARD_BEHOLD_M63 143 #define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 +#define SAA7134_BOARD_AVERMEDIA_M103 145 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3 From be99af6679174e5d0e9f36fc8c18318a8ce34bca Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 10 Jul 2008 11:04:10 -0300 Subject: V4L/DVB (8245): ovcamchip: Delete stray I2C bus ID I2C_HW_SMBUS_OVFX2 is referenced in ovcamchip_core.c, but no bus uses this driver ID, so we can remove the reference. As far as I can see, the Cypress FX2 webcam is handled by a different driver (dvb-usb). Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ovcamchip/ovcamchip_core.c | 1 - include/linux/i2c-id.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c index 8063e33f1c85..065c2454113e 100644 --- a/drivers/media/video/ovcamchip/ovcamchip_core.c +++ b/drivers/media/video/ovcamchip/ovcamchip_core.c @@ -297,7 +297,6 @@ static int ovcamchip_attach(struct i2c_adapter *adap) switch (adap->id) { 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; diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index ef13b7c66df3..9083847157a3 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -158,7 +158,6 @@ #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_OVFX2 0x040011 /* Cypress/OmniVision FX2 webcam */ #define I2C_HW_SMBUS_CAFE 0x040012 /* Marvell 88ALP01 "CAFE" cam */ #define I2C_HW_SMBUS_ALI1563 0x040013 -- cgit v1.2.3 From 5a367dfb739831d54caf226ce0bc4c75ef264d8d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 10 Jul 2008 11:23:37 -0300 Subject: V4L/DVB (8246): tvaudio: Stop I2C driver ID abuse The tvaudio driver is using "official" I2C device IDs for internal purpose. There must be some historical reason behind this but anyway, it shouldn't do that. As the stored values are never used, the easiest way to fix the problem is simply to remove them altogether. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/tvaudio.c | 13 ------------- include/linux/i2c-id.h | 7 ------- 2 files changed, 20 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index c77914d99d15..463680b13289 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -69,7 +69,6 @@ typedef struct AUDIOCMD { /* chip description */ struct CHIPDESC { char *name; /* chip name */ - int id; /* ID */ int addr_lo, addr_hi; /* i2c address range */ int registers; /* # of registers */ @@ -1256,7 +1255,6 @@ module_param(ta8874z, int, 0444); static struct CHIPDESC chiplist[] = { { .name = "tda9840", - .id = I2C_DRIVERID_TDA9840, .insmodopt = &tda9840, .addr_lo = I2C_ADDR_TDA9840 >> 1, .addr_hi = I2C_ADDR_TDA9840 >> 1, @@ -1272,7 +1270,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tda9873h", - .id = I2C_DRIVERID_TDA9873, .checkit = tda9873_checkit, .insmodopt = &tda9873, .addr_lo = I2C_ADDR_TDA985x_L >> 1, @@ -1293,7 +1290,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tda9874h/a", - .id = I2C_DRIVERID_TDA9874, .checkit = tda9874a_checkit, .initialize = tda9874a_initialize, .insmodopt = &tda9874a, @@ -1306,7 +1302,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tda9850", - .id = I2C_DRIVERID_TDA9850, .insmodopt = &tda9850, .addr_lo = I2C_ADDR_TDA985x_L >> 1, .addr_hi = I2C_ADDR_TDA985x_H >> 1, @@ -1319,7 +1314,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tda9855", - .id = I2C_DRIVERID_TDA9855, .insmodopt = &tda9855, .addr_lo = I2C_ADDR_TDA985x_L >> 1, .addr_hi = I2C_ADDR_TDA985x_H >> 1, @@ -1344,7 +1338,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tea6300", - .id = I2C_DRIVERID_TEA6300, .insmodopt = &tea6300, .addr_lo = I2C_ADDR_TEA6300 >> 1, .addr_hi = I2C_ADDR_TEA6300 >> 1, @@ -1365,7 +1358,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tea6320", - .id = I2C_DRIVERID_TEA6300, .initialize = tea6320_initialize, .insmodopt = &tea6320, .addr_lo = I2C_ADDR_TEA6300 >> 1, @@ -1387,7 +1379,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tea6420", - .id = I2C_DRIVERID_TEA6420, .insmodopt = &tea6420, .addr_lo = I2C_ADDR_TEA6420 >> 1, .addr_hi = I2C_ADDR_TEA6420 >> 1, @@ -1400,7 +1391,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "tda8425", - .id = I2C_DRIVERID_TDA8425, .insmodopt = &tda8425, .addr_lo = I2C_ADDR_TDA8425 >> 1, .addr_hi = I2C_ADDR_TDA8425 >> 1, @@ -1424,7 +1414,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "pic16c54 (PV951)", - .id = I2C_DRIVERID_PIC16C54_PV9, .insmodopt = &pic16c54, .addr_lo = I2C_ADDR_PIC16C54 >> 1, .addr_hi = I2C_ADDR_PIC16C54>> 1, @@ -1440,8 +1429,6 @@ static struct CHIPDESC chiplist[] = { }, { .name = "ta8874z", - .id = -1, - /*.id = I2C_DRIVERID_TA8874Z, */ .checkit = ta8874z_checkit, .insmodopt = &ta8874z, .addr_lo = I2C_ADDR_TDA9840 >> 1, diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 9083847157a3..4862398e05bf 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -33,15 +33,11 @@ #define I2C_DRIVERID_MSP3400 1 #define I2C_DRIVERID_TUNER 2 -#define I2C_DRIVERID_TDA8425 4 /* stereo sound processor */ #define I2C_DRIVERID_TEA6420 5 /* audio matrix switch */ #define I2C_DRIVERID_TEA6415C 6 /* video matrix switch */ #define I2C_DRIVERID_TDA9840 7 /* stereo sound processor */ #define I2C_DRIVERID_SAA7111A 8 /* video input processor */ #define I2C_DRIVERID_SAA7185B 13 /* video encoder */ -#define I2C_DRIVERID_TEA6300 18 /* audio mixer */ -#define I2C_DRIVERID_TDA9850 20 /* audio mixer */ -#define I2C_DRIVERID_TDA9855 21 /* audio mixer */ #define I2C_DRIVERID_SAA7110 22 /* video decoder */ #define I2C_DRIVERID_MGATVO 23 /* Matrox TVOut */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ @@ -50,9 +46,7 @@ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ -#define I2C_DRIVERID_TDA9873 31 /* TV sound decoder chip */ #define I2C_DRIVERID_TDA9875 32 /* TV sound decoder chip */ -#define I2C_DRIVERID_PIC16C54_PV9 33 /* Audio mux/ir receiver */ #define I2C_DRIVERID_BT819 40 /* video decoder */ #define I2C_DRIVERID_BT856 41 /* video encoder */ #define I2C_DRIVERID_VPX3220 42 /* video decoder+vbi/vtxt */ @@ -63,7 +57,6 @@ #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */ #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */ #define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */ -#define I2C_DRIVERID_TDA9874 66 /* TV sound decoder */ #define I2C_DRIVERID_SAA6752HS 67 /* MPEG2 encoder */ #define I2C_DRIVERID_TVEEPROM 68 /* TV EEPROM */ #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ -- cgit v1.2.3 From 3fce3fb0592841857ae01334d0c6934c1ad32faf Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 16:04:38 -0300 Subject: V4L/DVB (8249): Fix pointer cast warnings in the ivtv framebuffer driver Fix casts of pointers to integers of different sizes in the ivtv framebuffer driver. These were introduced in patch 38eb6ba5b8487d15b020fe391d324edd2b659b03. Signed-off-by: David Howells Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtvfb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index 14f93341f061..bdfda48e56bf 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -417,10 +417,11 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf, if (!err) { /* If transfer size > threshold and both src/dst addresses are aligned, use DMA */ - if (count >= 4096 && ((u32)buf & 3) == ((u32)dst & 3)) { + if (count >= 4096 && + ((unsigned long)buf & 3) == ((unsigned long)dst & 3)) { /* Odd address = can't DMA. Align */ - if ((u32)dst & 3) { - lead = 4 - ((u32)dst & 3); + if ((unsigned long)dst & 3) { + lead = 4 - ((unsigned long)dst & 3); memcpy(dst, buf, lead); buf += lead; dst += lead; -- cgit v1.2.3 From a8a89b7f60f18c2517c3b950f5ecede0626363eb Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 4 Jul 2008 06:33:20 -0300 Subject: V4L/DVB (8251): ttusb: use simple_read_from_buffer()() Signed-off-by: Akinobu Mita Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 156072239374..e6c9cd2e3b94 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -990,22 +991,9 @@ static int stc_open(struct inode *inode, struct file *file) } static ssize_t stc_read(struct file *file, char *buf, size_t count, - loff_t * offset) + loff_t *offset) { - int tc = count; - - if ((tc + *offset) > 8192) - tc = 8192 - *offset; - - if (tc < 0) - return 0; - - if (copy_to_user(buf, stc_firmware + *offset, tc)) - return -EFAULT; - - *offset += tc; - - return tc; + return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192); } static int stc_release(struct inode *inode, struct file *file) -- cgit v1.2.3 From a47cacbd869b67ce16981ad5a0b06e4eac2efaff Mon Sep 17 00:00:00 2001 From: Christophe Jaillet Date: Fri, 4 Jul 2008 06:33:22 -0300 Subject: V4L/DVB (8252): buf-dma-sg.c: avoid clearing memory twice 1) Remove a useless initialisation of 'i' 2) Avoid clearing the memory allocated twice (once in 'kcalloc', once in 'sg_init_table') 3) Remove a test that can never trigger. The function returns NULL in such a case, so we know that at this point 'pages[0]' != NULL Signed-off-by: Christophe Jaillet Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-sg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 03a7b946bd54..8ed60827d350 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -80,17 +80,15 @@ struct scatterlist* videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset) { struct scatterlist *sglist; - int i = 0; + int i; if (NULL == pages[0]) return NULL; - sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL); + sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL); if (NULL == sglist) return NULL; sg_init_table(sglist, nr_pages); - if (NULL == pages[0]) - goto nopage; if (PageHighMem(pages[0])) /* DMA to highmem pages might not work */ goto highmem; -- cgit v1.2.3 From a9e1113483f110723e4c0277a05d08f51da232aa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 9 Jul 2008 05:26:26 -0300 Subject: V4L/DVB (8253): gspca: fix warnings on x86_64 /home/v4l/master/v4l/gspca.c: In function 'gspca_frame_add': /home/v4l/master/v4l/gspca.c:222: warning: format '%d' expects type 'int', but argument 2 has type 'long int' /home/v4l/master/v4l/gspca.c: In function 'dev_read': /home/v4l/master/v4l/gspca.c:1568: warning: format '%d' expects type 'int', but argument 2 has type 'size_t' /home/v4l/master/v4l/gspca.c:1618: warning: format '%d' expects type 'int', but argument 3 has type 'size_t' Acked-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 77e5e4f4335b..09f190c689d5 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -216,7 +216,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, if (len > 0) { if (frame->data_end - frame->data + len > frame->v4l2_buf.length) { - PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d", + PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d", frame->data_end - frame->data + len, frame->v4l2_buf.length); packet_type = DISCARD_PACKET; @@ -1562,7 +1562,7 @@ static ssize_t dev_read(struct file *file, char __user *data, struct timeval timestamp; int n, ret, ret2; - PDEBUG(D_FRAM, "read (%d)", count); + PDEBUG(D_FRAM, "read (%zd)", count); if (!gspca_dev->present) return -ENODEV; switch (gspca_dev->memory) { @@ -1613,7 +1613,7 @@ static ssize_t dev_read(struct file *file, char __user *data, ret = copy_to_user(data, frame->data, count); if (ret != 0) { PDEBUG(D_ERR|D_STREAM, - "read cp to user lack %d / %d", ret, count); + "read cp to user lack %d / %zd", ret, count); ret = -EFAULT; goto out; } -- cgit v1.2.3 From 25e69850d1bb315f251c91183b89da44d4f9be23 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2008 18:29:59 -0300 Subject: V4L/DVB (8254): uvcvideo : Add support for Asus F9GS integrated webcam Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 2c0b16960b25..4deb04bc2a73 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1826,6 +1826,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* Asus F9SG */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x174f, + .idProduct = 0x8a31, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, /* Syntek (Asus U3S) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, -- cgit v1.2.3 From 6f80e1b4cda7e184e369c84a8b388882b0233d53 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 4 Jul 2008 06:33:23 -0300 Subject: V4L/DVB (8256): uvc/uvc_v4l2.c: suppress uninitialized var warning drivers/media/video/uvc/uvc_v4l2.c: In function `uvc_v4l2_mmap': drivers/media/video/uvc/uvc_v4l2.c:1035: warning: 'buffer' might be used uninitialized in this function Signed-off-by: Andrew Morton Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_v4l2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 0456bbdcd695..b5a11eb8f9fa 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -1032,7 +1032,7 @@ static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) { struct video_device *vdev = video_devdata(file); struct uvc_video_device *video = video_get_drvdata(vdev); - struct uvc_buffer *buffer; + struct uvc_buffer *uninitialized_var(buffer); struct page *page; unsigned long addr, start, size; unsigned int i; -- cgit v1.2.3 From a9e285856112e5e721b6a341d15437a164128b30 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 11 Jul 2008 19:32:15 -0300 Subject: V4L/DVB (8257): uvcvideo: Fix possible AB-BA deadlock with videodev_lock and open_mutex The uvcvideo driver's uvc_v4l2_open() method is called from videodev's video_open() function, which means it is called with the videodev_lock mutex held. uvc_v4l2_open() then takes uvc_driver.open_mutex to check dev->state and avoid racing against a device disconnect, which means that open_mutex must nest inside videodev_lock. However uvc_disconnect() takes the open_mutex around setting dev->state and also around putting its device reference. However, if uvc_disconnect() ends up dropping the last reference, it will call uvc_delete(), which calls into the videodev code to unregister its device, and this will end up taking videodev_lock. This opens a (unlikely in practice) window for an AB-BA deadlock and also causes a lockdep warning because of the lock misordering. Fortunately there is no apparent reason to hold open_mutex when doing kref_put() in uvc_disconnect(): if uvc_v4l2_open() runs before the state is set to UVC_DEV_DISCONNECTED, then it will take another reference to the device and kref_put() won't call uvc_delete; if uvc_v4l2_open() runs after the state is set, it will run before uvc_delete(), see the state, and return immediately -- uvc_delete() does uvc_unregister_video() (and hence video_unregister_device(), which is synchronized with videodev_lock) as its first thing, so there is no risk of use-after-free in uvc_v4l2_open(). Bug diagnosed based on a lockdep warning reported by Romano Giannetti . Signed-off-by: Roland Dreier Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_driver.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 4deb04bc2a73..f2b2983fe062 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1633,13 +1633,16 @@ static void uvc_disconnect(struct usb_interface *intf) * reference to the uvc_device instance after uvc_v4l2_open() received * the pointer to the device (video_devdata) but before it got the * chance to increase the reference count (kref_get). + * + * Note that the reference can't be released with the lock held, + * otherwise a AB-BA deadlock can occur with videodev_lock that + * videodev acquires in videodev_open() and video_unregister_device(). */ mutex_lock(&uvc_driver.open_mutex); - dev->state |= UVC_DEV_DISCONNECTED; - kref_put(&dev->kref, uvc_delete); - mutex_unlock(&uvc_driver.open_mutex); + + kref_put(&dev->kref, uvc_delete); } static int uvc_suspend(struct usb_interface *intf, pm_message_t message) -- cgit v1.2.3 From 2e5c1ec8865abd81e24a394918c7ba315e0b7b70 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 19 May 2008 18:56:13 -0300 Subject: V4L/DVB (8258): add support for SMS1010 and SMS1150 based digital television devices initial driver drop, provided by Siano Mobile Silicon, Inc. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 14 + drivers/media/Makefile | 1 + drivers/media/mdtv/Kconfig | 36 ++ drivers/media/mdtv/Makefile | 8 + drivers/media/mdtv/smschar.c | 575 ++++++++++++++++++ drivers/media/mdtv/smschar.h | 7 + drivers/media/mdtv/smscharioctl.h | 17 + drivers/media/mdtv/smscoreapi.c | 1170 +++++++++++++++++++++++++++++++++++++ drivers/media/mdtv/smscoreapi.h | 101 ++++ drivers/media/mdtv/smsdvb.c | 438 ++++++++++++++ drivers/media/mdtv/smskdefs.h | 21 + drivers/media/mdtv/smsnet.c | 447 ++++++++++++++ drivers/media/mdtv/smstypes.h | 361 ++++++++++++ drivers/media/mdtv/smsusb.c | 428 ++++++++++++++ 14 files changed, 3624 insertions(+) create mode 100644 drivers/media/mdtv/Kconfig create mode 100644 drivers/media/mdtv/Makefile create mode 100644 drivers/media/mdtv/smschar.c create mode 100644 drivers/media/mdtv/smschar.h create mode 100644 drivers/media/mdtv/smscharioctl.h create mode 100644 drivers/media/mdtv/smscoreapi.c create mode 100644 drivers/media/mdtv/smscoreapi.h create mode 100644 drivers/media/mdtv/smsdvb.c create mode 100644 drivers/media/mdtv/smskdefs.h create mode 100644 drivers/media/mdtv/smsnet.c create mode 100644 drivers/media/mdtv/smstypes.h create mode 100644 drivers/media/mdtv/smsusb.c (limited to 'drivers/media') diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 7a7803b5d497..e6a5879ea5f6 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -115,6 +115,20 @@ source "drivers/media/radio/Kconfig" source "drivers/media/dvb/Kconfig" +# +# Mobile Digital TV devices (DVB-H, T-DMB, etc.) +# +menuconfig MDTV_ADAPTERS + bool "Mobile Digital TV adapter" + default y + +if MDTV_ADAPTERS + +source "drivers/media/mdtv/Kconfig" + +endif # MDTV_ADAPTERS + + config DAB boolean "DAB adapters" ---help--- diff --git a/drivers/media/Makefile b/drivers/media/Makefile index 09a829d8a7e7..ec2102bcb282 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -6,3 +6,4 @@ obj-y += common/ video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB_CORE) += dvb/ +obj-$(CONFIG_MDTV_ADAPTERS) += mdtv/ \ No newline at end of file diff --git a/drivers/media/mdtv/Kconfig b/drivers/media/mdtv/Kconfig new file mode 100644 index 000000000000..f3bae45000d1 --- /dev/null +++ b/drivers/media/mdtv/Kconfig @@ -0,0 +1,36 @@ +# +# Mobile Digital TV device configuration +# + +config MDTV_SIANO_STELLAR_COMMON + tristate "Siano SMS10xx adapter" + default m + ---help--- + Choose Y here if you have SMS10xx chipset. + + In order to control the SMS10xx chipset you will need SMS Host Control library. + + Further documentation on this driver can be found on the WWW at + . + + To compile this driver as a module, choose M here: the + modules will be called smschar and smsnet. + +config MDTV_SIANO_STELLAR_USB + tristate "Siano SMS10xx USB dongle support" + depends on MDTV_SIANO_STELLAR_COMMON + default m + ---help--- + Choose Y here if you have USB dongle with SMS10xx chipset. + + In order to control the SMS10xx chipset you will need SMS Host Control library. + + Further documentation on this driver can be found on the WWW at + . + + To compile this driver as a module, choose M here: the + module will be called smsusb. + + + + diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile new file mode 100644 index 000000000000..1e54d8f796dc --- /dev/null +++ b/drivers/media/mdtv/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for the kernel MDTV driver +# + +obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smschar.o smsnet.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o + +EXTRA_CFLAGS += diff --git a/drivers/media/mdtv/smschar.c b/drivers/media/mdtv/smschar.c new file mode 100644 index 000000000000..0477ad0ed6d6 --- /dev/null +++ b/drivers/media/mdtv/smschar.c @@ -0,0 +1,575 @@ +/*! + + \file smschar.c + + \brief Implementation of smscore client for cdev based access + + \par Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + + \par This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation; + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. + + \author Anatoly Greenblat + +*/ + +#include +#include +#include + +#include /* printk() */ +#include /* everything... */ +#include /* size_t */ +#include +#include +#include /* cli(), *_flags */ +#include /* copy_*_user */ + +#include "smskdefs.h" // page, scatterlist, kmutex +#include "smscoreapi.h" +#include "smstypes.h" + +#include "smscharioctl.h" + +#define SMS_CHR_MAX_Q_LEN 10 // max number of packets allowed to be pending on queue +#define SMSCHAR_NR_DEVS 7 + +typedef struct _smschar_device +{ + struct cdev cdev; //!< Char device structure - kernel's device model representation + + wait_queue_head_t waitq; /* Processes waiting */ + spinlock_t lock; //!< critical section + int pending_count; + struct list_head pending_data; //!< list of pending data + + smscore_buffer_t *currentcb; + + int device_index; + + smscore_device_t *coredev; + smscore_client_t *smsclient; +} smschar_device_t; + +//! Holds the major number of the device node. may be changed at load time. +int smschar_major = 251; + +//! Holds the first minor number of the device node. may be changed at load time. +int smschar_minor = 0; + +// macros that allow the load time parameters change +module_param ( smschar_major, int, S_IRUGO ); +module_param ( smschar_minor, int, S_IRUGO ); + +#ifdef SMSCHAR_DEBUG + + #undef PERROR +# define PERROR(fmt, args...) printk( KERN_INFO "smschar error: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args) + #undef PWARNING +# define PWARNING(fmt, args...) printk( KERN_INFO "smschar warning: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args) + #undef PDEBUG /* undef it, just in case */ +# define PDEBUG(fmt, args...) printk( KERN_INFO "smschar - %s(): " fmt, __FUNCTION__, ## args) + +#else /* not debugging: nothing */ + + #define PDEBUG(fmt, args...) + #define PERROR(fmt, args...) + #define PWARNING(fmt, args...) + +#endif + +smschar_device_t smschar_devices[SMSCHAR_NR_DEVS]; +static int g_smschar_inuse = 0; + +/** + * unregisters sms client and returns all queued buffers + * + * @param dev pointer to the client context (smschar parameters block) + * + */ +void smschar_unregister_client(smschar_device_t* dev) +{ + unsigned long flags; + + if (dev->coredev && dev->smsclient) + { + wake_up_interruptible(&dev->waitq); + + spin_lock_irqsave(&dev->lock, flags); + + while (!list_empty(&dev->pending_data)) + { + smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; + list_del(&cb->entry); + + smscore_putbuffer(dev->coredev, cb); + + dev->pending_count --; + } + + if (dev->currentcb) + { + smscore_putbuffer(dev->coredev, dev->currentcb); + dev->currentcb = NULL; + dev->pending_count --; + } + + smscore_unregister_client(dev->smsclient); + dev->smsclient = NULL; + + spin_unlock_irqrestore(&dev->lock, flags); + } +} + +/** + * queues incoming buffers into buffers queue + * + * @param context pointer to the client context (smschar parameters block) + * @param cb pointer to incoming buffer descriptor + * + * @return 0 on success, <0 on queue overflow. + */ +int smschar_onresponse(void *context, smscore_buffer_t *cb) +{ + smschar_device_t *dev = context; + unsigned long flags; + + spin_lock_irqsave(&dev->lock, flags); + + if (dev->pending_count > SMS_CHR_MAX_Q_LEN) + { + spin_unlock_irqrestore(&dev->lock, flags); + return -EBUSY; + } + + dev->pending_count ++; + + // if data channel, remove header + if (dev->device_index) + { + cb->size -= sizeof(SmsMsgHdr_ST); + cb->offset += sizeof(SmsMsgHdr_ST); + } + + list_add_tail(&cb->entry, &dev->pending_data); + spin_unlock_irqrestore(&dev->lock, flags); + + if (waitqueue_active(&dev->waitq)) + wake_up_interruptible(&dev->waitq); + + return 0; +} + +/** + * handles device removal event + * + * @param context pointer to the client context (smschar parameters block) + * + */ +void smschar_onremove(void *context) +{ + smschar_device_t *dev = (smschar_device_t *) context; + + smschar_unregister_client(dev); + dev->coredev = NULL; +} + +/** + * registers client associated with the node + * + * @param inode Inode concerned. + * @param file File concerned. + * + * @return 0 on success, <0 on error. + */ +int smschar_open (struct inode *inode, struct file *file) +{ + smschar_device_t *dev = container_of(inode->i_cdev, smschar_device_t, cdev); + int rc = -ENODEV; + + PDEBUG("entering index %d\n", dev->device_index); + + if (dev->coredev) + { + smsclient_params_t params; + + params.initial_id = dev->device_index ? dev->device_index : SMS_HOST_LIB; + params.data_type = dev->device_index ? MSG_SMS_DAB_CHANNEL : 0; + params.onresponse_handler = smschar_onresponse; + params.onremove_handler = smschar_onremove; + params.context = dev; + + rc = smscore_register_client(dev->coredev, ¶ms, &dev->smsclient); + if (!rc) + { + file->private_data = dev; + } + } + + PDEBUG("exiting, rc %d\n", rc); + + return rc; +} + +/** + * unregisters client associated with the node + * + * @param inode Inode concerned. + * @param file File concerned. + * + */ +int smschar_release(struct inode *inode, struct file *file) +{ + smschar_unregister_client(file->private_data); + + PDEBUG("exiting\n"); + + return 0; +} + +/** + * copies data from buffers in incoming queue into a user buffer + * + * @param file File structure. + * @param buf Source buffer. + * @param count Size of source buffer. + * @param f_pos Position in file (ignored). + * + * @return Number of bytes read, or <0 on error. + */ +ssize_t smschar_read ( struct file * file, char __user * buf, size_t count, loff_t * f_pos ) +{ + smschar_device_t *dev = file->private_data; + unsigned long flags; + int copied = 0; + + if (!dev->coredev || !dev->smsclient) + { + PERROR("no client\n"); + return -ENODEV; + } + + while (copied != count) + { + if (0 > wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data))) + { + PERROR("wait_event_interruptible error\n"); + return -ENODEV; + } + + if (!dev->smsclient) + { + PERROR("no client\n"); + return -ENODEV; + } + + spin_lock_irqsave(&dev->lock, flags); + + while (!list_empty(&dev->pending_data) && (copied != count)) + { + smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; + int actual_size = min(((int) count - copied), cb->size); + + copy_to_user(&buf[copied], &((char*)cb->p)[cb->offset], actual_size); + + copied += actual_size; + cb->offset += actual_size; + cb->size -= actual_size; + + if (!cb->size) + { + list_del(&cb->entry); + smscore_putbuffer(dev->coredev, cb); + + dev->pending_count --; + } + } + + spin_unlock_irqrestore(&dev->lock, flags); + } + + return copied; +} + +/** + * sends the buffer to the associated device + * + * @param file File structure. + * @param buf Source buffer. + * @param count Size of source buffer. + * @param f_pos Position in file (ignored). + * + * @return Number of bytes read, or <0 on error. + */ +ssize_t smschar_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos) +{ + smschar_device_t *dev = file->private_data; + void *buffer; + + if (!dev->smsclient) + { + PERROR("no client\n"); + return -ENODEV; + } + + buffer = kmalloc(ALIGN(count, SMS_ALLOC_ALIGNMENT) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (buffer) + { + void *msg_buffer = (void*) SMS_ALIGN_ADDRESS(buffer); + + if (!copy_from_user(msg_buffer, buf, count)) + smsclient_sendrequest(dev->smsclient, msg_buffer, count); + else + count = 0; + + kfree(buffer); + } + + return count; +} + +int smschar_mmap(struct file *file, struct vm_area_struct *vma) +{ + smschar_device_t *dev = file->private_data; + return smscore_map_common_buffer(dev->coredev, vma); +} + +/** + * waits until buffer inserted into a queue. when inserted buffer offset are reported + * to the calling process. previously reported buffer is returned to smscore pool + * + * @param dev pointer to smschar parameters block + * @param touser pointer to a structure that receives incoming buffer offsets + * + * @return 0 on success, <0 on error. + */ +int smschar_wait_get_buffer(smschar_device_t* dev, smschar_buffer_t* touser) +{ + unsigned long flags; + int rc; + + spin_lock_irqsave(&dev->lock, flags); + + if (dev->currentcb) + { + smscore_putbuffer(dev->coredev, dev->currentcb); + dev->currentcb = NULL; + dev->pending_count --; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + rc = wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data)); + if (rc < 0) + { + PERROR("wait_event_interruptible error\n"); + return rc; + } + + if (!dev->smsclient) + { + PERROR("no client\n"); + return -ENODEV; + } + + spin_lock_irqsave(&dev->lock, flags); + + if (!list_empty(&dev->pending_data)) + { + smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; + + touser->offset = cb->offset_in_common + cb->offset; + touser->size = cb->size; + + list_del(&cb->entry); + + dev->currentcb = cb; + } + else + { + touser->offset = 0; + touser->size = 0; + } + + spin_unlock_irqrestore(&dev->lock, flags); + + return 0; +} + +int smschar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + smschar_device_t *dev = file->private_data; + void __user *up = (void __user *) arg; + + if (!dev->coredev || !dev->smsclient) + { + PERROR("no client\n"); + return -ENODEV; + } + + switch(cmd) + { + case SMSCHAR_SET_DEVICE_MODE: + return smscore_set_device_mode(dev->coredev, (int) arg); + + case SMSCHAR_GET_DEVICE_MODE: + { + if (put_user(smscore_get_device_mode(dev->coredev), (int*) up)) + return -EFAULT; + + break; + } + + case SMSCHAR_GET_BUFFER_SIZE: + { + if (put_user(smscore_get_common_buffer_size(dev->coredev), (int*) up)) + return -EFAULT; + + break; + } + + case SMSCHAR_WAIT_GET_BUFFER: + { + smschar_buffer_t touser; + int rc; + + rc = smschar_wait_get_buffer(dev, &touser); + if (rc < 0) + return rc; + + if (copy_to_user(up, &touser, sizeof(smschar_buffer_t))) + return -EFAULT; + + break; + } + + default: + return -ENOIOCTLCMD; + } + + return 0; +} + +struct file_operations smschar_fops = +{ + .owner = THIS_MODULE, + .read = smschar_read, + .write = smschar_write, + .open = smschar_open, + .release = smschar_release, + .mmap = smschar_mmap, + .ioctl = smschar_ioctl, +}; + +static int smschar_setup_cdev ( smschar_device_t *dev, int index ) +{ + int rc, devno = MKDEV ( smschar_major, smschar_minor + index ); + + cdev_init ( &dev->cdev, &smschar_fops ); + + dev->cdev.owner = THIS_MODULE; + dev->cdev.ops = &smschar_fops; + + kobject_set_name(&dev->cdev.kobj, "Siano_sms%d", index); + + rc = cdev_add ( &dev->cdev, devno, 1 ); + + PDEBUG("exiting %p %d, rc %d\n", dev, index, rc); + + return rc; +} + +/** + * smschar callback that called when device plugged in/out. the function + * register or unregisters char device interface according to plug in/out + * + * @param coredev pointer to device that is being plugged in/out + * @param device pointer to system device object + * @param arrival 1 on plug-on, 0 othewise + * + * @return 0 on success, <0 on error. + */ +int smschar_hotplug(smscore_device_t* coredev, struct device* device, int arrival) +{ + int rc = 0, i; + + PDEBUG("entering %d\n", arrival); + + if (arrival) + { + // currently only 1 instance supported + if (!g_smschar_inuse) + { + /* data notification callbacks assignment */ + memset ( smschar_devices, 0, SMSCHAR_NR_DEVS * sizeof ( smschar_device_t ) ); + + /* Initialize each device. */ + for (i = 0; i < SMSCHAR_NR_DEVS; i++) + { + smschar_setup_cdev ( &smschar_devices[i], i ); + + INIT_LIST_HEAD(&smschar_devices[i].pending_data); + spin_lock_init(&smschar_devices[i].lock); + init_waitqueue_head(&smschar_devices[i].waitq); + + smschar_devices[i].coredev = coredev; + smschar_devices[i].device_index = i; + } + + g_smschar_inuse = 1; + } + } + else + { + // currently only 1 instance supported + if (g_smschar_inuse) + { + /* Get rid of our char dev entries */ + for(i = 0; i < SMSCHAR_NR_DEVS; i++) + cdev_del(&smschar_devices[i].cdev); + + g_smschar_inuse = 0; + } + } + + PDEBUG("exiting, rc %d\n", rc); + + return rc; /* succeed */ +} + +int smschar_initialize(void) +{ + dev_t devno = MKDEV ( smschar_major, smschar_minor ); + int rc; + + if(smschar_major) + { + rc = register_chrdev_region ( devno, SMSCHAR_NR_DEVS, "smschar" ); + } + else + { + rc = alloc_chrdev_region ( &devno, smschar_minor, SMSCHAR_NR_DEVS, "smschar" ); + smschar_major = MAJOR ( devno ); + } + + if (rc < 0) + { + PWARNING ( "smschar: can't get major %d\n", smschar_major ); + return rc; + } + + return smscore_register_hotplug(smschar_hotplug); +} + +void smschar_terminate(void) +{ + dev_t devno = MKDEV ( smschar_major, smschar_minor ); + + unregister_chrdev_region(devno, SMSCHAR_NR_DEVS); + smscore_unregister_hotplug(smschar_hotplug); +} diff --git a/drivers/media/mdtv/smschar.h b/drivers/media/mdtv/smschar.h new file mode 100644 index 000000000000..1cd2f32a7f71 --- /dev/null +++ b/drivers/media/mdtv/smschar.h @@ -0,0 +1,7 @@ +#ifndef __smschar_h__ +#define __smschar_h__ + +extern int smschar_initialize(void); +extern void smschar_terminate(void); + +#endif // __smschar_h__ diff --git a/drivers/media/mdtv/smscharioctl.h b/drivers/media/mdtv/smscharioctl.h new file mode 100644 index 000000000000..e57b89efc499 --- /dev/null +++ b/drivers/media/mdtv/smscharioctl.h @@ -0,0 +1,17 @@ +#ifndef __smscharioctl_h__ +#define __smscharioctl_h__ + +#include + +typedef struct _smschar_buffer_t +{ + unsigned long offset; // offset in common buffer (mapped to user space) + int size; +} smschar_buffer_t; + +#define SMSCHAR_SET_DEVICE_MODE _IOW('K', 0, int) +#define SMSCHAR_GET_DEVICE_MODE _IOR('K', 1, int) +#define SMSCHAR_GET_BUFFER_SIZE _IOR('K', 2, int) +#define SMSCHAR_WAIT_GET_BUFFER _IOR('K', 3, smschar_buffer_t) + +#endif // __smscharioctl_h__ diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c new file mode 100644 index 000000000000..a354912391a0 --- /dev/null +++ b/drivers/media/mdtv/smscoreapi.c @@ -0,0 +1,1170 @@ +/*! + + \file smscoreapi.c + + \brief Siano core API module + This file contains implementation for the interface to sms core component + + \par Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + + \par This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3 as + published by the Free Software Foundation; + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. + + \author Anatoly Greenblat + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "smskdefs.h" // device, page, scatterlist, kmutex + +#include + +#include "smscoreapi.h" +#include "smstypes.h" + +#include "smschar.h" + +typedef struct _smscore_device_notifyee +{ + struct list_head entry; + hotplug_t hotplug; +} smscore_device_notifyee_t; + +typedef struct _smscore_client +{ + struct list_head entry; + smscore_device_t *coredev; + + void *context; + + int data_type; + + onresponse_t onresponse_handler; + onremove_t onremove_handler; +} *psmscore_client_t; + +typedef struct _smscore_subclient +{ + struct list_head entry; + smscore_client_t *client; + + int id; +} smscore_subclient_t; + +typedef struct _smscore_device +{ + struct list_head entry; + + struct list_head clients; + struct list_head subclients; + spinlock_t clientslock; + + struct list_head buffers; + spinlock_t bufferslock; + int num_buffers; + + void *common_buffer; + int common_buffer_size; + dma_addr_t common_buffer_phys; + + void *context; + struct device *device; + + char devpath[32]; + unsigned long device_flags; + + setmode_t setmode_handler; + detectmode_t detectmode_handler; + sendrequest_t sendrequest_handler; + preload_t preload_handler; + postload_t postload_handler; + + int mode, modes_supported; + + struct completion version_ex_done, data_download_done, trigger_done; + struct completion init_device_done, reload_start_done, resume_done; +} *psmscore_device_t; + +typedef struct _smscore_registry_entry +{ + struct list_head entry; + char devpath[32]; + int mode; +} smscore_registry_entry_t; + +struct list_head g_smscore_notifyees; +struct list_head g_smscore_devices; +kmutex_t g_smscore_deviceslock; + +struct list_head g_smscore_registry; +kmutex_t g_smscore_registrylock; + +static int default_mode = 1; +module_param(default_mode, int, 0644); +MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); + +int smscore_registry_getmode(char* devpath) +{ + smscore_registry_entry_t *entry; + struct list_head *next; + + kmutex_lock(&g_smscore_registrylock); + + for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) + { + entry = (smscore_registry_entry_t *) next; + + if (!strcmp(entry->devpath, devpath)) + { + kmutex_unlock(&g_smscore_registrylock); + return entry->mode; + } + } + + entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); + if (entry) + { + entry->mode = default_mode; + strcpy(entry->devpath, devpath); + + list_add(&entry->entry, &g_smscore_registry); + } + + kmutex_unlock(&g_smscore_registrylock); + + return default_mode; +} + +void smscore_registry_setmode(char* devpath, int mode) +{ + smscore_registry_entry_t *entry; + struct list_head *next; + + kmutex_lock(&g_smscore_registrylock); + + for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) + { + entry = (smscore_registry_entry_t *) next; + + if (!strcmp(entry->devpath, devpath)) + { + entry->mode = mode; + break; + } + } + + kmutex_unlock(&g_smscore_registrylock); +} + + +void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock) +{ + unsigned long flags; + + spin_lock_irqsave(lock, flags); + + list_add(new, head); + + spin_unlock_irqrestore(lock, flags); +} + +/** + * register a client callback that called when device plugged in/unplugged + * NOTE: if devices exist callback is called immediately for each device + * + * @param hotplug callback + * + * @return 0 on success, <0 on error. + */ +int smscore_register_hotplug(hotplug_t hotplug) +{ + smscore_device_notifyee_t *notifyee; + struct list_head *next, *first; + int rc = 0; + + kmutex_lock(&g_smscore_deviceslock); + + notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); + if (notifyee) + { + // now notify callback about existing devices + first = &g_smscore_devices; + for (next = first->next; next != first && !rc; next = next->next) + { + smscore_device_t *coredev = (smscore_device_t *) next; + rc = hotplug(coredev, coredev->device, 1); + } + + if (rc >= 0) + { + notifyee->hotplug = hotplug; + list_add(¬ifyee->entry, &g_smscore_notifyees); + } + else + kfree(notifyee); + } + else + rc = -ENOMEM; + + kmutex_unlock(&g_smscore_deviceslock); + + return rc; +} + +/** + * unregister a client callback that called when device plugged in/unplugged + * + * @param hotplug callback + * + */ +void smscore_unregister_hotplug(hotplug_t hotplug) +{ + struct list_head *next, *first; + + kmutex_lock(&g_smscore_deviceslock); + + first = &g_smscore_notifyees; + + for (next = first->next; next != first;) + { + smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next; + next = next->next; + + if (notifyee->hotplug == hotplug) + { + list_del(¬ifyee->entry); + kfree(notifyee); + } + } + + kmutex_unlock(&g_smscore_deviceslock); +} + +void smscore_notify_clients(smscore_device_t *coredev) +{ + smscore_client_t* client; + + // the client must call smscore_unregister_client from remove handler + while (!list_empty(&coredev->clients)) + { + client = (smscore_client_t *) coredev->clients.next; + client->onremove_handler(client->context); + } +} + +int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival) +{ + struct list_head *next, *first; + int rc = 0; + + // note: must be called under g_deviceslock + + first = &g_smscore_notifyees; + + for (next = first->next; next != first; next = next->next) + { + rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); + if (rc < 0) + break; + } + + return rc; +} + +smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys) +{ + smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); + if (!cb) + { + printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__); + return NULL; + } + + cb->p = buffer; + cb->offset_in_common = buffer - (u8*) common_buffer; + cb->phys = common_buffer_phys + cb->offset_in_common; + + return cb; +} + +/** + * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies + * registered hotplugs about new device. + * + * @param params device pointer to struct with device specific parameters and handlers + * @param coredev pointer to a value that receives created coredev object + * + * @return 0 on success, <0 on error. + */ +int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) +{ + smscore_device_t* dev; + u8 *buffer; + + dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); + if (!dev) + { + printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__); + return -ENOMEM; + } + + // init list entry so it could be safe in smscore_unregister_device + INIT_LIST_HEAD(&dev->entry); + + // init queues + INIT_LIST_HEAD(&dev->clients); + INIT_LIST_HEAD(&dev->subclients); + INIT_LIST_HEAD(&dev->buffers); + + // init locks + spin_lock_init(&dev->clientslock); + spin_lock_init(&dev->bufferslock); + + // init completion events + init_completion(&dev->version_ex_done); + init_completion(&dev->data_download_done); + init_completion(&dev->trigger_done); + init_completion(&dev->init_device_done); + init_completion(&dev->reload_start_done); + init_completion(&dev->resume_done); + + // alloc common buffer + dev->common_buffer_size = params->buffer_size * params->num_buffers; + dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA); + if (!dev->common_buffer) + { + smscore_unregister_device(dev); + return -ENOMEM; + } + + // prepare dma buffers + for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers ++, buffer += params->buffer_size) + { + smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); + if (!cb) + { + smscore_unregister_device(dev); + return -ENOMEM; + } + + smscore_putbuffer(dev, cb); + } + + printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers); + + dev->mode = DEVICE_MODE_NONE; + dev->context = params->context; + dev->device = params->device; + dev->setmode_handler = params->setmode_handler; + dev->detectmode_handler = params->detectmode_handler; + dev->sendrequest_handler = params->sendrequest_handler; + dev->preload_handler = params->preload_handler; + dev->postload_handler = params->postload_handler; + + dev->device_flags = params->flags; + strcpy(dev->devpath, params->devpath); + + // add device to devices list + kmutex_lock(&g_smscore_deviceslock); + list_add(&dev->entry, &g_smscore_devices); + kmutex_unlock(&g_smscore_deviceslock); + + *coredev = dev; + + printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + + return 0; +} + +/** + * sets initial device mode and notifies client hotplugs that device is ready + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return 0 on success, <0 on error. + */ +int smscore_start_device(smscore_device_t *coredev) +{ + int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); + if (rc < 0) + return rc; + + kmutex_lock(&g_smscore_deviceslock); + + rc = smscore_notify_callbacks(coredev, coredev->device, 1); + + printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc); + + kmutex_unlock(&g_smscore_deviceslock); + + return rc; +} + +int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion) +{ + int rc = coredev->sendrequest_handler(coredev->context, buffer, size); + if (rc < 0) + return rc; + + return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME; +} + +int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) +{ + SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; + SmsMsgHdr_ST *msg; + UINT32 mem_address = firmware->StartAddress; + u8* payload = firmware->Payload; + int rc = 0; + + if (coredev->preload_handler) + { + rc = coredev->preload_handler(coredev->context); + if (rc < 0) + return rc; + } + + // PAGE_SIZE buffer shall be enough and dma aligned + msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); + if (!msg) + return -ENOMEM; + + if (coredev->mode != DEVICE_MODE_NONE) + { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); + mem_address = *(UINT32*) &payload[20]; + } + + while (size && rc >= 0) + { + SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; + int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); + + SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + payload_size)); + + DataMsg->MemAddr = mem_address; + memcpy(DataMsg->Payload, payload, payload_size); + + if (coredev->device_flags & SMS_ROM_NO_RESPONSE && coredev->mode == DEVICE_MODE_NONE) + rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); + else + rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); + + payload += payload_size; + size -= payload_size; + mem_address += payload_size; + } + + if (rc >= 0) + { + if (coredev->mode == DEVICE_MODE_NONE) + { + SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg; + + SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5); + + TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point + TriggerMsg->msgData[1] = 5; // Priority + TriggerMsg->msgData[2] = 0x200; // Stack size + TriggerMsg->msgData[3] = 0; // Parameter + TriggerMsg->msgData[4] = 4; // Task ID + + if (coredev->device_flags & SMS_ROM_NO_RESPONSE) + { + rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); + msleep(100); + } + else + rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); + } + else + { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); + + rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); + } + } + + printk("%s %d \n", __func__, rc); + + kfree(msg); + + return (rc >= 0 && coredev->postload_handler) ? + coredev->postload_handler(coredev->context) : + rc; +} + +/** + * loads specified firmware into a buffer and calls device loadfirmware_handler + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param filename null-terminated string specifies firmware file name + * @param loadfirmware_handler device handler that loads firmware + * + * @return 0 on success, <0 on error. + */ +int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler) +{ + int rc = -ENOENT; + + const struct firmware *fw; + u8* fw_buffer; + + if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) + return -EINVAL; + + rc = request_firmware(&fw, filename, coredev->device); + if (rc < 0) + { + printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename); + return rc; + } + + fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); + if (fw_buffer) + { + memcpy(fw_buffer, fw->data, fw->size); + + rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? + smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : + loadfirmware_handler(coredev->context, fw_buffer, fw->size); + + kfree(fw_buffer); + } + else + { + printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__); + rc = -ENOMEM; + } + + release_firmware(fw); + + return rc; +} + +/** + * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return 0 on success, <0 on error. + */ +void smscore_unregister_device(smscore_device_t *coredev) +{ + smscore_buffer_t *cb; + int num_buffers = 0; + + kmutex_lock(&g_smscore_deviceslock); + + smscore_notify_clients(coredev); + smscore_notify_callbacks(coredev, NULL, 0); + + // at this point all buffers should be back + // onresponse must no longer be called + + while (1) + { + while ((cb = smscore_getbuffer(coredev))) + { + kfree(cb); + num_buffers ++; + } + + if (num_buffers == coredev->num_buffers) + break; + + printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers); + msleep(100); + } + + printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers); + + if (coredev->common_buffer) + dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); + + list_del(&coredev->entry); + kfree(coredev); + + kmutex_unlock(&g_smscore_deviceslock); + + printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev); +} + +int smscore_detect_mode(smscore_device_t *coredev) +{ + void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); + int rc; + + if (!buffer) + return -ENOMEM; + + SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); + + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + if (rc == -ETIME) + { + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__); + + if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) + { + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + if (rc < 0) + { + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc); + } + } + else + rc = -ETIME; + } + + kfree(buffer); + + return rc; +} + +char *smscore_fw_lkup[] = +{ + "dvb_nova_12mhz.inp", + "dvb_nova_12mhz.inp", + "tdmb_nova.inp", + "none", + "dvb_nova_12mhz.inp", + "isdbt_nova_12mhz.inp", + "isdbt_nova_12mhz.inp", + "cmmb_nova_12mhz.inp", + "none", +}; + +/** + * calls device handler to change mode of operation + * NOTE: stellar/usb may disconnect when changing mode + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param mode requested mode of operation + * + * @return 0 on success, <0 on error. + */ +int smscore_set_device_mode(smscore_device_t *coredev, int mode) +{ + void *buffer; + int rc = 0; + + if (coredev->device_flags & SMS_DEVICE_FAMILY2) + { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) + { + printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode); + return -EINVAL; + } + + if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) + { + rc = smscore_detect_mode(coredev); + if (rc < 0) + return rc; + } + + if (coredev->mode == mode) + { + printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode); + return 0; + } + + if (!(coredev->modes_supported & (1 << mode))) + { + rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL); + if (rc < 0) + return rc; + } + else + { + printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode); + } + + buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (buffer) + { + SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); + + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); + msg->msgData[0] = mode; + + rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); + + kfree(buffer); + } + else + rc = -ENOMEM; + } + else + { + if (coredev->detectmode_handler) + coredev->detectmode_handler(coredev->context, &coredev->mode); + + if (coredev->mode != mode && coredev->setmode_handler) + rc = coredev->setmode_handler(coredev->context, mode); + } + + smscore_registry_setmode(coredev->devpath, mode); + + if (rc >= 0) + { + coredev->mode = mode; + coredev->device_flags &= ~SMS_DEVICE_NOT_READY; + } + + return rc; +} + +/** + * calls device handler to get current mode of operation + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return current mode + */ +int smscore_get_device_mode(smscore_device_t *coredev) +{ + return coredev->mode; +} + +smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type) +{ + smscore_client_t *client = NULL; + struct list_head *next, *first; + unsigned long flags; + + if (!data_type) + return NULL; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->clients; + + for (next = first->next; next != first; next = next->next) + { + if (((smscore_client_t*) next)->data_type == data_type) + { + client = (smscore_client_t*) next; + break; + } + } + + spin_unlock_irqrestore(&coredev->clientslock, flags); + + return client; +} + +smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) +{ + smscore_client_t *client = NULL; + struct list_head *next, *first; + unsigned long flags; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->subclients; + + for (next = first->next; next != first; next = next->next) + { + if (((smscore_subclient_t*) next)->id == id) + { + client = ((smscore_subclient_t*) next)->client; + break; + } + } + + spin_unlock_irqrestore(&coredev->clientslock, flags); + + return client; +} + +/** + * find client by response id/type, call clients onresponse handler + * return buffer to pool on error + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param cb pointer to response buffer descriptor + * + */ +void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) +{ + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); + smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType); + int rc = -EBUSY; + + static unsigned long last_sample_time = 0; + static int data_total = 0; + unsigned long time_now = jiffies_to_msecs(jiffies); + + if (!last_sample_time) + last_sample_time = time_now; + + if (time_now - last_sample_time > 10000) + { + printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); + + last_sample_time = time_now; + data_total = 0; + } + + data_total += cb->size; + + if (!client) + client = smscore_getclient_by_id(coredev, phdr->msgDstId); + + if (client) + rc = client->onresponse_handler(client->context, cb); + + if (rc < 0) + { + switch (phdr->msgType) + { + case MSG_SMS_GET_VERSION_EX_RES: + { + SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; + printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); + + coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; + coredev->modes_supported = ver->SupportedProtocols; + + complete(&coredev->version_ex_done); + break; + } + + case MSG_SMS_INIT_DEVICE_RES: + printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__); + complete(&coredev->init_device_done); + break; + + case MSG_SW_RELOAD_START_RES: + printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__); + complete(&coredev->reload_start_done); + break; + + case MSG_SMS_DATA_DOWNLOAD_RES: + complete(&coredev->data_download_done); + break; + + case MSG_SW_RELOAD_EXEC_RES: + printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__); + break; + + case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: + printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__); + complete(&coredev->trigger_done); + break; + + case MSG_SMS_SLEEP_RESUME_COMP_IND: + complete(&coredev->resume_done); + break; + + default: + printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId); + } + + smscore_putbuffer(coredev, cb); + } +} + +/** + * return pointer to next free buffer descriptor from core pool + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return pointer to descriptor on success, NULL on error. + */ +smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) +{ + smscore_buffer_t *cb = NULL; + unsigned long flags; + + spin_lock_irqsave(&coredev->bufferslock, flags); + + if (!list_empty(&coredev->buffers)) + { + cb = (smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); + } + + spin_unlock_irqrestore(&coredev->bufferslock, flags); + + return cb; +} + +/** + * return buffer descriptor to a pool + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param cb pointer buffer descriptor + * + */ +void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) +{ + list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); +} + +int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id) +{ + smscore_client_t *existing_client; + smscore_subclient_t *subclient; + + if (!id) + return 0; + + existing_client = smscore_getclient_by_id(coredev, id); + if (existing_client == client) + return 0; + + if (existing_client) + return -EBUSY; + + subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL); + if (!subclient) + return -ENOMEM; + + subclient->client = client; + subclient->id = id; + + list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock); + + return 0; +} + +/** + * creates smsclient object, check that id is taken by another client + * + * @param coredev pointer to a coredev object from clients hotplug + * @param initial_id all messages with this id would be sent to this client + * @param data_type all messages of this type would be sent to this client + * @param onresponse_handler client handler that is called to process incoming messages + * @param onremove_handler client handler that is called when device is removed + * @param context client-specific context + * @param client pointer to a value that receives created smsclient object + * + * @return 0 on success, <0 on error. + */ +int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) +{ + smscore_client_t* newclient; + int rc; + + // check that no other channel with same data type exists + if (params->data_type && smscore_getclient_by_type(coredev, params->data_type)) + return -EEXIST; + + newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); + if (!newclient) + return -ENOMEM; + + // check that no other channel with same id exists + rc = smscore_validate_client(coredev, newclient, params->initial_id); + if (rc < 0) + { + kfree(newclient); + return rc; + } + + newclient->coredev = coredev; + newclient->data_type = params->data_type; + newclient->onresponse_handler = params->onresponse_handler; + newclient->onremove_handler = params->onremove_handler; + newclient->context = params->context; + + list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); + + *client = newclient; + + printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id); + + return 0; +} + +/** + * frees smsclient object and all subclients associated with it + * + * @param client pointer to smsclient object returned by smscore_register_client + * + */ +void smscore_unregister_client(smscore_client_t *client) +{ + smscore_device_t *coredev = client->coredev; + struct list_head *next, *first; + unsigned long flags; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->subclients; + + for (next = first->next; next != first;) + { + smscore_subclient_t *subclient = (smscore_subclient_t *) next; + next = next->next; + + if (subclient->client == client) + { + list_del(&subclient->entry); + kfree(subclient); + } + } + + printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type); + + list_del(&client->entry); + kfree(client); + + spin_unlock_irqrestore(&coredev->clientslock, flags); +} + +/** + * verifies that source id is not taken by another client, + * calls device handler to send requests to the device + * + * @param client pointer to smsclient object returned by smscore_register_client + * @param buffer pointer to a request buffer + * @param size size (in bytes) of request buffer + * + * @return 0 on success, <0 on error. + */ +int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) +{ + smscore_device_t* coredev = client->coredev; + SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; + + // check that no other channel with same id exists + int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId); + if (rc < 0) + return rc; + + return coredev->sendrequest_handler(coredev->context, buffer, size); +} + +/** + * return the size of large (common) buffer + * + * @param coredev pointer to a coredev object from clients hotplug + * + * @return size (in bytes) of the buffer + */ +int smscore_get_common_buffer_size(smscore_device_t *coredev) +{ + return coredev->common_buffer_size; +} + +/** + * maps common buffer (if supported by platform) + * + * @param coredev pointer to a coredev object from clients hotplug + * @param vma pointer to vma struct from mmap handler + * + * @return 0 on success, <0 on error. + */ +int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma) +{ + unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); + + if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) + { + printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__); + return -EINVAL; + } + + if ((end - start) != size) + { + printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (int)(end - start), (int) size); + return -EINVAL; + } + + if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) + { + printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__); + return -EAGAIN; + } + + return 0; +} + +int smscore_module_init(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smscore_notifyees); + INIT_LIST_HEAD(&g_smscore_devices); + kmutex_init(&g_smscore_deviceslock); + + INIT_LIST_HEAD(&g_smscore_registry); + kmutex_init(&g_smscore_registrylock); + + rc = smschar_initialize(); + + printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); + + return rc; +} + +void smscore_module_exit(void) +{ + smschar_terminate(); + + kmutex_lock(&g_smscore_deviceslock); + while (!list_empty(&g_smscore_notifyees)) + { + smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next; + + list_del(¬ifyee->entry); + kfree(notifyee); + } + kmutex_unlock(&g_smscore_deviceslock); + + kmutex_lock(&g_smscore_registrylock); + while (!list_empty(&g_smscore_registry)) + { + smscore_registry_entry_t *entry = (smscore_registry_entry_t *) g_smscore_registry.next; + + list_del(&entry->entry); + kfree(entry); + } + kmutex_unlock(&g_smscore_registrylock); + + printk(KERN_INFO "%s\n", __FUNCTION__); +} + +module_init(smscore_module_init); +module_exit(smscore_module_exit); + +MODULE_DESCRIPTION("smscore"); +MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(smscore_registry_setmode); +EXPORT_SYMBOL(smscore_registry_getmode); +EXPORT_SYMBOL(smscore_register_hotplug); +EXPORT_SYMBOL(smscore_unregister_hotplug); +EXPORT_SYMBOL(smscore_register_device); +EXPORT_SYMBOL(smscore_unregister_device); +EXPORT_SYMBOL(smscore_start_device); +EXPORT_SYMBOL(smscore_load_firmware); +EXPORT_SYMBOL(smscore_set_device_mode); +EXPORT_SYMBOL(smscore_get_device_mode); +EXPORT_SYMBOL(smscore_register_client); +EXPORT_SYMBOL(smscore_unregister_client); +EXPORT_SYMBOL(smsclient_sendrequest); +EXPORT_SYMBOL(smscore_onresponse); +EXPORT_SYMBOL(smscore_get_common_buffer_size); +EXPORT_SYMBOL(smscore_map_common_buffer); +EXPORT_SYMBOL(smscore_getbuffer); +EXPORT_SYMBOL(smscore_putbuffer); diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h new file mode 100644 index 000000000000..a8c025f74eb7 --- /dev/null +++ b/drivers/media/mdtv/smscoreapi.h @@ -0,0 +1,101 @@ +#ifndef __smscoreapi_h__ +#define __smscoreapi_h__ + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#define SMS_ALLOC_ALIGNMENT 128 +#define SMS_DMA_ALIGNMENT 16 +#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) + +#define SMS_DEVICE_FAMILY2 1 +#define SMS_ROM_NO_RESPONSE 2 +#define SMS_DEVICE_NOT_READY 0x8000000 + +typedef struct _smscore_device smscore_device_t; +typedef struct _smscore_client smscore_client_t; +typedef struct _smscore_buffer smscore_buffer_t; + +typedef int (*hotplug_t)(smscore_device_t *coredev, struct device *device, int arrival); + +typedef int (*setmode_t)(void *context, int mode); +typedef void (*detectmode_t)(void *context, int *mode); +typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); +typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); +typedef int (*preload_t)(void *context); +typedef int (*postload_t)(void *context); + +typedef int (*onresponse_t)(void *context, smscore_buffer_t *cb); +typedef void (*onremove_t)(void *context); + +typedef struct _smscore_buffer +{ + // public members, once passed to clients can be changed freely + struct list_head entry; + int size; + int offset; + + // private members, read-only for clients + void *p; + dma_addr_t phys; + unsigned long offset_in_common; +} *psmscore_buffer_t; + +typedef struct _smsdevice_params +{ + struct device *device; + + int buffer_size; + int num_buffers; + + char devpath[32]; + unsigned long flags; + + setmode_t setmode_handler; + detectmode_t detectmode_handler; + sendrequest_t sendrequest_handler; + preload_t preload_handler; + postload_t postload_handler; + + void *context; +} smsdevice_params_t; + +typedef struct _smsclient_params +{ + int initial_id; + int data_type; + onresponse_t onresponse_handler; + onremove_t onremove_handler; + + void *context; +} smsclient_params_t; + +extern void smscore_registry_setmode(char *devpath, int mode); +extern int smscore_registry_getmode(char *devpath); + +extern int smscore_register_hotplug(hotplug_t hotplug); +extern void smscore_unregister_hotplug(hotplug_t hotplug); + +extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev); +extern void smscore_unregister_device(smscore_device_t *coredev); + +extern int smscore_start_device(smscore_device_t *coredev); +extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler); + +extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); +extern int smscore_get_device_mode(smscore_device_t *coredev); + +extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client); +extern void smscore_unregister_client(smscore_client_t *client); + +extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size); +extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb); + +extern int smscore_get_common_buffer_size(smscore_device_t *coredev); +extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma); + +extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); +extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); + +#endif // __smscoreapi_h__ diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c new file mode 100644 index 000000000000..f2ed1718d180 --- /dev/null +++ b/drivers/media/mdtv/smsdvb.c @@ -0,0 +1,438 @@ +#include +#include + +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + +#include "smskdefs.h" // page, scatterlist, kmutex +#include "smscoreapi.h" +#include "smstypes.h" + +typedef struct _smsdvb_client +{ + struct list_head entry; + + smscore_device_t *coredev; + smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_signal_strength; + + struct completion tune_done, stat_done; + + // todo: save freq/band instead whole struct + struct dvb_frontend_parameters fe_params; + +} smsdvb_client_t; + +struct list_head g_smsdvb_clients; +kmutex_t g_smsdvb_clientslock; + +int smsdvb_onresponse(void *context, smscore_buffer_t *cb) +{ + smsdvb_client_t *client = (smsdvb_client_t *) context; + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset); + + switch(phdr->msgType) + { + case MSG_SMS_DVBT_BDA_DATA: + dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST)); + break; + + case MSG_SMS_RF_TUNE_RES: + complete(&client->tune_done); + break; + + case MSG_SMS_GET_STATISTICS_RES: + { + SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1); + + if (p->Stat.IsDemodLocked) + { + client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + client->fe_snr = p->Stat.SNR; + client->fe_ber = p->Stat.BER; + + if (p->Stat.InBandPwr < -95) + client->fe_signal_strength = 0; + else if (p->Stat.InBandPwr > -29) + client->fe_signal_strength = 100; + else + client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2; + } + else + { + client->fe_status = 0; + client->fe_snr = + client->fe_ber = + client->fe_signal_strength = 0; + } + + complete(&client->stat_done); + break; + } + } + + smscore_putbuffer(client->coredev, cb); + + return 0; +} + +void smsdvb_unregister_client(smsdvb_client_t* client) +{ + // must be called under clientslock + + list_del(&client->entry); + + smscore_unregister_client(client->smsclient); + dvb_unregister_frontend(&client->frontend); + dvb_dmxdev_release(&client->dmxdev); + dvb_dmx_release(&client->demux); + dvb_unregister_adapter(&client->adapter); + kfree(client); +} + +void smsdvb_onremove(void *context) +{ + kmutex_lock(&g_smsdvb_clientslock); + + smsdvb_unregister_client((smsdvb_client_t*) context); + + kmutex_unlock(&g_smsdvb_clientslock); +} + +static int smsdvb_start_feed(struct dvb_demux_feed *feed) +{ + smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + SmsMsgData_ST PidMsg; + + printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_stop_feed(struct dvb_demux_feed *feed) +{ + smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + SmsMsgData_ST PidMsg; + + printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion) +{ + int rc = smsclient_sendrequest(client->smsclient, buffer, size); + if (rc < 0) + return rc; + + return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME; +} + +static int smsdvb_send_statistics_request(smsdvb_client_t *client) +{ + SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done); +} + +static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *stat = client->fe_status; + + return rc; +} + +static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *ber = client->fe_ber; + + return rc; +} + +static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *strength = client->fe_signal_strength; + + return rc; +} + +static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *snr = client->fe_snr; + + return rc; +} + +static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) +{ + printk("%s\n", __FUNCTION__); + + tune->min_delay_ms = 400; + tune->step_size = 250000; + tune->max_drift = 0; + return 0; +} + +static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + + struct + { + SmsMsgHdr_ST Msg; + u32 Data[3]; + } Msg; + + Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.Msg.msgDstId = HIF_TASK; + Msg.Msg.msgFlags = 0; + Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; + Msg.Msg.msgLength = sizeof(Msg); + Msg.Data[0] = fep->frequency; + Msg.Data[2] = 12000000; + + printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth); + + switch(fep->u.ofdm.bandwidth) + { + case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; + case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; + case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; +// case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: return -EINVAL; + } + + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); +} + +static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + + printk("%s\n", __FUNCTION__); + + // todo: + memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); + return 0; +} + +static void smsdvb_release(struct dvb_frontend *fe) +{ + // do nothing +} + +static struct dvb_frontend_ops smsdvb_fe_ops = { + .info = { + .name = "Siano Mobile Digital SMS10xx", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 250000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = smsdvb_release, + + .set_frontend = smsdvb_set_frontend, + .get_frontend = smsdvb_get_frontend, + .get_tune_settings = smsdvb_get_tune_settings, + + .read_status = smsdvb_read_status, + .read_ber = smsdvb_read_ber, + .read_signal_strength = smsdvb_read_signal_strength, + .read_snr = smsdvb_read_snr, +}; + +int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival) +{ + smsclient_params_t params; + smsdvb_client_t* client; + int rc; + + // device removal handled by onremove callback + if (!arrival) + return 0; + + if (smscore_get_device_mode(coredev) != 4) + { + rc = smscore_set_device_mode(coredev, 4); + if (rc < 0) + return rc; + } + + client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); + if (!client) + { + printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); + return -ENOMEM; + } + + // register dvb adapter + rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device); + if (rc < 0) + { + printk("%s dvb_register_adapter() failed %d\n", __func__, rc); + goto adapter_error; + } + + // init dvb demux + client->demux.dmx.capabilities = DMX_TS_FILTERING; + client->demux.filternum = 32; // todo: nova ??? + client->demux.feednum = 32; + client->demux.start_feed = smsdvb_start_feed; + client->demux.stop_feed = smsdvb_stop_feed; + + rc = dvb_dmx_init(&client->demux); + if (rc < 0) + { + printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc); + goto dvbdmx_error; + } + + // init dmxdev + client->dmxdev.filternum = 32; + client->dmxdev.demux = &client->demux.dmx; + client->dmxdev.capabilities = 0; + + rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); + if (rc < 0) + { + printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc); + goto dmxdev_error; + } + + // init and register frontend + memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); + + rc = dvb_register_frontend(&client->adapter, &client->frontend); + if (rc < 0) + { + printk("%s frontend registration failed %d\n", __FUNCTION__, rc); + goto frontend_error; + } + + params.initial_id = 0; + params.data_type = MSG_SMS_DVBT_BDA_DATA; + params.onresponse_handler = smsdvb_onresponse; + params.onremove_handler = smsdvb_onremove; + params.context = client; + + rc = smscore_register_client(coredev, ¶ms, &client->smsclient); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); + goto client_error; + } + + client->coredev = coredev; + + init_completion(&client->tune_done); + init_completion(&client->stat_done); + + kmutex_lock(&g_smsdvb_clientslock); + + list_add(&client->entry, &g_smsdvb_clients); + + kmutex_unlock(&g_smsdvb_clientslock); + + printk(KERN_INFO "%s success\n", __FUNCTION__); + + return 0; + +client_error: + dvb_unregister_frontend(&client->frontend); + +frontend_error: + dvb_dmxdev_release(&client->dmxdev); + +dmxdev_error: + dvb_dmx_release(&client->demux); + +dvbdmx_error: + dvb_unregister_adapter(&client->adapter); + +adapter_error: + kfree(client); + return rc; +} + +int smsdvb_module_init(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smsdvb_clients); + kmutex_init(&g_smsdvb_clientslock); + + rc = smscore_register_hotplug(smsdvb_hotplug); + + printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); + + return rc; +} + +void smsdvb_module_exit(void) +{ + smscore_unregister_hotplug(smsdvb_hotplug); + + kmutex_lock(&g_smsdvb_clientslock); + + while (!list_empty(&g_smsdvb_clients)) + smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); + + kmutex_unlock(&g_smsdvb_clientslock); + + printk(KERN_INFO "%s\n", __FUNCTION__); +} + +module_init(smsdvb_module_init); +module_exit(smsdvb_module_exit); + +MODULE_DESCRIPTION("smsdvb dvb-api module"); +MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/mdtv/smskdefs.h b/drivers/media/mdtv/smskdefs.h new file mode 100644 index 000000000000..6874fbcdc7a8 --- /dev/null +++ b/drivers/media/mdtv/smskdefs.h @@ -0,0 +1,21 @@ +#ifndef __smskdefs_h__ +#define __smskdefs_h__ + +#include +#include +#include +#include +#include +#include + +#include + +typedef struct mutex kmutex_t; + +#define kmutex_init(_p_) mutex_init(_p_) +#define kmutex_lock(_p_) mutex_lock(_p_) +#define kmutex_trylock(_p_) mutex_trylock(_p_) +#define kmutex_unlock(_p_) mutex_unlock(_p_) + + +#endif // __smskdefs_h__ diff --git a/drivers/media/mdtv/smsnet.c b/drivers/media/mdtv/smsnet.c new file mode 100644 index 000000000000..5b70d1261e59 --- /dev/null +++ b/drivers/media/mdtv/smsnet.c @@ -0,0 +1,447 @@ +#include +#include +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include /* struct ipv6hdr */ +#include + +#include "smskdefs.h" // page, scatterlist, kmutex +#include "smscoreapi.h" +#include "smstypes.h" + +#define IPV4VERSION 0x40 +#define IPV6VERSION 0x60 +#define GETIPVERSION(_x_) ((_x_) & 0xf0) + +typedef struct _smsnet_client +{ + struct list_head entry; + + smscore_device_t *coredev; + smscore_client_t *smsclient; + + int packet_length, splitpacket_length; + int header_length, splitheader_length; + u8 splitpacket[ETH_DATA_LEN]; +} smsnet_client_t; + +struct list_head g_smsnet_clients; +kmutex_t g_smsnet_clientslock; + +struct net_device *g_smsnet_device = NULL; +struct net_device_stats g_smsnet_stats; + +int g_smsnet_inuse = 0; + +void smsnet_send_packet(u8* buffer, int length) +{ + u8 *eth; + struct sk_buff *skb = dev_alloc_skb(length + ETH_HLEN + NET_IP_ALIGN); + + if (!skb) + { + g_smsnet_stats.rx_dropped++; + return; + } + + skb_reserve(skb, NET_IP_ALIGN); + + eth = (u8 *) skb_put(skb, length + ETH_HLEN); + memcpy(eth + ETH_HLEN, buffer, length); + + eth[6] = 0; + eth[7] = 1; + eth[8] = 1; + eth[9] = 3; + eth[10] = 4; + eth[11] = 5; + + if (GETIPVERSION(*buffer) == IPV4VERSION) + { + eth[0] = 1; + eth[1] = 0; + eth[2] = 0x5e; + eth[3] = buffer[17] & 0x7f; + eth[4] = buffer[18]; + eth[5] = buffer[19]; + + eth[12] = 0x08; + eth[13] = 0x00; + } + else + { + // todo: ip6 mcast address + + eth[12] = 0x86; + eth[13] = 0xdd; + } + + skb->dev = g_smsnet_device; + skb->protocol = eth_type_trans(skb, g_smsnet_device); + skb->ip_summed = CHECKSUM_UNNECESSARY; + + g_smsnet_stats.rx_packets ++; + g_smsnet_stats.rx_bytes += skb->len; + + netif_rx(skb); +} + +int check_header(smsnet_client_t* client, u8* buffer) +{ + struct iphdr *ip4_hdr; + struct ipv6hdr *ip6_hdr; + struct udphdr *udp_hdr; + u16 csum; + + // check if packet header is valid and it is a UDP + if (GETIPVERSION(*buffer) == IPV4VERSION) + { + ip4_hdr = (struct iphdr*) buffer; + csum = ip4_hdr->check; + + ip4_hdr->check = 0; + + // check header checksum for IPv4 packets + if(ip4_hdr->protocol != IPPROTO_UDP || csum != ip_fast_csum(buffer, ip4_hdr->ihl)) + { + ip4_hdr->check = csum; + return 0; + } + + ip4_hdr->check = csum; + client->packet_length = ntohs(ip4_hdr->tot_len); + } + else + { + ip6_hdr = (struct ipv6hdr *) buffer; + udp_hdr = (struct udphdr *)(ip6_hdr + 1); + + if ((ip6_hdr->nexthdr != IPPROTO_UDP) || + (ip6_hdr->payload_len != udp_hdr->len)) + { + return 0; + } + + client->packet_length = ntohs(ip6_hdr->payload_len) + sizeof(struct ipv6hdr); + } + + // check for abnormal packet length + if (client->packet_length > ETH_DATA_LEN) + return 0; + + return 1; +} + +int smsnet_onresponse(void *context, smscore_buffer_t *cb) +{ + smsnet_client_t *client = (smsnet_client_t *) context; + int length, rest; + u8 ip_ver, *buffer; + + buffer = ((u8*) cb->p) + cb->offset + sizeof(SmsMsgHdr_ST); + length = cb->size - sizeof(SmsMsgHdr_ST); + + if (client->splitheader_length) + { + // how much data is missing ? + rest = client->header_length - client->splitheader_length; + + // do we have enough in this buffer ? + rest = min(rest, length); + + memcpy(&client->splitpacket[client->splitheader_length], buffer, rest); + + client->splitheader_length += rest; + + if (client->splitheader_length != client->header_length) + goto exit; + + if (check_header(client, client->splitpacket)) + { + buffer += rest; + length -= rest; + + client->splitpacket_length = client->header_length; + } + + client->splitheader_length = 0; + } + + if (client->splitpacket_length) + { + // how much data is missing ? + rest = client->packet_length - client->splitpacket_length; + + // do we have enough in this buffer ? + rest = min(rest, length); + + memcpy(&client->splitpacket[client->splitpacket_length], buffer, rest); + + client->splitpacket_length += rest; + + if (client->splitpacket_length != client->packet_length) + goto exit; + + client->splitpacket_length = 0; + + smsnet_send_packet(client->splitpacket, client->packet_length); + + buffer += rest; + length -= rest; + } + + while (length > 0) + { + ip_ver = GETIPVERSION(*buffer); + while (length && (ip_ver != IPV4VERSION) && (ip_ver != IPV6VERSION)) + { + buffer++; + length--; + ip_ver = GETIPVERSION(*buffer); + } + + // No more data in section + if (!length) + break; + + // Set the header length at start of packet according to the version + // no problem with the IP header cast, since we have at least 1 byte (we use only the first byte) + client->header_length = (ip_ver == IPV4VERSION) ? (((struct iphdr *) buffer)->ihl * 4) : (sizeof(struct ipv6hdr) + sizeof(struct udphdr)); + + // Check that Header length is at least 20 (min IPv4 length) + if (client->header_length < 20) + { + length--; + buffer++; + continue; + } + + // check split header case + if (client->header_length > length) + { + memcpy(client->splitpacket, buffer, length); + client->splitheader_length = length; + break; + } + + if (check_header(client, buffer)) + { + // check split packet case + if (client->packet_length > length) + { + memcpy(client->splitpacket, buffer, length); + client->splitpacket_length = length; + break; + } + } + else + { + length --; + buffer ++; + continue; + } + + smsnet_send_packet(buffer, client->packet_length); + + buffer += client->packet_length; + length -= client->packet_length; + } + +exit: + smscore_putbuffer(client->coredev, cb); + + return 0; +} + +void smsnet_unregister_client(smsnet_client_t* client) +{ + // must be called under clientslock + + list_del(&client->entry); + + smscore_unregister_client(client->smsclient); + kfree(client); +} + +void smsnet_onremove(void *context) +{ + kmutex_lock(&g_smsnet_clientslock); + + smsnet_unregister_client((smsnet_client_t*) context); + + kmutex_unlock(&g_smsnet_clientslock); +} + +int smsnet_hotplug(smscore_device_t *coredev, struct device* device, int arrival) +{ + smsclient_params_t params; + smsnet_client_t* client; + int rc; + + // device removal handled by onremove callback + if (!arrival) + return 0; + + client = kzalloc(sizeof(smsnet_client_t), GFP_KERNEL); + if (!client) + { + printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); + return -ENOMEM; + } + + params.initial_id = 0; + params.data_type = MSG_SMS_DATA_MSG; + params.onresponse_handler = smsnet_onresponse; + params.onremove_handler = smsnet_onremove; + params.context = client; + + rc = smscore_register_client(coredev, ¶ms, &client->smsclient); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); + kfree(client); + return rc; + } + + client->coredev = coredev; + + kmutex_lock(&g_smsnet_clientslock); + + list_add(&client->entry, &g_smsnet_clients); + + kmutex_unlock(&g_smsnet_clientslock); + + printk(KERN_INFO "%s success\n", __FUNCTION__); + + return 0; +} + +static int smsnet_open(struct net_device *dev) +{ + g_smsnet_inuse ++; + + netif_start_queue(dev); + + printk(KERN_INFO "%s, %d\n", __FUNCTION__, g_smsnet_inuse); + + return 0; +} + +static int smsnet_stop(struct net_device *dev) +{ + netif_stop_queue(dev); + + g_smsnet_inuse --; + + printk(KERN_INFO "%s, %d\n", __FUNCTION__, g_smsnet_inuse); + + return 0; +} + +static int smsnet_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + printk(KERN_INFO "%s\n", __FUNCTION__); + + dev_kfree_skb(skb); + return 0; +} + +static struct net_device_stats * smsnet_get_stats(struct net_device *dev) +{ + return &g_smsnet_stats; +} + +static void smsnet_set_multicast_list(struct net_device *dev) +{ + printk(KERN_INFO "%s %d\n", __FUNCTION__, dev->mc_count); + if (dev->mc_count) + { + struct dev_mc_list *p; + + for (p = dev->mc_list; p; p = p->next) + printk(KERN_INFO "%s %d %02x %02x %02x %02x %02x %02x %02x %02x\n", __FUNCTION__, p->dmi_addrlen, + p->dmi_addr[0], p->dmi_addr[1], p->dmi_addr[2], p->dmi_addr[3], + p->dmi_addr[4], p->dmi_addr[5], p->dmi_addr[6], p->dmi_addr[7] + ); + } +} + +static void smsnet_setup_device(struct net_device *dev) +{ + ether_setup(dev); + + dev->open = smsnet_open; + dev->stop = smsnet_stop; + dev->hard_start_xmit = smsnet_hard_start_xmit; + dev->get_stats = smsnet_get_stats; + dev->set_multicast_list = smsnet_set_multicast_list; + + dev->mc_count = 0; + dev->hard_header_cache = NULL; + + memcpy(dev->dev_addr, "\0SIANO", ETH_ALEN); + + dev->flags |= IFF_NOARP; + dev->features |= NETIF_F_NO_CSUM; +} + +int smsnet_module_init(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smsnet_clients); + kmutex_init(&g_smsnet_clientslock); + + memset(&g_smsnet_stats, 0, sizeof(g_smsnet_stats)); + + g_smsnet_device = alloc_netdev(0, "sms", smsnet_setup_device); + if (!g_smsnet_device) + { + printk(KERN_INFO "%s alloc_netdev() failed\n", __FUNCTION__); + return -ENOMEM; + } + + rc = register_netdev(g_smsnet_device); + if (rc < 0) + { + printk(KERN_INFO "%s register_netdev() failed %d\n", __FUNCTION__, rc); + free_netdev(g_smsnet_device); + return rc; + } + + rc = smscore_register_hotplug(smsnet_hotplug); + + printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); + + return rc; +} + +void smsnet_module_exit(void) +{ + if (g_smsnet_device) + { + unregister_netdev(g_smsnet_device); + free_netdev(g_smsnet_device); + + g_smsnet_device = NULL; + } + + smscore_unregister_hotplug(smsnet_hotplug); + + kmutex_lock(&g_smsnet_clientslock); + + while (!list_empty(&g_smsnet_clients)) + smsnet_unregister_client((smsnet_client_t*) g_smsnet_clients.next); + + kmutex_unlock(&g_smsnet_clientslock); + + printk(KERN_INFO "%s\n", __FUNCTION__); +} + +module_init(smsnet_module_init); +module_exit(smsnet_module_exit); + +MODULE_DESCRIPTION("smsnet dvb-h ip sink module"); +MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/mdtv/smstypes.h b/drivers/media/mdtv/smstypes.h new file mode 100644 index 000000000000..011cd904d0f1 --- /dev/null +++ b/drivers/media/mdtv/smstypes.h @@ -0,0 +1,361 @@ +#ifndef __smstypes_h__ +#define __smstypes_h__ + +// GPIO definitions for antenna frequency domain control (SMS8021) +#define SMS_ANTENNA_GPIO_0 1 +#define SMS_ANTENNA_GPIO_1 0 + +#define BW_8_MHZ 0 +#define BW_7_MHZ 1 +#define BW_6_MHZ 2 +#define BW_5_MHZ 3 +#define BW_ISDBT_1SEG 4 +#define BW_ISDBT_3SEG 5 + +#define MSG_HDR_FLAG_SPLIT_MSG 4 + +#define MAX_GPIO_PIN_NUMBER 31 + +#define HIF_TASK 11 +#define SMS_HOST_LIB 150 +#define DVBT_BDA_CONTROL_MSG_ID 201 + +#define SMS_MAX_PAYLOAD_SIZE 240 +#define SMS_TUNE_TIMEOUT 500 + +#define MSG_SMS_GPIO_CONFIG_REQ 507 +#define MSG_SMS_GPIO_CONFIG_RES 508 +#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 +#define MSG_SMS_GPIO_SET_LEVEL_RES 510 +#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 +#define MSG_SMS_GPIO_GET_LEVEL_RES 512 +#define MSG_SMS_RF_TUNE_REQ 561 +#define MSG_SMS_RF_TUNE_RES 562 +#define MSG_SMS_INIT_DEVICE_REQ 578 +#define MSG_SMS_INIT_DEVICE_RES 579 +#define MSG_SMS_ADD_PID_FILTER_REQ 601 +#define MSG_SMS_ADD_PID_FILTER_RES 602 +#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 +#define MSG_SMS_REMOVE_PID_FILTER_RES 604 +#define MSG_SMS_DAB_CHANNEL 607 +#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 +#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 +#define MSG_SMS_GET_STATISTICS_REQ 615 +#define MSG_SMS_GET_STATISTICS_RES 616 +#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 +#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 +#define MSG_SMS_GET_STATISTICS_EX_REQ 653 +#define MSG_SMS_GET_STATISTICS_EX_RES 654 +#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 +#define MSG_SMS_DATA_DOWNLOAD_REQ 660 +#define MSG_SMS_DATA_DOWNLOAD_RES 661 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 +#define MSG_SMS_GET_VERSION_EX_REQ 668 +#define MSG_SMS_GET_VERSION_EX_RES 669 +#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 +#define MSG_SMS_I2C_SET_FREQ_REQ 685 +#define MSG_SMS_GENERIC_I2C_REQ 687 +#define MSG_SMS_GENERIC_I2C_RES 688 +#define MSG_SMS_DVBT_BDA_DATA 693 +#define MSG_SW_RELOAD_REQ 697 +#define MSG_SMS_DATA_MSG 699 +#define MSG_SW_RELOAD_START_REQ 702 +#define MSG_SW_RELOAD_START_RES 703 +#define MSG_SW_RELOAD_EXEC_REQ 704 +#define MSG_SW_RELOAD_EXEC_RES 705 +#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 +#define MSG_SMS_ISDBT_TUNE_REQ 776 +#define MSG_SMS_ISDBT_TUNE_RES 777 + +#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ + (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ + (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ +} while (0) +#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) + +typedef enum +{ + DEVICE_MODE_NONE = -1, + DEVICE_MODE_DVBT = 0, + DEVICE_MODE_DVBH, + DEVICE_MODE_DAB_TDMB, + DEVICE_MODE_DAB_TDMB_DABIP, + DEVICE_MODE_DVBT_BDA, + DEVICE_MODE_ISDBT, + DEVICE_MODE_ISDBT_BDA, + DEVICE_MODE_CMMB, + DEVICE_MODE_RAW_TUNER, + DEVICE_MODE_MAX, +} SMS_DEVICE_MODE; + +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef int INT32; + +typedef struct SmsMsgHdr_S +{ + UINT16 msgType; + UINT8 msgSrcId; + UINT8 msgDstId; + UINT16 msgLength; // Length is of the entire message, including header + UINT16 msgFlags; +} SmsMsgHdr_ST; + +typedef struct SmsMsgData_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 msgData[1]; +} SmsMsgData_ST; + +typedef struct SmsDataDownload_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 MemAddr; + UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; +} SmsDataDownload_ST; + +typedef struct SmsVersionRes_S +{ + SmsMsgHdr_ST xMsgHeader; + + UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" + UINT8 Step; // 0 - Step A + UINT8 MetalFix; // 0 - Metal 0 + + UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E + UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols + + UINT8 VersionMajor; + UINT8 VersionMinor; + UINT8 VersionPatch; + UINT8 VersionFieldPatch; + + UINT8 RomVersionMajor; + UINT8 RomVersionMinor; + UINT8 RomVersionPatch; + UINT8 RomVersionFieldPatch; + + UINT8 TextLabel[34]; +} SmsVersionRes_ST; + +typedef struct SmsFirmware_S +{ + UINT32 CheckSum; + UINT32 Length; + UINT32 StartAddress; + UINT8 Payload[1]; +} SmsFirmware_ST; + +typedef struct SMSHOSTLIB_STATISTICS_S +{ + UINT32 Reserved; //!< Reserved + + /// Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + /// Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + /// Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H + UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos + UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H + UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H + UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H + + /// Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding + /// Common params + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + + /// Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + + /// DAB/T-DMB + UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] + + /// DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + +} SMSHOSTLIB_STATISTICS_ST; + +typedef struct +{ + UINT32 RequestResult; + + SMSHOSTLIB_STATISTICS_ST Stat; + + // Split the calc of the SNR in DAB + UINT32 Signal; //!< dB + UINT32 Noise; //!< dB + +} SmsMsgStatisticsInfo_ST; + +typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S +{ + // Per-layer information + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist + UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count + UINT32 BERBitCount; //!< Post Viterbi Total Bits Count + UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist + UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist + UINT32 TMCCErrors; //!< TMCC errors +} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in Hz + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 TransmissionMode; //!< ISDB-T transmission mode + UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) + UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise + UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network + + // Per-layer information + // Layers A, B and C + SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_ISDBT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_DVB_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET + UINT32 TransmissionMode; //!< FFT mode carriers in Kilos + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET + + // Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H + UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received + + // DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_DVB_ST; + +typedef struct SMSHOSTLIB_GPIO_CONFIG_S +{ + UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 + UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 + UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 + UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 + UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 +} SMSHOSTLIB_GPIO_CONFIG_ST; + +typedef struct SMSHOSTLIB_I2C_REQ_S +{ + UINT32 DeviceAddress; // I2c device address + UINT32 WriteCount; // number of bytes to write + UINT32 ReadCount; // number of bytes to read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_REQ_ST; + +typedef struct SMSHOSTLIB_I2C_RES_S +{ + UINT32 Status; // non-zero value in case of failure + UINT32 ReadCount; // number of bytes read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_RES_ST; + +#endif // __smstypes_h__ diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c new file mode 100644 index 000000000000..43af826b3832 --- /dev/null +++ b/drivers/media/mdtv/smsusb.c @@ -0,0 +1,428 @@ +#include +#include +#include +#include +#include + +#include "smskdefs.h" // page, scatterlist, kmutex +#include "smscoreapi.h" +#include "smstypes.h" + +#define USB_VID_SIANO 0x187f +#define USB_PID_0010 0x0010 +#define USB_PID_0100 0x0100 +#define USB_PID_0200 0x0200 + +#define USB1_BUFFER_SIZE 0x1000 +#define USB2_BUFFER_SIZE 0x4000 + +#define MAX_BUFFERS 50 +#define MAX_URBS 10 + +typedef struct _smsusb_device smsusb_device_t; + +typedef struct _smsusb_urb +{ + smscore_buffer_t *cb; + smsusb_device_t *dev; + + struct urb urb; +} smsusb_urb_t; + +typedef struct _smsusb_device +{ + struct usb_device* udev; + smscore_device_t *coredev; + + smsusb_urb_t surbs[MAX_URBS]; + + int response_alignment; + int buffer_size; +} *psmsusb_device_t; + +static struct usb_device_id smsusb_id_table [] = { + { USB_DEVICE(USB_VID_SIANO, USB_PID_0010) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_0100) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_0200) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, smsusb_id_table); + +int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb); + +void smsusb_onresponse(struct urb *urb) +{ + smsusb_urb_t *surb = (smsusb_urb_t *) urb->context; + smsusb_device_t *dev = surb->dev; + + if (urb->status < 0) + { + printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length); + return; + } + + if (urb->actual_length > 0) + { + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p; + + if (urb->actual_length >= phdr->msgLength) + { + surb->cb->size = phdr->msgLength; + + if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) + { + surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3); + + // sanity check + if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) + { + printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length); + goto exit_and_resubmit; + } + + // move buffer pointer and copy header to its new location + memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST)); + } + else + surb->cb->offset = 0; + + smscore_onresponse(dev->coredev, surb->cb); + surb->cb = NULL; + } + else + { + printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length); + } + } + +exit_and_resubmit: + smsusb_submit_urb(dev, surb); +} + +int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) +{ + if (!surb->cb) + { + surb->cb = smscore_getbuffer(dev->coredev); + if (!surb->cb) + { + printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__); + return -ENOMEM; + } + } + + usb_fill_bulk_urb( + &surb->urb, + dev->udev, + usb_rcvbulkpipe(dev->udev, 0x81), + surb->cb->p, + dev->buffer_size, + smsusb_onresponse, + surb + ); + surb->urb.transfer_dma = surb->cb->phys; + surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + return usb_submit_urb(&surb->urb, GFP_ATOMIC); +} + +void smsusb_stop_streaming(smsusb_device_t* dev) +{ + int i; + + for (i = 0; i < MAX_URBS; i ++) + { + usb_kill_urb(&dev->surbs[i].urb); + + if (dev->surbs[i].cb) + { + smscore_putbuffer(dev->coredev, dev->surbs[i].cb); + dev->surbs[i].cb = NULL; + } + } +} + +int smsusb_start_streaming(smsusb_device_t* dev) +{ + int i, rc; + + for (i = 0; i < MAX_URBS; i ++) + { + rc = smsusb_submit_urb(dev, &dev->surbs[i]); + if (rc < 0) + { + printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__); + smsusb_stop_streaming(dev); + break; + } + } + + return rc; +} + +int smsusb_sendrequest(void *context, void *buffer, size_t size) +{ + smsusb_device_t* dev = (smsusb_device_t*) context; + int dummy; + + return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); +} + +char *smsusb1_fw_lkup[] = +{ + "dvbt_stellar_usb.inp", + "dvbh_stellar_usb.inp", + "tdmb_stellar_usb.inp", + "none", + "dvbt_bda_stellar_usb.inp", +}; + +int smsusb1_load_firmware(struct usb_device *udev, int id) +{ + const struct firmware *fw; + u8* fw_buffer; + int rc, dummy; + + if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) + { + printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id); + return -EINVAL; + } + + rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); + if (rc < 0) + { + printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id); + return rc; + } + + fw_buffer = kmalloc(fw->size, GFP_KERNEL); + if (fw_buffer) + { + memcpy(fw_buffer, fw->data, fw->size); + + rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); + + printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc); + + kfree(fw_buffer); + } + else + { + printk(KERN_INFO "failed to allocate firmware buffer\n"); + rc = -ENOMEM; + } + + release_firmware(fw); + + return rc; +} + +void smsusb1_detectmode(void *context, int *mode) +{ + char *product_string = ((smsusb_device_t *) context)->udev->product; + + *mode = DEVICE_MODE_NONE; + + if (!product_string) + { + product_string = "none"; + printk("%s product string not found\n", __FUNCTION__); + } + else + { + if (strstr(product_string, "DVBH")) + *mode = 1; + else if (strstr(product_string, "BDA")) + *mode = 4; + else if (strstr(product_string, "DVBT")) + *mode = 0; + else if (strstr(product_string, "TDMB")) + *mode = 2; + } + + printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string); +} + +int smsusb1_setmode(void *context, int mode) +{ + SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) + { + printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode); + return -EINVAL; + } + + return smsusb_sendrequest(context, &Msg, sizeof(Msg)); +} + +void smsusb_term_device(struct usb_interface *intf) +{ + smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf); + + if (dev) + { + smsusb_stop_streaming(dev); + + // unregister from smscore + if (dev->coredev) + smscore_unregister_device(dev->coredev); + + kfree(dev); + + printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev); + } + + usb_set_intfdata(intf, NULL); +} + +int smsusb_init_device(struct usb_interface *intf) +{ + smsdevice_params_t params; + smsusb_device_t* dev; + int i, rc; + + // create device object + dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); + if (!dev) + { + printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__); + return -ENOMEM; + } + + memset(¶ms, 0, sizeof(params)); + usb_set_intfdata(intf, dev); + dev->udev = interface_to_usbdev(intf); + + switch (dev->udev->descriptor.idProduct) + { + case USB_PID_0100: + dev->buffer_size = USB1_BUFFER_SIZE; + + params.setmode_handler = smsusb1_setmode; + params.detectmode_handler = smsusb1_detectmode; + break; + + default: + dev->buffer_size = USB2_BUFFER_SIZE; + dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); + + params.flags |= SMS_DEVICE_FAMILY2; + break; + } + + params.device = &dev->udev->dev; + params.buffer_size = dev->buffer_size; + params.num_buffers = MAX_BUFFERS; + params.sendrequest_handler = smsusb_sendrequest; + params.context = dev; + snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); + + // register in smscore + rc = smscore_register_device(¶ms, &dev->coredev); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc); + smsusb_term_device(intf); + return rc; + } + + // initialize urbs + for (i = 0; i < MAX_URBS; i ++) + { + dev->surbs[i].dev = dev; + usb_init_urb(&dev->surbs[i].urb); + } + + rc = smsusb_start_streaming(dev); + if (rc < 0) + { + printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__); + smsusb_term_device(intf); + return rc; + } + + rc = smscore_start_device(dev->coredev); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__); + smsusb_term_device(intf); + return rc; + } + + printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + + return rc; +} + +int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + char devpath[32]; + int i, rc; + + if (intf->num_altsetting > 0) + { + rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); + if (rc < 0) + { + printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc); + return rc; + } + } + + printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) + printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); + + if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0) + { + printk(KERN_INFO "rom interface 0 is not used\n"); + return -ENODEV; + } + + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) + { + snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath); + return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); + } + + return smsusb_init_device(intf); +} + +void smsusb_disconnect(struct usb_interface *intf) +{ + smsusb_term_device(intf); +} + +static struct usb_driver smsusb_driver = { + .name = "smsusb", + .probe = smsusb_probe, + .disconnect = smsusb_disconnect, + .id_table = smsusb_id_table, +}; + +int smsusb_module_init(void) +{ + int rc = usb_register(&smsusb_driver); + if (rc) + printk(KERN_INFO "usb_register failed. Error number %d\n", rc); + + printk(KERN_INFO "%s\n", __FUNCTION__); + + return rc; +} + +void smsusb_module_exit(void) +{ + usb_deregister(&smsusb_driver); + printk(KERN_INFO "%s\n", __FUNCTION__); +} + +module_init(smsusb_module_init); +module_exit(smsusb_module_exit); + +MODULE_DESCRIPTION("smsusb"); +MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9c59f968a9960bbb3402c8a8ea8004c798f4f383 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 19 May 2008 18:57:12 -0300 Subject: V4L/DVB (8259): sms1xxx: pass adapter_nr into dvb_register_adapter Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smsdvb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index f2ed1718d180..ecba51c8b65b 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -10,6 +10,8 @@ #include "smscoreapi.h" #include "smstypes.h" +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + typedef struct _smsdvb_client { struct list_head entry; @@ -314,7 +316,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival } // register dvb adapter - rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device); + rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); if (rc < 0) { printk("%s dvb_register_adapter() failed %d\n", __func__, rc); -- cgit v1.2.3 From 7315b082e333191f7606dbb23dbcbdba98a79c11 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 19 May 2008 18:58:40 -0300 Subject: V4L/DVB (8260): sms1xxx: build fixes Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/Makefile | 7 ++++--- drivers/media/mdtv/smschar.c | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile index 1e54d8f796dc..9798657c7a52 100644 --- a/drivers/media/mdtv/Makefile +++ b/drivers/media/mdtv/Makefile @@ -2,7 +2,8 @@ # Makefile for the kernel MDTV driver # -obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smschar.o smsnet.o -obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o +smscore-objs := smschar.o smscoreapi.o -EXTRA_CFLAGS += +obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o smsnet.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsdvb.o diff --git a/drivers/media/mdtv/smschar.c b/drivers/media/mdtv/smschar.c index 0477ad0ed6d6..15ebecd598ec 100644 --- a/drivers/media/mdtv/smschar.c +++ b/drivers/media/mdtv/smschar.c @@ -565,6 +565,7 @@ int smschar_initialize(void) return smscore_register_hotplug(smschar_hotplug); } +EXPORT_SYMBOL(smschar_initialize); void smschar_terminate(void) { @@ -573,3 +574,4 @@ void smschar_terminate(void) unregister_chrdev_region(devno, SMSCHAR_NR_DEVS); smscore_unregister_hotplug(smschar_hotplug); } +EXPORT_SYMBOL(smschar_terminate); -- cgit v1.2.3 From 464a77dd8845fc8f3beeaad24478081576c4b83a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 19 May 2008 19:01:25 -0300 Subject: V4L/DVB (8261): sms1xxx: remove smsnet.o Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/Makefile | 2 +- drivers/media/mdtv/smsnet.c | 447 -------------------------------------------- 2 files changed, 1 insertion(+), 448 deletions(-) delete mode 100644 drivers/media/mdtv/smsnet.c (limited to 'drivers/media') diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile index 9798657c7a52..c3cf917d726a 100644 --- a/drivers/media/mdtv/Makefile +++ b/drivers/media/mdtv/Makefile @@ -4,6 +4,6 @@ smscore-objs := smschar.o smscoreapi.o -obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o smsnet.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsdvb.o diff --git a/drivers/media/mdtv/smsnet.c b/drivers/media/mdtv/smsnet.c deleted file mode 100644 index 5b70d1261e59..000000000000 --- a/drivers/media/mdtv/smsnet.c +++ /dev/null @@ -1,447 +0,0 @@ -#include -#include -#include /* struct device, and other headers */ -#include /* eth_type_trans */ -#include /* struct iphdr */ -#include /* struct ipv6hdr */ -#include - -#include "smskdefs.h" // page, scatterlist, kmutex -#include "smscoreapi.h" -#include "smstypes.h" - -#define IPV4VERSION 0x40 -#define IPV6VERSION 0x60 -#define GETIPVERSION(_x_) ((_x_) & 0xf0) - -typedef struct _smsnet_client -{ - struct list_head entry; - - smscore_device_t *coredev; - smscore_client_t *smsclient; - - int packet_length, splitpacket_length; - int header_length, splitheader_length; - u8 splitpacket[ETH_DATA_LEN]; -} smsnet_client_t; - -struct list_head g_smsnet_clients; -kmutex_t g_smsnet_clientslock; - -struct net_device *g_smsnet_device = NULL; -struct net_device_stats g_smsnet_stats; - -int g_smsnet_inuse = 0; - -void smsnet_send_packet(u8* buffer, int length) -{ - u8 *eth; - struct sk_buff *skb = dev_alloc_skb(length + ETH_HLEN + NET_IP_ALIGN); - - if (!skb) - { - g_smsnet_stats.rx_dropped++; - return; - } - - skb_reserve(skb, NET_IP_ALIGN); - - eth = (u8 *) skb_put(skb, length + ETH_HLEN); - memcpy(eth + ETH_HLEN, buffer, length); - - eth[6] = 0; - eth[7] = 1; - eth[8] = 1; - eth[9] = 3; - eth[10] = 4; - eth[11] = 5; - - if (GETIPVERSION(*buffer) == IPV4VERSION) - { - eth[0] = 1; - eth[1] = 0; - eth[2] = 0x5e; - eth[3] = buffer[17] & 0x7f; - eth[4] = buffer[18]; - eth[5] = buffer[19]; - - eth[12] = 0x08; - eth[13] = 0x00; - } - else - { - // todo: ip6 mcast address - - eth[12] = 0x86; - eth[13] = 0xdd; - } - - skb->dev = g_smsnet_device; - skb->protocol = eth_type_trans(skb, g_smsnet_device); - skb->ip_summed = CHECKSUM_UNNECESSARY; - - g_smsnet_stats.rx_packets ++; - g_smsnet_stats.rx_bytes += skb->len; - - netif_rx(skb); -} - -int check_header(smsnet_client_t* client, u8* buffer) -{ - struct iphdr *ip4_hdr; - struct ipv6hdr *ip6_hdr; - struct udphdr *udp_hdr; - u16 csum; - - // check if packet header is valid and it is a UDP - if (GETIPVERSION(*buffer) == IPV4VERSION) - { - ip4_hdr = (struct iphdr*) buffer; - csum = ip4_hdr->check; - - ip4_hdr->check = 0; - - // check header checksum for IPv4 packets - if(ip4_hdr->protocol != IPPROTO_UDP || csum != ip_fast_csum(buffer, ip4_hdr->ihl)) - { - ip4_hdr->check = csum; - return 0; - } - - ip4_hdr->check = csum; - client->packet_length = ntohs(ip4_hdr->tot_len); - } - else - { - ip6_hdr = (struct ipv6hdr *) buffer; - udp_hdr = (struct udphdr *)(ip6_hdr + 1); - - if ((ip6_hdr->nexthdr != IPPROTO_UDP) || - (ip6_hdr->payload_len != udp_hdr->len)) - { - return 0; - } - - client->packet_length = ntohs(ip6_hdr->payload_len) + sizeof(struct ipv6hdr); - } - - // check for abnormal packet length - if (client->packet_length > ETH_DATA_LEN) - return 0; - - return 1; -} - -int smsnet_onresponse(void *context, smscore_buffer_t *cb) -{ - smsnet_client_t *client = (smsnet_client_t *) context; - int length, rest; - u8 ip_ver, *buffer; - - buffer = ((u8*) cb->p) + cb->offset + sizeof(SmsMsgHdr_ST); - length = cb->size - sizeof(SmsMsgHdr_ST); - - if (client->splitheader_length) - { - // how much data is missing ? - rest = client->header_length - client->splitheader_length; - - // do we have enough in this buffer ? - rest = min(rest, length); - - memcpy(&client->splitpacket[client->splitheader_length], buffer, rest); - - client->splitheader_length += rest; - - if (client->splitheader_length != client->header_length) - goto exit; - - if (check_header(client, client->splitpacket)) - { - buffer += rest; - length -= rest; - - client->splitpacket_length = client->header_length; - } - - client->splitheader_length = 0; - } - - if (client->splitpacket_length) - { - // how much data is missing ? - rest = client->packet_length - client->splitpacket_length; - - // do we have enough in this buffer ? - rest = min(rest, length); - - memcpy(&client->splitpacket[client->splitpacket_length], buffer, rest); - - client->splitpacket_length += rest; - - if (client->splitpacket_length != client->packet_length) - goto exit; - - client->splitpacket_length = 0; - - smsnet_send_packet(client->splitpacket, client->packet_length); - - buffer += rest; - length -= rest; - } - - while (length > 0) - { - ip_ver = GETIPVERSION(*buffer); - while (length && (ip_ver != IPV4VERSION) && (ip_ver != IPV6VERSION)) - { - buffer++; - length--; - ip_ver = GETIPVERSION(*buffer); - } - - // No more data in section - if (!length) - break; - - // Set the header length at start of packet according to the version - // no problem with the IP header cast, since we have at least 1 byte (we use only the first byte) - client->header_length = (ip_ver == IPV4VERSION) ? (((struct iphdr *) buffer)->ihl * 4) : (sizeof(struct ipv6hdr) + sizeof(struct udphdr)); - - // Check that Header length is at least 20 (min IPv4 length) - if (client->header_length < 20) - { - length--; - buffer++; - continue; - } - - // check split header case - if (client->header_length > length) - { - memcpy(client->splitpacket, buffer, length); - client->splitheader_length = length; - break; - } - - if (check_header(client, buffer)) - { - // check split packet case - if (client->packet_length > length) - { - memcpy(client->splitpacket, buffer, length); - client->splitpacket_length = length; - break; - } - } - else - { - length --; - buffer ++; - continue; - } - - smsnet_send_packet(buffer, client->packet_length); - - buffer += client->packet_length; - length -= client->packet_length; - } - -exit: - smscore_putbuffer(client->coredev, cb); - - return 0; -} - -void smsnet_unregister_client(smsnet_client_t* client) -{ - // must be called under clientslock - - list_del(&client->entry); - - smscore_unregister_client(client->smsclient); - kfree(client); -} - -void smsnet_onremove(void *context) -{ - kmutex_lock(&g_smsnet_clientslock); - - smsnet_unregister_client((smsnet_client_t*) context); - - kmutex_unlock(&g_smsnet_clientslock); -} - -int smsnet_hotplug(smscore_device_t *coredev, struct device* device, int arrival) -{ - smsclient_params_t params; - smsnet_client_t* client; - int rc; - - // device removal handled by onremove callback - if (!arrival) - return 0; - - client = kzalloc(sizeof(smsnet_client_t), GFP_KERNEL); - if (!client) - { - printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); - return -ENOMEM; - } - - params.initial_id = 0; - params.data_type = MSG_SMS_DATA_MSG; - params.onresponse_handler = smsnet_onresponse; - params.onremove_handler = smsnet_onremove; - params.context = client; - - rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); - kfree(client); - return rc; - } - - client->coredev = coredev; - - kmutex_lock(&g_smsnet_clientslock); - - list_add(&client->entry, &g_smsnet_clients); - - kmutex_unlock(&g_smsnet_clientslock); - - printk(KERN_INFO "%s success\n", __FUNCTION__); - - return 0; -} - -static int smsnet_open(struct net_device *dev) -{ - g_smsnet_inuse ++; - - netif_start_queue(dev); - - printk(KERN_INFO "%s, %d\n", __FUNCTION__, g_smsnet_inuse); - - return 0; -} - -static int smsnet_stop(struct net_device *dev) -{ - netif_stop_queue(dev); - - g_smsnet_inuse --; - - printk(KERN_INFO "%s, %d\n", __FUNCTION__, g_smsnet_inuse); - - return 0; -} - -static int smsnet_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - printk(KERN_INFO "%s\n", __FUNCTION__); - - dev_kfree_skb(skb); - return 0; -} - -static struct net_device_stats * smsnet_get_stats(struct net_device *dev) -{ - return &g_smsnet_stats; -} - -static void smsnet_set_multicast_list(struct net_device *dev) -{ - printk(KERN_INFO "%s %d\n", __FUNCTION__, dev->mc_count); - if (dev->mc_count) - { - struct dev_mc_list *p; - - for (p = dev->mc_list; p; p = p->next) - printk(KERN_INFO "%s %d %02x %02x %02x %02x %02x %02x %02x %02x\n", __FUNCTION__, p->dmi_addrlen, - p->dmi_addr[0], p->dmi_addr[1], p->dmi_addr[2], p->dmi_addr[3], - p->dmi_addr[4], p->dmi_addr[5], p->dmi_addr[6], p->dmi_addr[7] - ); - } -} - -static void smsnet_setup_device(struct net_device *dev) -{ - ether_setup(dev); - - dev->open = smsnet_open; - dev->stop = smsnet_stop; - dev->hard_start_xmit = smsnet_hard_start_xmit; - dev->get_stats = smsnet_get_stats; - dev->set_multicast_list = smsnet_set_multicast_list; - - dev->mc_count = 0; - dev->hard_header_cache = NULL; - - memcpy(dev->dev_addr, "\0SIANO", ETH_ALEN); - - dev->flags |= IFF_NOARP; - dev->features |= NETIF_F_NO_CSUM; -} - -int smsnet_module_init(void) -{ - int rc; - - INIT_LIST_HEAD(&g_smsnet_clients); - kmutex_init(&g_smsnet_clientslock); - - memset(&g_smsnet_stats, 0, sizeof(g_smsnet_stats)); - - g_smsnet_device = alloc_netdev(0, "sms", smsnet_setup_device); - if (!g_smsnet_device) - { - printk(KERN_INFO "%s alloc_netdev() failed\n", __FUNCTION__); - return -ENOMEM; - } - - rc = register_netdev(g_smsnet_device); - if (rc < 0) - { - printk(KERN_INFO "%s register_netdev() failed %d\n", __FUNCTION__, rc); - free_netdev(g_smsnet_device); - return rc; - } - - rc = smscore_register_hotplug(smsnet_hotplug); - - printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); - - return rc; -} - -void smsnet_module_exit(void) -{ - if (g_smsnet_device) - { - unregister_netdev(g_smsnet_device); - free_netdev(g_smsnet_device); - - g_smsnet_device = NULL; - } - - smscore_unregister_hotplug(smsnet_hotplug); - - kmutex_lock(&g_smsnet_clientslock); - - while (!list_empty(&g_smsnet_clients)) - smsnet_unregister_client((smsnet_client_t*) g_smsnet_clients.next); - - kmutex_unlock(&g_smsnet_clientslock); - - printk(KERN_INFO "%s\n", __FUNCTION__); -} - -module_init(smsnet_module_init); -module_exit(smsnet_module_exit); - -MODULE_DESCRIPTION("smsnet dvb-h ip sink module"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From c6465799c38762b963bb819e033d2a56a3d3c233 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 19 May 2008 19:09:21 -0300 Subject: V4L/DVB (8262): sms1xxx: remove smschar.o Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/Makefile | 2 +- drivers/media/mdtv/smschar.c | 577 -------------------------------------- drivers/media/mdtv/smschar.h | 7 - drivers/media/mdtv/smscharioctl.h | 17 -- drivers/media/mdtv/smscoreapi.c | 8 +- 5 files changed, 2 insertions(+), 609 deletions(-) delete mode 100644 drivers/media/mdtv/smschar.c delete mode 100644 drivers/media/mdtv/smschar.h delete mode 100644 drivers/media/mdtv/smscharioctl.h (limited to 'drivers/media') diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile index c3cf917d726a..0af1b3827821 100644 --- a/drivers/media/mdtv/Makefile +++ b/drivers/media/mdtv/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel MDTV driver # -smscore-objs := smschar.o smscoreapi.o +smscore-objs := smscoreapi.o obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o diff --git a/drivers/media/mdtv/smschar.c b/drivers/media/mdtv/smschar.c deleted file mode 100644 index 15ebecd598ec..000000000000 --- a/drivers/media/mdtv/smschar.c +++ /dev/null @@ -1,577 +0,0 @@ -/*! - - \file smschar.c - - \brief Implementation of smscore client for cdev based access - - \par Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - - \par This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 3 as - published by the Free Software Foundation; - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. - - \author Anatoly Greenblat - -*/ - -#include -#include -#include - -#include /* printk() */ -#include /* everything... */ -#include /* size_t */ -#include -#include -#include /* cli(), *_flags */ -#include /* copy_*_user */ - -#include "smskdefs.h" // page, scatterlist, kmutex -#include "smscoreapi.h" -#include "smstypes.h" - -#include "smscharioctl.h" - -#define SMS_CHR_MAX_Q_LEN 10 // max number of packets allowed to be pending on queue -#define SMSCHAR_NR_DEVS 7 - -typedef struct _smschar_device -{ - struct cdev cdev; //!< Char device structure - kernel's device model representation - - wait_queue_head_t waitq; /* Processes waiting */ - spinlock_t lock; //!< critical section - int pending_count; - struct list_head pending_data; //!< list of pending data - - smscore_buffer_t *currentcb; - - int device_index; - - smscore_device_t *coredev; - smscore_client_t *smsclient; -} smschar_device_t; - -//! Holds the major number of the device node. may be changed at load time. -int smschar_major = 251; - -//! Holds the first minor number of the device node. may be changed at load time. -int smschar_minor = 0; - -// macros that allow the load time parameters change -module_param ( smschar_major, int, S_IRUGO ); -module_param ( smschar_minor, int, S_IRUGO ); - -#ifdef SMSCHAR_DEBUG - - #undef PERROR -# define PERROR(fmt, args...) printk( KERN_INFO "smschar error: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args) - #undef PWARNING -# define PWARNING(fmt, args...) printk( KERN_INFO "smschar warning: line %d- %s(): " fmt,__LINE__, __FUNCTION__, ## args) - #undef PDEBUG /* undef it, just in case */ -# define PDEBUG(fmt, args...) printk( KERN_INFO "smschar - %s(): " fmt, __FUNCTION__, ## args) - -#else /* not debugging: nothing */ - - #define PDEBUG(fmt, args...) - #define PERROR(fmt, args...) - #define PWARNING(fmt, args...) - -#endif - -smschar_device_t smschar_devices[SMSCHAR_NR_DEVS]; -static int g_smschar_inuse = 0; - -/** - * unregisters sms client and returns all queued buffers - * - * @param dev pointer to the client context (smschar parameters block) - * - */ -void smschar_unregister_client(smschar_device_t* dev) -{ - unsigned long flags; - - if (dev->coredev && dev->smsclient) - { - wake_up_interruptible(&dev->waitq); - - spin_lock_irqsave(&dev->lock, flags); - - while (!list_empty(&dev->pending_data)) - { - smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; - list_del(&cb->entry); - - smscore_putbuffer(dev->coredev, cb); - - dev->pending_count --; - } - - if (dev->currentcb) - { - smscore_putbuffer(dev->coredev, dev->currentcb); - dev->currentcb = NULL; - dev->pending_count --; - } - - smscore_unregister_client(dev->smsclient); - dev->smsclient = NULL; - - spin_unlock_irqrestore(&dev->lock, flags); - } -} - -/** - * queues incoming buffers into buffers queue - * - * @param context pointer to the client context (smschar parameters block) - * @param cb pointer to incoming buffer descriptor - * - * @return 0 on success, <0 on queue overflow. - */ -int smschar_onresponse(void *context, smscore_buffer_t *cb) -{ - smschar_device_t *dev = context; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->pending_count > SMS_CHR_MAX_Q_LEN) - { - spin_unlock_irqrestore(&dev->lock, flags); - return -EBUSY; - } - - dev->pending_count ++; - - // if data channel, remove header - if (dev->device_index) - { - cb->size -= sizeof(SmsMsgHdr_ST); - cb->offset += sizeof(SmsMsgHdr_ST); - } - - list_add_tail(&cb->entry, &dev->pending_data); - spin_unlock_irqrestore(&dev->lock, flags); - - if (waitqueue_active(&dev->waitq)) - wake_up_interruptible(&dev->waitq); - - return 0; -} - -/** - * handles device removal event - * - * @param context pointer to the client context (smschar parameters block) - * - */ -void smschar_onremove(void *context) -{ - smschar_device_t *dev = (smschar_device_t *) context; - - smschar_unregister_client(dev); - dev->coredev = NULL; -} - -/** - * registers client associated with the node - * - * @param inode Inode concerned. - * @param file File concerned. - * - * @return 0 on success, <0 on error. - */ -int smschar_open (struct inode *inode, struct file *file) -{ - smschar_device_t *dev = container_of(inode->i_cdev, smschar_device_t, cdev); - int rc = -ENODEV; - - PDEBUG("entering index %d\n", dev->device_index); - - if (dev->coredev) - { - smsclient_params_t params; - - params.initial_id = dev->device_index ? dev->device_index : SMS_HOST_LIB; - params.data_type = dev->device_index ? MSG_SMS_DAB_CHANNEL : 0; - params.onresponse_handler = smschar_onresponse; - params.onremove_handler = smschar_onremove; - params.context = dev; - - rc = smscore_register_client(dev->coredev, ¶ms, &dev->smsclient); - if (!rc) - { - file->private_data = dev; - } - } - - PDEBUG("exiting, rc %d\n", rc); - - return rc; -} - -/** - * unregisters client associated with the node - * - * @param inode Inode concerned. - * @param file File concerned. - * - */ -int smschar_release(struct inode *inode, struct file *file) -{ - smschar_unregister_client(file->private_data); - - PDEBUG("exiting\n"); - - return 0; -} - -/** - * copies data from buffers in incoming queue into a user buffer - * - * @param file File structure. - * @param buf Source buffer. - * @param count Size of source buffer. - * @param f_pos Position in file (ignored). - * - * @return Number of bytes read, or <0 on error. - */ -ssize_t smschar_read ( struct file * file, char __user * buf, size_t count, loff_t * f_pos ) -{ - smschar_device_t *dev = file->private_data; - unsigned long flags; - int copied = 0; - - if (!dev->coredev || !dev->smsclient) - { - PERROR("no client\n"); - return -ENODEV; - } - - while (copied != count) - { - if (0 > wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data))) - { - PERROR("wait_event_interruptible error\n"); - return -ENODEV; - } - - if (!dev->smsclient) - { - PERROR("no client\n"); - return -ENODEV; - } - - spin_lock_irqsave(&dev->lock, flags); - - while (!list_empty(&dev->pending_data) && (copied != count)) - { - smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; - int actual_size = min(((int) count - copied), cb->size); - - copy_to_user(&buf[copied], &((char*)cb->p)[cb->offset], actual_size); - - copied += actual_size; - cb->offset += actual_size; - cb->size -= actual_size; - - if (!cb->size) - { - list_del(&cb->entry); - smscore_putbuffer(dev->coredev, cb); - - dev->pending_count --; - } - } - - spin_unlock_irqrestore(&dev->lock, flags); - } - - return copied; -} - -/** - * sends the buffer to the associated device - * - * @param file File structure. - * @param buf Source buffer. - * @param count Size of source buffer. - * @param f_pos Position in file (ignored). - * - * @return Number of bytes read, or <0 on error. - */ -ssize_t smschar_write(struct file *file, const char __user *buf, size_t count, loff_t *f_pos) -{ - smschar_device_t *dev = file->private_data; - void *buffer; - - if (!dev->smsclient) - { - PERROR("no client\n"); - return -ENODEV; - } - - buffer = kmalloc(ALIGN(count, SMS_ALLOC_ALIGNMENT) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) - { - void *msg_buffer = (void*) SMS_ALIGN_ADDRESS(buffer); - - if (!copy_from_user(msg_buffer, buf, count)) - smsclient_sendrequest(dev->smsclient, msg_buffer, count); - else - count = 0; - - kfree(buffer); - } - - return count; -} - -int smschar_mmap(struct file *file, struct vm_area_struct *vma) -{ - smschar_device_t *dev = file->private_data; - return smscore_map_common_buffer(dev->coredev, vma); -} - -/** - * waits until buffer inserted into a queue. when inserted buffer offset are reported - * to the calling process. previously reported buffer is returned to smscore pool - * - * @param dev pointer to smschar parameters block - * @param touser pointer to a structure that receives incoming buffer offsets - * - * @return 0 on success, <0 on error. - */ -int smschar_wait_get_buffer(smschar_device_t* dev, smschar_buffer_t* touser) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->currentcb) - { - smscore_putbuffer(dev->coredev, dev->currentcb); - dev->currentcb = NULL; - dev->pending_count --; - } - - spin_unlock_irqrestore(&dev->lock, flags); - - rc = wait_event_interruptible(dev->waitq, !list_empty(&dev->pending_data)); - if (rc < 0) - { - PERROR("wait_event_interruptible error\n"); - return rc; - } - - if (!dev->smsclient) - { - PERROR("no client\n"); - return -ENODEV; - } - - spin_lock_irqsave(&dev->lock, flags); - - if (!list_empty(&dev->pending_data)) - { - smscore_buffer_t *cb = (smscore_buffer_t *) dev->pending_data.next; - - touser->offset = cb->offset_in_common + cb->offset; - touser->size = cb->size; - - list_del(&cb->entry); - - dev->currentcb = cb; - } - else - { - touser->offset = 0; - touser->size = 0; - } - - spin_unlock_irqrestore(&dev->lock, flags); - - return 0; -} - -int smschar_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -{ - smschar_device_t *dev = file->private_data; - void __user *up = (void __user *) arg; - - if (!dev->coredev || !dev->smsclient) - { - PERROR("no client\n"); - return -ENODEV; - } - - switch(cmd) - { - case SMSCHAR_SET_DEVICE_MODE: - return smscore_set_device_mode(dev->coredev, (int) arg); - - case SMSCHAR_GET_DEVICE_MODE: - { - if (put_user(smscore_get_device_mode(dev->coredev), (int*) up)) - return -EFAULT; - - break; - } - - case SMSCHAR_GET_BUFFER_SIZE: - { - if (put_user(smscore_get_common_buffer_size(dev->coredev), (int*) up)) - return -EFAULT; - - break; - } - - case SMSCHAR_WAIT_GET_BUFFER: - { - smschar_buffer_t touser; - int rc; - - rc = smschar_wait_get_buffer(dev, &touser); - if (rc < 0) - return rc; - - if (copy_to_user(up, &touser, sizeof(smschar_buffer_t))) - return -EFAULT; - - break; - } - - default: - return -ENOIOCTLCMD; - } - - return 0; -} - -struct file_operations smschar_fops = -{ - .owner = THIS_MODULE, - .read = smschar_read, - .write = smschar_write, - .open = smschar_open, - .release = smschar_release, - .mmap = smschar_mmap, - .ioctl = smschar_ioctl, -}; - -static int smschar_setup_cdev ( smschar_device_t *dev, int index ) -{ - int rc, devno = MKDEV ( smschar_major, smschar_minor + index ); - - cdev_init ( &dev->cdev, &smschar_fops ); - - dev->cdev.owner = THIS_MODULE; - dev->cdev.ops = &smschar_fops; - - kobject_set_name(&dev->cdev.kobj, "Siano_sms%d", index); - - rc = cdev_add ( &dev->cdev, devno, 1 ); - - PDEBUG("exiting %p %d, rc %d\n", dev, index, rc); - - return rc; -} - -/** - * smschar callback that called when device plugged in/out. the function - * register or unregisters char device interface according to plug in/out - * - * @param coredev pointer to device that is being plugged in/out - * @param device pointer to system device object - * @param arrival 1 on plug-on, 0 othewise - * - * @return 0 on success, <0 on error. - */ -int smschar_hotplug(smscore_device_t* coredev, struct device* device, int arrival) -{ - int rc = 0, i; - - PDEBUG("entering %d\n", arrival); - - if (arrival) - { - // currently only 1 instance supported - if (!g_smschar_inuse) - { - /* data notification callbacks assignment */ - memset ( smschar_devices, 0, SMSCHAR_NR_DEVS * sizeof ( smschar_device_t ) ); - - /* Initialize each device. */ - for (i = 0; i < SMSCHAR_NR_DEVS; i++) - { - smschar_setup_cdev ( &smschar_devices[i], i ); - - INIT_LIST_HEAD(&smschar_devices[i].pending_data); - spin_lock_init(&smschar_devices[i].lock); - init_waitqueue_head(&smschar_devices[i].waitq); - - smschar_devices[i].coredev = coredev; - smschar_devices[i].device_index = i; - } - - g_smschar_inuse = 1; - } - } - else - { - // currently only 1 instance supported - if (g_smschar_inuse) - { - /* Get rid of our char dev entries */ - for(i = 0; i < SMSCHAR_NR_DEVS; i++) - cdev_del(&smschar_devices[i].cdev); - - g_smschar_inuse = 0; - } - } - - PDEBUG("exiting, rc %d\n", rc); - - return rc; /* succeed */ -} - -int smschar_initialize(void) -{ - dev_t devno = MKDEV ( smschar_major, smschar_minor ); - int rc; - - if(smschar_major) - { - rc = register_chrdev_region ( devno, SMSCHAR_NR_DEVS, "smschar" ); - } - else - { - rc = alloc_chrdev_region ( &devno, smschar_minor, SMSCHAR_NR_DEVS, "smschar" ); - smschar_major = MAJOR ( devno ); - } - - if (rc < 0) - { - PWARNING ( "smschar: can't get major %d\n", smschar_major ); - return rc; - } - - return smscore_register_hotplug(smschar_hotplug); -} -EXPORT_SYMBOL(smschar_initialize); - -void smschar_terminate(void) -{ - dev_t devno = MKDEV ( smschar_major, smschar_minor ); - - unregister_chrdev_region(devno, SMSCHAR_NR_DEVS); - smscore_unregister_hotplug(smschar_hotplug); -} -EXPORT_SYMBOL(smschar_terminate); diff --git a/drivers/media/mdtv/smschar.h b/drivers/media/mdtv/smschar.h deleted file mode 100644 index 1cd2f32a7f71..000000000000 --- a/drivers/media/mdtv/smschar.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __smschar_h__ -#define __smschar_h__ - -extern int smschar_initialize(void); -extern void smschar_terminate(void); - -#endif // __smschar_h__ diff --git a/drivers/media/mdtv/smscharioctl.h b/drivers/media/mdtv/smscharioctl.h deleted file mode 100644 index e57b89efc499..000000000000 --- a/drivers/media/mdtv/smscharioctl.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __smscharioctl_h__ -#define __smscharioctl_h__ - -#include - -typedef struct _smschar_buffer_t -{ - unsigned long offset; // offset in common buffer (mapped to user space) - int size; -} smschar_buffer_t; - -#define SMSCHAR_SET_DEVICE_MODE _IOW('K', 0, int) -#define SMSCHAR_GET_DEVICE_MODE _IOR('K', 1, int) -#define SMSCHAR_GET_BUFFER_SIZE _IOR('K', 2, int) -#define SMSCHAR_WAIT_GET_BUFFER _IOR('K', 3, smschar_buffer_t) - -#endif // __smscharioctl_h__ diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index a354912391a0..315319483798 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -34,8 +34,6 @@ #include "smscoreapi.h" #include "smstypes.h" -#include "smschar.h" - typedef struct _smscore_device_notifyee { struct list_head entry; @@ -1100,7 +1098,7 @@ int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * int smscore_module_init(void) { - int rc; + int rc = 0; INIT_LIST_HEAD(&g_smscore_notifyees); INIT_LIST_HEAD(&g_smscore_devices); @@ -1109,8 +1107,6 @@ int smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); - rc = smschar_initialize(); - printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); return rc; @@ -1118,8 +1114,6 @@ int smscore_module_init(void) void smscore_module_exit(void) { - smschar_terminate(); - kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { -- cgit v1.2.3 From 955e9ca3cdeae62e8067ede204b5a02dcde6813e Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 15:46:32 -0300 Subject: V4L/DVB (8263): sms1xxx: merge ksyms Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.c | 2 -- drivers/media/mdtv/smscoreapi.h | 21 +++++++++++++++++++++ drivers/media/mdtv/smsdvb.c | 1 - drivers/media/mdtv/smskdefs.h | 21 --------------------- drivers/media/mdtv/smsusb.c | 1 - 5 files changed, 21 insertions(+), 25 deletions(-) delete mode 100644 drivers/media/mdtv/smskdefs.h (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index 315319483798..a30be8301429 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -27,8 +27,6 @@ #include #include -#include "smskdefs.h" // device, page, scatterlist, kmutex - #include #include "smscoreapi.h" diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index a8c025f74eb7..43ebee68f77b 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -1,6 +1,27 @@ #ifndef __smscoreapi_h__ #define __smscoreapi_h__ +/* From sysksyms.h */ + +#include +#include +#include +#include +#include +#include + +#include + +typedef struct mutex kmutex_t; + +#define kmutex_init(_p_) mutex_init(_p_) +#define kmutex_lock(_p_) mutex_lock(_p_) +#define kmutex_trylock(_p_) mutex_trylock(_p_) +#define kmutex_unlock(_p_) mutex_unlock(_p_) + + +/* End sysksyms.h */ + #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index ecba51c8b65b..11a9b0b11cb2 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -6,7 +6,6 @@ #include "dvb_demux.h" #include "dvb_frontend.h" -#include "smskdefs.h" // page, scatterlist, kmutex #include "smscoreapi.h" #include "smstypes.h" diff --git a/drivers/media/mdtv/smskdefs.h b/drivers/media/mdtv/smskdefs.h deleted file mode 100644 index 6874fbcdc7a8..000000000000 --- a/drivers/media/mdtv/smskdefs.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __smskdefs_h__ -#define __smskdefs_h__ - -#include -#include -#include -#include -#include -#include - -#include - -typedef struct mutex kmutex_t; - -#define kmutex_init(_p_) mutex_init(_p_) -#define kmutex_lock(_p_) mutex_lock(_p_) -#define kmutex_trylock(_p_) mutex_trylock(_p_) -#define kmutex_unlock(_p_) mutex_unlock(_p_) - - -#endif // __smskdefs_h__ diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index 43af826b3832..c076c046bf52 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -4,7 +4,6 @@ #include #include -#include "smskdefs.h" // page, scatterlist, kmutex #include "smscoreapi.h" #include "smstypes.h" -- cgit v1.2.3 From 9e4fb5e7122ce67769719e715159baed5e5d7247 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 15:48:54 -0300 Subject: V4L/DVB (8264): sms1xxx: remove smstypes.h Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.c | 1 - drivers/media/mdtv/smscoreapi.h | 361 ++++++++++++++++++++++++++++++++++++++++ drivers/media/mdtv/smsdvb.c | 1 - drivers/media/mdtv/smstypes.h | 361 ---------------------------------------- drivers/media/mdtv/smsusb.c | 1 - 5 files changed, 361 insertions(+), 364 deletions(-) delete mode 100644 drivers/media/mdtv/smstypes.h (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index a30be8301429..715dde034e8a 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -30,7 +30,6 @@ #include #include "smscoreapi.h" -#include "smstypes.h" typedef struct _smscore_device_notifyee { diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index 43ebee68f77b..61fed88cf1c5 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -92,6 +92,367 @@ typedef struct _smsclient_params void *context; } smsclient_params_t; +/* Begin types.h */ + +// GPIO definitions for antenna frequency domain control (SMS8021) +#define SMS_ANTENNA_GPIO_0 1 +#define SMS_ANTENNA_GPIO_1 0 + +#define BW_8_MHZ 0 +#define BW_7_MHZ 1 +#define BW_6_MHZ 2 +#define BW_5_MHZ 3 +#define BW_ISDBT_1SEG 4 +#define BW_ISDBT_3SEG 5 + +#define MSG_HDR_FLAG_SPLIT_MSG 4 + +#define MAX_GPIO_PIN_NUMBER 31 + +#define HIF_TASK 11 +#define SMS_HOST_LIB 150 +#define DVBT_BDA_CONTROL_MSG_ID 201 + +#define SMS_MAX_PAYLOAD_SIZE 240 +#define SMS_TUNE_TIMEOUT 500 + +#define MSG_SMS_GPIO_CONFIG_REQ 507 +#define MSG_SMS_GPIO_CONFIG_RES 508 +#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 +#define MSG_SMS_GPIO_SET_LEVEL_RES 510 +#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 +#define MSG_SMS_GPIO_GET_LEVEL_RES 512 +#define MSG_SMS_RF_TUNE_REQ 561 +#define MSG_SMS_RF_TUNE_RES 562 +#define MSG_SMS_INIT_DEVICE_REQ 578 +#define MSG_SMS_INIT_DEVICE_RES 579 +#define MSG_SMS_ADD_PID_FILTER_REQ 601 +#define MSG_SMS_ADD_PID_FILTER_RES 602 +#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 +#define MSG_SMS_REMOVE_PID_FILTER_RES 604 +#define MSG_SMS_DAB_CHANNEL 607 +#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 +#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 +#define MSG_SMS_GET_STATISTICS_REQ 615 +#define MSG_SMS_GET_STATISTICS_RES 616 +#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 +#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 +#define MSG_SMS_GET_STATISTICS_EX_REQ 653 +#define MSG_SMS_GET_STATISTICS_EX_RES 654 +#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 +#define MSG_SMS_DATA_DOWNLOAD_REQ 660 +#define MSG_SMS_DATA_DOWNLOAD_RES 661 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 +#define MSG_SMS_GET_VERSION_EX_REQ 668 +#define MSG_SMS_GET_VERSION_EX_RES 669 +#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 +#define MSG_SMS_I2C_SET_FREQ_REQ 685 +#define MSG_SMS_GENERIC_I2C_REQ 687 +#define MSG_SMS_GENERIC_I2C_RES 688 +#define MSG_SMS_DVBT_BDA_DATA 693 +#define MSG_SW_RELOAD_REQ 697 +#define MSG_SMS_DATA_MSG 699 +#define MSG_SW_RELOAD_START_REQ 702 +#define MSG_SW_RELOAD_START_RES 703 +#define MSG_SW_RELOAD_EXEC_REQ 704 +#define MSG_SW_RELOAD_EXEC_RES 705 +#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 +#define MSG_SMS_ISDBT_TUNE_REQ 776 +#define MSG_SMS_ISDBT_TUNE_RES 777 + +#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ + (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ + (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ +} while (0) +#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) + +typedef enum +{ + DEVICE_MODE_NONE = -1, + DEVICE_MODE_DVBT = 0, + DEVICE_MODE_DVBH, + DEVICE_MODE_DAB_TDMB, + DEVICE_MODE_DAB_TDMB_DABIP, + DEVICE_MODE_DVBT_BDA, + DEVICE_MODE_ISDBT, + DEVICE_MODE_ISDBT_BDA, + DEVICE_MODE_CMMB, + DEVICE_MODE_RAW_TUNER, + DEVICE_MODE_MAX, +} SMS_DEVICE_MODE; + +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef int INT32; + +typedef struct SmsMsgHdr_S +{ + UINT16 msgType; + UINT8 msgSrcId; + UINT8 msgDstId; + UINT16 msgLength; // Length is of the entire message, including header + UINT16 msgFlags; +} SmsMsgHdr_ST; + +typedef struct SmsMsgData_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 msgData[1]; +} SmsMsgData_ST; + +typedef struct SmsDataDownload_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 MemAddr; + UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; +} SmsDataDownload_ST; + +typedef struct SmsVersionRes_S +{ + SmsMsgHdr_ST xMsgHeader; + + UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" + UINT8 Step; // 0 - Step A + UINT8 MetalFix; // 0 - Metal 0 + + UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E + UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols + + UINT8 VersionMajor; + UINT8 VersionMinor; + UINT8 VersionPatch; + UINT8 VersionFieldPatch; + + UINT8 RomVersionMajor; + UINT8 RomVersionMinor; + UINT8 RomVersionPatch; + UINT8 RomVersionFieldPatch; + + UINT8 TextLabel[34]; +} SmsVersionRes_ST; + +typedef struct SmsFirmware_S +{ + UINT32 CheckSum; + UINT32 Length; + UINT32 StartAddress; + UINT8 Payload[1]; +} SmsFirmware_ST; + +typedef struct SMSHOSTLIB_STATISTICS_S +{ + UINT32 Reserved; //!< Reserved + + /// Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + /// Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + /// Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H + UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos + UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H + UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H + UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H + + /// Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding + /// Common params + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + + /// Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + + /// DAB/T-DMB + UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] + + /// DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + +} SMSHOSTLIB_STATISTICS_ST; + +typedef struct +{ + UINT32 RequestResult; + + SMSHOSTLIB_STATISTICS_ST Stat; + + // Split the calc of the SNR in DAB + UINT32 Signal; //!< dB + UINT32 Noise; //!< dB + +} SmsMsgStatisticsInfo_ST; + +typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S +{ + // Per-layer information + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist + UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count + UINT32 BERBitCount; //!< Post Viterbi Total Bits Count + UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist + UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist + UINT32 TMCCErrors; //!< TMCC errors +} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in Hz + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 TransmissionMode; //!< ISDB-T transmission mode + UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) + UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise + UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network + + // Per-layer information + // Layers A, B and C + SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_ISDBT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_DVB_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET + UINT32 TransmissionMode; //!< FFT mode carriers in Kilos + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET + + // Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H + UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received + + // DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_DVB_ST; + +typedef struct SMSHOSTLIB_GPIO_CONFIG_S +{ + UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 + UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 + UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 + UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 + UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 +} SMSHOSTLIB_GPIO_CONFIG_ST; + +typedef struct SMSHOSTLIB_I2C_REQ_S +{ + UINT32 DeviceAddress; // I2c device address + UINT32 WriteCount; // number of bytes to write + UINT32 ReadCount; // number of bytes to read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_REQ_ST; + +typedef struct SMSHOSTLIB_I2C_RES_S +{ + UINT32 Status; // non-zero value in case of failure + UINT32 ReadCount; // number of bytes read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_RES_ST; + +/* End types.h */ + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index 11a9b0b11cb2..e941a0b97f2c 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -7,7 +7,6 @@ #include "dvb_frontend.h" #include "smscoreapi.h" -#include "smstypes.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); diff --git a/drivers/media/mdtv/smstypes.h b/drivers/media/mdtv/smstypes.h deleted file mode 100644 index 011cd904d0f1..000000000000 --- a/drivers/media/mdtv/smstypes.h +++ /dev/null @@ -1,361 +0,0 @@ -#ifndef __smstypes_h__ -#define __smstypes_h__ - -// GPIO definitions for antenna frequency domain control (SMS8021) -#define SMS_ANTENNA_GPIO_0 1 -#define SMS_ANTENNA_GPIO_1 0 - -#define BW_8_MHZ 0 -#define BW_7_MHZ 1 -#define BW_6_MHZ 2 -#define BW_5_MHZ 3 -#define BW_ISDBT_1SEG 4 -#define BW_ISDBT_3SEG 5 - -#define MSG_HDR_FLAG_SPLIT_MSG 4 - -#define MAX_GPIO_PIN_NUMBER 31 - -#define HIF_TASK 11 -#define SMS_HOST_LIB 150 -#define DVBT_BDA_CONTROL_MSG_ID 201 - -#define SMS_MAX_PAYLOAD_SIZE 240 -#define SMS_TUNE_TIMEOUT 500 - -#define MSG_SMS_GPIO_CONFIG_REQ 507 -#define MSG_SMS_GPIO_CONFIG_RES 508 -#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 -#define MSG_SMS_GPIO_SET_LEVEL_RES 510 -#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 -#define MSG_SMS_GPIO_GET_LEVEL_RES 512 -#define MSG_SMS_RF_TUNE_REQ 561 -#define MSG_SMS_RF_TUNE_RES 562 -#define MSG_SMS_INIT_DEVICE_REQ 578 -#define MSG_SMS_INIT_DEVICE_RES 579 -#define MSG_SMS_ADD_PID_FILTER_REQ 601 -#define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_GET_STATISTICS_RES 616 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_GET_STATISTICS_EX_REQ 653 -#define MSG_SMS_GET_STATISTICS_EX_RES 654 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 -#define MSG_SMS_DATA_DOWNLOAD_REQ 660 -#define MSG_SMS_DATA_DOWNLOAD_RES 661 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 -#define MSG_SMS_GET_VERSION_EX_REQ 668 -#define MSG_SMS_GET_VERSION_EX_RES 669 -#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 -#define MSG_SMS_I2C_SET_FREQ_REQ 685 -#define MSG_SMS_GENERIC_I2C_REQ 687 -#define MSG_SMS_GENERIC_I2C_RES 688 -#define MSG_SMS_DVBT_BDA_DATA 693 -#define MSG_SW_RELOAD_REQ 697 -#define MSG_SMS_DATA_MSG 699 -#define MSG_SW_RELOAD_START_REQ 702 -#define MSG_SW_RELOAD_START_RES 703 -#define MSG_SW_RELOAD_EXEC_REQ 704 -#define MSG_SW_RELOAD_EXEC_RES 705 -#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 -#define MSG_SMS_ISDBT_TUNE_REQ 776 -#define MSG_SMS_ISDBT_TUNE_RES 777 - -#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ - (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ - (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ -} while (0) -#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) - -typedef enum -{ - DEVICE_MODE_NONE = -1, - DEVICE_MODE_DVBT = 0, - DEVICE_MODE_DVBH, - DEVICE_MODE_DAB_TDMB, - DEVICE_MODE_DAB_TDMB_DABIP, - DEVICE_MODE_DVBT_BDA, - DEVICE_MODE_ISDBT, - DEVICE_MODE_ISDBT_BDA, - DEVICE_MODE_CMMB, - DEVICE_MODE_RAW_TUNER, - DEVICE_MODE_MAX, -} SMS_DEVICE_MODE; - -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -typedef int INT32; - -typedef struct SmsMsgHdr_S -{ - UINT16 msgType; - UINT8 msgSrcId; - UINT8 msgDstId; - UINT16 msgLength; // Length is of the entire message, including header - UINT16 msgFlags; -} SmsMsgHdr_ST; - -typedef struct SmsMsgData_S -{ - SmsMsgHdr_ST xMsgHeader; - UINT32 msgData[1]; -} SmsMsgData_ST; - -typedef struct SmsDataDownload_S -{ - SmsMsgHdr_ST xMsgHeader; - UINT32 MemAddr; - UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; -} SmsDataDownload_ST; - -typedef struct SmsVersionRes_S -{ - SmsMsgHdr_ST xMsgHeader; - - UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" - UINT8 Step; // 0 - Step A - UINT8 MetalFix; // 0 - Metal 0 - - UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E - UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols - - UINT8 VersionMajor; - UINT8 VersionMinor; - UINT8 VersionPatch; - UINT8 VersionFieldPatch; - - UINT8 RomVersionMajor; - UINT8 RomVersionMinor; - UINT8 RomVersionPatch; - UINT8 RomVersionFieldPatch; - - UINT8 TextLabel[34]; -} SmsVersionRes_ST; - -typedef struct SmsFirmware_S -{ - UINT32 CheckSum; - UINT32 Length; - UINT32 StartAddress; - UINT8 Payload[1]; -} SmsFirmware_ST; - -typedef struct SMSHOSTLIB_STATISTICS_S -{ - UINT32 Reserved; //!< Reserved - - /// Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - /// Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - /// Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H - UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos - UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H - UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H - UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H - - /// Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding - /// Common params - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - - /// Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - - /// DAB/T-DMB - UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] - - /// DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered - -} SMSHOSTLIB_STATISTICS_ST; - -typedef struct -{ - UINT32 RequestResult; - - SMSHOSTLIB_STATISTICS_ST Stat; - - // Split the calc of the SNR in DAB - UINT32 Signal; //!< dB - UINT32 Noise; //!< dB - -} SmsMsgStatisticsInfo_ST; - -typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S -{ - // Per-layer information - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist - UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count - UINT32 BERBitCount; //!< Post Viterbi Total Bits Count - UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist - UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist - UINT32 TMCCErrors; //!< TMCC errors -} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S -{ - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in Hz - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 TransmissionMode; //!< ISDB-T transmission mode - UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) - UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise - UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network - - // Per-layer information - // Layers A, B and C - SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - -} SMSHOSTLIB_STATISTICS_ISDBT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_DVB_S -{ - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET - UINT32 TransmissionMode; //!< FFT mode carriers in Kilos - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET - - // Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H - UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received - - // DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered - UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - -} SMSHOSTLIB_STATISTICS_DVB_ST; - -typedef struct SMSHOSTLIB_GPIO_CONFIG_S -{ - UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 - UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 - UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 - UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 - UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 -} SMSHOSTLIB_GPIO_CONFIG_ST; - -typedef struct SMSHOSTLIB_I2C_REQ_S -{ - UINT32 DeviceAddress; // I2c device address - UINT32 WriteCount; // number of bytes to write - UINT32 ReadCount; // number of bytes to read - UINT8 Data[1]; -} SMSHOSTLIB_I2C_REQ_ST; - -typedef struct SMSHOSTLIB_I2C_RES_S -{ - UINT32 Status; // non-zero value in case of failure - UINT32 ReadCount; // number of bytes read - UINT8 Data[1]; -} SMSHOSTLIB_I2C_RES_ST; - -#endif // __smstypes_h__ diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index c076c046bf52..1da0209fc56f 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -5,7 +5,6 @@ #include #include "smscoreapi.h" -#include "smstypes.h" #define USB_VID_SIANO 0x187f #define USB_PID_0010 0x0010 -- cgit v1.2.3 From 7a19598c75660b6d4464d291f8e99a91fd7afc4a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 16:43:04 -0300 Subject: V4L/DVB (8265): sms1xxx: Kconfig / Makefile cleanups Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/Kconfig | 22 +--------------------- drivers/media/mdtv/Makefile | 4 +--- 2 files changed, 2 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/Kconfig b/drivers/media/mdtv/Kconfig index f3bae45000d1..a7faca0b7020 100644 --- a/drivers/media/mdtv/Kconfig +++ b/drivers/media/mdtv/Kconfig @@ -2,35 +2,15 @@ # Mobile Digital TV device configuration # -config MDTV_SIANO_STELLAR_COMMON - tristate "Siano SMS10xx adapter" - default m - ---help--- - Choose Y here if you have SMS10xx chipset. - - In order to control the SMS10xx chipset you will need SMS Host Control library. - - Further documentation on this driver can be found on the WWW at - . - - To compile this driver as a module, choose M here: the - modules will be called smschar and smsnet. - config MDTV_SIANO_STELLAR_USB tristate "Siano SMS10xx USB dongle support" - depends on MDTV_SIANO_STELLAR_COMMON default m ---help--- Choose Y here if you have USB dongle with SMS10xx chipset. - In order to control the SMS10xx chipset you will need SMS Host Control library. - Further documentation on this driver can be found on the WWW at . To compile this driver as a module, choose M here: the - module will be called smsusb. - - - + modules will be called smschar and smsnet. diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile index 0af1b3827821..e3d727d0a3ce 100644 --- a/drivers/media/mdtv/Makefile +++ b/drivers/media/mdtv/Makefile @@ -4,6 +4,4 @@ smscore-objs := smscoreapi.o -obj-$(CONFIG_MDTV_SIANO_STELLAR_COMMON) += smscore.o -obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsusb.o -obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smsdvb.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smscore.o smsusb.o smsdvb.o -- cgit v1.2.3 From 3dd243787017e40c66ae54cf590ea513a110c51d Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:01:02 -0300 Subject: V4L/DVB (8266): sms1xxx: merge modules Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.h | 31 +++++++++++++++++++++ drivers/media/mdtv/smsdvb.c | 61 ----------------------------------------- drivers/media/mdtv/smsusb.c | 20 ++++++++++++++ 3 files changed, 51 insertions(+), 61 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index 61fed88cf1c5..5c1369365c75 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -1,6 +1,11 @@ #ifndef __smscoreapi_h__ #define __smscoreapi_h__ +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + /* From sysksyms.h */ #include @@ -453,6 +458,28 @@ typedef struct SMSHOSTLIB_I2C_RES_S /* End types.h */ +typedef struct _smsdvb_client +{ + struct list_head entry; + + smscore_device_t *coredev; + smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_signal_strength; + + struct completion tune_done, stat_done; + + // todo: save freq/band instead whole struct + struct dvb_frontend_parameters fe_params; + +} smsdvb_client_t; + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -480,4 +507,8 @@ extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_s extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); +/* smsdvb.c */ +int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival); +void smsdvb_unregister_client(smsdvb_client_t* client); + #endif // __smscoreapi_h__ diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index e941a0b97f2c..166f218ca5c1 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -1,37 +1,10 @@ #include #include -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - #include "smscoreapi.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -typedef struct _smsdvb_client -{ - struct list_head entry; - - smscore_device_t *coredev; - smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_signal_strength; - - struct completion tune_done, stat_done; - - // todo: save freq/band instead whole struct - struct dvb_frontend_parameters fe_params; - -} smsdvb_client_t; - struct list_head g_smsdvb_clients; kmutex_t g_smsdvb_clientslock; @@ -402,37 +375,3 @@ adapter_error: return rc; } -int smsdvb_module_init(void) -{ - int rc; - - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - rc = smscore_register_hotplug(smsdvb_hotplug); - - printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); - - return rc; -} - -void smsdvb_module_exit(void) -{ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); - - kmutex_unlock(&g_smsdvb_clientslock); - - printk(KERN_INFO "%s\n", __FUNCTION__); -} - -module_init(smsdvb_module_init); -module_exit(smsdvb_module_exit); - -MODULE_DESCRIPTION("smsdvb dvb-api module"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index 1da0209fc56f..11c471ad6326 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -401,12 +401,21 @@ static struct usb_driver smsusb_driver = { .id_table = smsusb_id_table, }; +extern struct list_head g_smsdvb_clients; +kmutex_t g_smsdvb_clientslock; + int smsusb_module_init(void) { int rc = usb_register(&smsusb_driver); if (rc) printk(KERN_INFO "usb_register failed. Error number %d\n", rc); + /* Bring up the dvb componenets */ + INIT_LIST_HEAD(&g_smsdvb_clients); + kmutex_init(&g_smsdvb_clientslock); + + rc = smscore_register_hotplug(smsdvb_hotplug); + printk(KERN_INFO "%s\n", __FUNCTION__); return rc; @@ -414,6 +423,17 @@ int smsusb_module_init(void) void smsusb_module_exit(void) { + /* Tear down the DVB components */ + smscore_unregister_hotplug(smsdvb_hotplug); + + kmutex_lock(&g_smsdvb_clientslock); + + while (!list_empty(&g_smsdvb_clients)) + smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); + + kmutex_unlock(&g_smsdvb_clientslock); + + /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); printk(KERN_INFO "%s\n", __FUNCTION__); } -- cgit v1.2.3 From 159ed4bbc394bb3e547eb64fdd3a59141ced131a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:01:42 -0300 Subject: V4L/DVB (8267): sms1xxx: Makefile cleanup Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile index e3d727d0a3ce..16b9c488c9d1 100644 --- a/drivers/media/mdtv/Makefile +++ b/drivers/media/mdtv/Makefile @@ -1,7 +1,10 @@ -# -# Makefile for the kernel MDTV driver -# +smscore-objs := smscoreapi.o smsusb.o smsdvb.o -smscore-objs := smscoreapi.o +obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smscore.o + +EXTRA_CFLAGS += -Idrivers/media/video +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +EXTRA_CFLAGS += -Idrivers/media/dvb/frontends + +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) -obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smscore.o smsusb.o smsdvb.o -- cgit v1.2.3 From eae55660fc4a7f17f0f87458d8ada2b51b1833c1 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:04:36 -0300 Subject: V4L/DVB (8268): sms1xxx: usb cleanup Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.c | 13 +++++++++++++ drivers/media/mdtv/smscoreapi.h | 8 ++++++-- drivers/media/mdtv/smsdvb.c | 27 +++++++++++++++++++++++++++ drivers/media/mdtv/smsusb.c | 30 ++---------------------------- 4 files changed, 48 insertions(+), 30 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index 715dde034e8a..6d21ff391227 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -1104,6 +1104,12 @@ int smscore_module_init(void) INIT_LIST_HEAD(&g_smscore_registry); kmutex_init(&g_smscore_registrylock); + /* USB Register */ + rc = smsusb_register(); + + /* DVB Register */ + rc = smsdvb_register(); + printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); return rc; @@ -1111,6 +1117,7 @@ int smscore_module_init(void) void smscore_module_exit(void) { + kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { @@ -1131,6 +1138,12 @@ void smscore_module_exit(void) } kmutex_unlock(&g_smscore_registrylock); + /* DVB UnRegister */ + smsdvb_unregister(); + + /* Unregister USB */ + smsusb_unregister(); + printk(KERN_INFO "%s\n", __FUNCTION__); } diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index 5c1369365c75..9f367f2cdf3c 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -508,7 +508,11 @@ extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); /* smsdvb.c */ -int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival); -void smsdvb_unregister_client(smsdvb_client_t* client); +int smsdvb_register(void); +void smsdvb_unregister(void); + +/* smsusb.c */ +int smsusb_register(void); +void smsusb_unregister(void); #endif // __smscoreapi_h__ diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index 166f218ca5c1..7a1e6c33b12c 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -375,3 +375,30 @@ adapter_error: return rc; } +int smsdvb_register(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smsdvb_clients); + kmutex_init(&g_smsdvb_clientslock); + + rc = smscore_register_hotplug(smsdvb_hotplug); + + printk(KERN_INFO "%s\n", __FUNCTION__); + + return rc; +} + +void smsdvb_unregister(void) +{ + smscore_unregister_hotplug(smsdvb_hotplug); + + kmutex_lock(&g_smsdvb_clientslock); + + while (!list_empty(&g_smsdvb_clients)) + smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); + + kmutex_unlock(&g_smsdvb_clientslock); + +} + diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index 11c471ad6326..277faf142ade 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -401,46 +400,21 @@ static struct usb_driver smsusb_driver = { .id_table = smsusb_id_table, }; -extern struct list_head g_smsdvb_clients; -kmutex_t g_smsdvb_clientslock; - -int smsusb_module_init(void) +int smsusb_register(void) { int rc = usb_register(&smsusb_driver); if (rc) printk(KERN_INFO "usb_register failed. Error number %d\n", rc); - /* Bring up the dvb componenets */ - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - rc = smscore_register_hotplug(smsdvb_hotplug); - printk(KERN_INFO "%s\n", __FUNCTION__); return rc; } -void smsusb_module_exit(void) +void smsusb_unregister(void) { - /* Tear down the DVB components */ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); - - kmutex_unlock(&g_smsdvb_clientslock); - /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); printk(KERN_INFO "%s\n", __FUNCTION__); } -module_init(smsusb_module_init); -module_exit(smsusb_module_exit); - -MODULE_DESCRIPTION("smsusb"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 8d4f9d0e0bb8b8191b525bd41eddadaf831e47ef Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:05:26 -0300 Subject: V4L/DVB (8269): sms1xxx: copyrights Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.c | 22 ++++++++++++++++++++++ drivers/media/mdtv/smscoreapi.h | 21 +++++++++++++++++++++ drivers/media/mdtv/smsdvb.c | 21 +++++++++++++++++++++ drivers/media/mdtv/smsusb.c | 21 +++++++++++++++++++++ 4 files changed, 85 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index 6d21ff391227..524818f409f1 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -1,3 +1,25 @@ + +/* + * Driver for the Siano SMS10xx USB dongle + * + * Copyright (c) 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /*! \file smscoreapi.c diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index 9f367f2cdf3c..5e06ade04f43 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -1,3 +1,24 @@ +/* + * Driver for the Siano SMS10xx USB dongle + * + * Copyright (c) 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #ifndef __smscoreapi_h__ #define __smscoreapi_h__ diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c index 7a1e6c33b12c..f56658c5599d 100644 --- a/drivers/media/mdtv/smsdvb.c +++ b/drivers/media/mdtv/smsdvb.c @@ -1,3 +1,24 @@ +/* + * Driver for the Siano SMS10xx USB dongle + * + * Copyright (c) 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index 277faf142ade..07c72f057387 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -1,3 +1,24 @@ +/* + * Driver for the Siano SMS10xx USB dongle + * + * Copyright (c) 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include #include #include -- cgit v1.2.3 From 19d703da05de6495adfc0ec9aec927d2fce99af6 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:06:41 -0300 Subject: V4L/DVB (8270): sms1xxx: header include cleanups and unexport symbols Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smscoreapi.c | 18 ------------------ drivers/media/mdtv/smscoreapi.h | 18 +++++------------- 2 files changed, 5 insertions(+), 31 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c index 524818f409f1..b261fe2cee5e 100644 --- a/drivers/media/mdtv/smscoreapi.c +++ b/drivers/media/mdtv/smscoreapi.c @@ -1176,21 +1176,3 @@ MODULE_DESCRIPTION("smscore"); MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(smscore_registry_setmode); -EXPORT_SYMBOL(smscore_registry_getmode); -EXPORT_SYMBOL(smscore_register_hotplug); -EXPORT_SYMBOL(smscore_unregister_hotplug); -EXPORT_SYMBOL(smscore_register_device); -EXPORT_SYMBOL(smscore_unregister_device); -EXPORT_SYMBOL(smscore_start_device); -EXPORT_SYMBOL(smscore_load_firmware); -EXPORT_SYMBOL(smscore_set_device_mode); -EXPORT_SYMBOL(smscore_get_device_mode); -EXPORT_SYMBOL(smscore_register_client); -EXPORT_SYMBOL(smscore_unregister_client); -EXPORT_SYMBOL(smsclient_sendrequest); -EXPORT_SYMBOL(smscore_onresponse); -EXPORT_SYMBOL(smscore_get_common_buffer_size); -EXPORT_SYMBOL(smscore_map_common_buffer); -EXPORT_SYMBOL(smscore_getbuffer); -EXPORT_SYMBOL(smscore_putbuffer); diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h index 5e06ade04f43..53c1d35da68f 100644 --- a/drivers/media/mdtv/smscoreapi.h +++ b/drivers/media/mdtv/smscoreapi.h @@ -22,13 +22,6 @@ #ifndef __smscoreapi_h__ #define __smscoreapi_h__ -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - -/* From sysksyms.h */ - #include #include #include @@ -36,6 +29,11 @@ #include #include +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + #include typedef struct mutex kmutex_t; @@ -46,8 +44,6 @@ typedef struct mutex kmutex_t; #define kmutex_unlock(_p_) mutex_unlock(_p_) -/* End sysksyms.h */ - #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif @@ -118,8 +114,6 @@ typedef struct _smsclient_params void *context; } smsclient_params_t; -/* Begin types.h */ - // GPIO definitions for antenna frequency domain control (SMS8021) #define SMS_ANTENNA_GPIO_0 1 #define SMS_ANTENNA_GPIO_1 0 @@ -477,8 +471,6 @@ typedef struct SMSHOSTLIB_I2C_RES_S UINT8 Data[1]; } SMSHOSTLIB_I2C_RES_ST; -/* End types.h */ - typedef struct _smsdvb_client { struct list_head entry; -- cgit v1.2.3 From 7d18d2e91b5495ed0b99c83d595a56e25521a111 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 22 May 2008 18:07:39 -0300 Subject: V4L/DVB (8271): sms1xxx: usbvid table Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/mdtv/smsusb.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c index 07c72f057387..c0f77a328ca9 100644 --- a/drivers/media/mdtv/smsusb.c +++ b/drivers/media/mdtv/smsusb.c @@ -26,11 +26,6 @@ #include "smscoreapi.h" -#define USB_VID_SIANO 0x187f -#define USB_PID_0010 0x0010 -#define USB_PID_0100 0x0100 -#define USB_PID_0200 0x0200 - #define USB1_BUFFER_SIZE 0x1000 #define USB2_BUFFER_SIZE 0x4000 @@ -58,14 +53,6 @@ typedef struct _smsusb_device int buffer_size; } *psmsusb_device_t; -static struct usb_device_id smsusb_id_table [] = { - { USB_DEVICE(USB_VID_SIANO, USB_PID_0010) }, - { USB_DEVICE(USB_VID_SIANO, USB_PID_0100) }, - { USB_DEVICE(USB_VID_SIANO, USB_PID_0200) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, smsusb_id_table); - int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb); void smsusb_onresponse(struct urb *urb) @@ -315,7 +302,7 @@ int smsusb_init_device(struct usb_interface *intf) switch (dev->udev->descriptor.idProduct) { - case USB_PID_0100: + case 0x100: dev->buffer_size = USB1_BUFFER_SIZE; params.setmode_handler = smsusb1_setmode; @@ -414,6 +401,14 @@ void smsusb_disconnect(struct usb_interface *intf) smsusb_term_device(intf); } +static struct usb_device_id smsusb_id_table [] = { + { USB_DEVICE(0x187F, 0x0010) }, + { USB_DEVICE(0x187F, 0x0100) }, + { USB_DEVICE(0x187F, 0x0200) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, smsusb_id_table); + static struct usb_driver smsusb_driver = { .name = "smsusb", .probe = smsusb_probe, -- cgit v1.2.3 From 854470606070d91955f03a7dca3a8024fc2a2540 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 22 May 2008 18:29:20 -0300 Subject: V4L/DVB (8272): sms1xxx: move driver from media/mdtv/ to media/dvb/siano/ Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/Kconfig | 1 + drivers/media/dvb/Makefile | 2 +- drivers/media/dvb/siano/Kconfig | 16 + drivers/media/dvb/siano/Makefile | 8 + drivers/media/dvb/siano/smscoreapi.c | 1158 +++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/smscoreapi.h | 531 +++++++++++++++ drivers/media/dvb/siano/smsdvb.c | 425 ++++++++++++ drivers/media/dvb/siano/smsusb.c | 436 +++++++++++++ drivers/media/mdtv/Kconfig | 16 - drivers/media/mdtv/Makefile | 10 - drivers/media/mdtv/smscoreapi.c | 1178 ---------------------------------- drivers/media/mdtv/smscoreapi.h | 531 --------------- drivers/media/mdtv/smsdvb.c | 425 ------------ drivers/media/mdtv/smsusb.c | 436 ------------- 14 files changed, 2576 insertions(+), 2597 deletions(-) create mode 100644 drivers/media/dvb/siano/Kconfig create mode 100644 drivers/media/dvb/siano/Makefile create mode 100644 drivers/media/dvb/siano/smscoreapi.c create mode 100644 drivers/media/dvb/siano/smscoreapi.h create mode 100644 drivers/media/dvb/siano/smsdvb.c create mode 100644 drivers/media/dvb/siano/smsusb.c delete mode 100644 drivers/media/mdtv/Kconfig delete mode 100644 drivers/media/mdtv/Makefile delete mode 100644 drivers/media/mdtv/smscoreapi.c delete mode 100644 drivers/media/mdtv/smscoreapi.h delete mode 100644 drivers/media/mdtv/smsdvb.c delete mode 100644 drivers/media/mdtv/smsusb.c (limited to 'drivers/media') diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 7b21b49f1945..8bc1445bd33b 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -21,6 +21,7 @@ source "drivers/media/dvb/dvb-usb/Kconfig" source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" source "drivers/media/dvb/cinergyT2/Kconfig" +source "drivers/media/dvb/siano/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" depends on DVB_CORE && (PCI || USB) && I2C diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index a7ad0841e6fc..d6ba4d195201 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -2,4 +2,4 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ +obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/ diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig new file mode 100644 index 000000000000..878d48c1cfc0 --- /dev/null +++ b/drivers/media/dvb/siano/Kconfig @@ -0,0 +1,16 @@ +# +# Siano Mobile Silicon Digital TV device configuration +# + +config DVB_SIANO_SMS1XXX + tristate "Siano SMS1xxx USB dongle support" + depends on DVB_CORE && USB + ---help--- + Choose Y here if you have USB dongle with SMS1xxx chipset. + + Further documentation on this driver can be found on the WWW at + . + + To compile this driver as a module, choose M here: the + module will be called sms1xxx. + diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile new file mode 100644 index 000000000000..e549c4e2bbe2 --- /dev/null +++ b/drivers/media/dvb/siano/Makefile @@ -0,0 +1,8 @@ +sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o + +obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o + +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core + +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) + diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c new file mode 100644 index 000000000000..d3ba1fcde54a --- /dev/null +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -0,0 +1,1158 @@ +/* + * Siano core API module + * + * This file contains implementation for the interface to sms core component + * + * author: Anatoly Greenblat + * + * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "smscoreapi.h" + +typedef struct _smscore_device_notifyee +{ + struct list_head entry; + hotplug_t hotplug; +} smscore_device_notifyee_t; + +typedef struct _smscore_client +{ + struct list_head entry; + smscore_device_t *coredev; + + void *context; + + int data_type; + + onresponse_t onresponse_handler; + onremove_t onremove_handler; +} *psmscore_client_t; + +typedef struct _smscore_subclient +{ + struct list_head entry; + smscore_client_t *client; + + int id; +} smscore_subclient_t; + +typedef struct _smscore_device +{ + struct list_head entry; + + struct list_head clients; + struct list_head subclients; + spinlock_t clientslock; + + struct list_head buffers; + spinlock_t bufferslock; + int num_buffers; + + void *common_buffer; + int common_buffer_size; + dma_addr_t common_buffer_phys; + + void *context; + struct device *device; + + char devpath[32]; + unsigned long device_flags; + + setmode_t setmode_handler; + detectmode_t detectmode_handler; + sendrequest_t sendrequest_handler; + preload_t preload_handler; + postload_t postload_handler; + + int mode, modes_supported; + + struct completion version_ex_done, data_download_done, trigger_done; + struct completion init_device_done, reload_start_done, resume_done; +} *psmscore_device_t; + +typedef struct _smscore_registry_entry +{ + struct list_head entry; + char devpath[32]; + int mode; +} smscore_registry_entry_t; + +struct list_head g_smscore_notifyees; +struct list_head g_smscore_devices; +kmutex_t g_smscore_deviceslock; + +struct list_head g_smscore_registry; +kmutex_t g_smscore_registrylock; + +static int default_mode = 1; +module_param(default_mode, int, 0644); +MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); + +int smscore_registry_getmode(char* devpath) +{ + smscore_registry_entry_t *entry; + struct list_head *next; + + kmutex_lock(&g_smscore_registrylock); + + for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) + { + entry = (smscore_registry_entry_t *) next; + + if (!strcmp(entry->devpath, devpath)) + { + kmutex_unlock(&g_smscore_registrylock); + return entry->mode; + } + } + + entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); + if (entry) + { + entry->mode = default_mode; + strcpy(entry->devpath, devpath); + + list_add(&entry->entry, &g_smscore_registry); + } + + kmutex_unlock(&g_smscore_registrylock); + + return default_mode; +} + +void smscore_registry_setmode(char* devpath, int mode) +{ + smscore_registry_entry_t *entry; + struct list_head *next; + + kmutex_lock(&g_smscore_registrylock); + + for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) + { + entry = (smscore_registry_entry_t *) next; + + if (!strcmp(entry->devpath, devpath)) + { + entry->mode = mode; + break; + } + } + + kmutex_unlock(&g_smscore_registrylock); +} + + +void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock) +{ + unsigned long flags; + + spin_lock_irqsave(lock, flags); + + list_add(new, head); + + spin_unlock_irqrestore(lock, flags); +} + +/** + * register a client callback that called when device plugged in/unplugged + * NOTE: if devices exist callback is called immediately for each device + * + * @param hotplug callback + * + * @return 0 on success, <0 on error. + */ +int smscore_register_hotplug(hotplug_t hotplug) +{ + smscore_device_notifyee_t *notifyee; + struct list_head *next, *first; + int rc = 0; + + kmutex_lock(&g_smscore_deviceslock); + + notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); + if (notifyee) + { + // now notify callback about existing devices + first = &g_smscore_devices; + for (next = first->next; next != first && !rc; next = next->next) + { + smscore_device_t *coredev = (smscore_device_t *) next; + rc = hotplug(coredev, coredev->device, 1); + } + + if (rc >= 0) + { + notifyee->hotplug = hotplug; + list_add(¬ifyee->entry, &g_smscore_notifyees); + } + else + kfree(notifyee); + } + else + rc = -ENOMEM; + + kmutex_unlock(&g_smscore_deviceslock); + + return rc; +} + +/** + * unregister a client callback that called when device plugged in/unplugged + * + * @param hotplug callback + * + */ +void smscore_unregister_hotplug(hotplug_t hotplug) +{ + struct list_head *next, *first; + + kmutex_lock(&g_smscore_deviceslock); + + first = &g_smscore_notifyees; + + for (next = first->next; next != first;) + { + smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next; + next = next->next; + + if (notifyee->hotplug == hotplug) + { + list_del(¬ifyee->entry); + kfree(notifyee); + } + } + + kmutex_unlock(&g_smscore_deviceslock); +} + +void smscore_notify_clients(smscore_device_t *coredev) +{ + smscore_client_t* client; + + // the client must call smscore_unregister_client from remove handler + while (!list_empty(&coredev->clients)) + { + client = (smscore_client_t *) coredev->clients.next; + client->onremove_handler(client->context); + } +} + +int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival) +{ + struct list_head *next, *first; + int rc = 0; + + // note: must be called under g_deviceslock + + first = &g_smscore_notifyees; + + for (next = first->next; next != first; next = next->next) + { + rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); + if (rc < 0) + break; + } + + return rc; +} + +smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys) +{ + smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); + if (!cb) + { + printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__); + return NULL; + } + + cb->p = buffer; + cb->offset_in_common = buffer - (u8*) common_buffer; + cb->phys = common_buffer_phys + cb->offset_in_common; + + return cb; +} + +/** + * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies + * registered hotplugs about new device. + * + * @param params device pointer to struct with device specific parameters and handlers + * @param coredev pointer to a value that receives created coredev object + * + * @return 0 on success, <0 on error. + */ +int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) +{ + smscore_device_t* dev; + u8 *buffer; + + dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); + if (!dev) + { + printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__); + return -ENOMEM; + } + + // init list entry so it could be safe in smscore_unregister_device + INIT_LIST_HEAD(&dev->entry); + + // init queues + INIT_LIST_HEAD(&dev->clients); + INIT_LIST_HEAD(&dev->subclients); + INIT_LIST_HEAD(&dev->buffers); + + // init locks + spin_lock_init(&dev->clientslock); + spin_lock_init(&dev->bufferslock); + + // init completion events + init_completion(&dev->version_ex_done); + init_completion(&dev->data_download_done); + init_completion(&dev->trigger_done); + init_completion(&dev->init_device_done); + init_completion(&dev->reload_start_done); + init_completion(&dev->resume_done); + + // alloc common buffer + dev->common_buffer_size = params->buffer_size * params->num_buffers; + dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA); + if (!dev->common_buffer) + { + smscore_unregister_device(dev); + return -ENOMEM; + } + + // prepare dma buffers + for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers ++, buffer += params->buffer_size) + { + smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); + if (!cb) + { + smscore_unregister_device(dev); + return -ENOMEM; + } + + smscore_putbuffer(dev, cb); + } + + printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers); + + dev->mode = DEVICE_MODE_NONE; + dev->context = params->context; + dev->device = params->device; + dev->setmode_handler = params->setmode_handler; + dev->detectmode_handler = params->detectmode_handler; + dev->sendrequest_handler = params->sendrequest_handler; + dev->preload_handler = params->preload_handler; + dev->postload_handler = params->postload_handler; + + dev->device_flags = params->flags; + strcpy(dev->devpath, params->devpath); + + // add device to devices list + kmutex_lock(&g_smscore_deviceslock); + list_add(&dev->entry, &g_smscore_devices); + kmutex_unlock(&g_smscore_deviceslock); + + *coredev = dev; + + printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + + return 0; +} + +/** + * sets initial device mode and notifies client hotplugs that device is ready + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return 0 on success, <0 on error. + */ +int smscore_start_device(smscore_device_t *coredev) +{ + int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); + if (rc < 0) + return rc; + + kmutex_lock(&g_smscore_deviceslock); + + rc = smscore_notify_callbacks(coredev, coredev->device, 1); + + printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc); + + kmutex_unlock(&g_smscore_deviceslock); + + return rc; +} + +int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion) +{ + int rc = coredev->sendrequest_handler(coredev->context, buffer, size); + if (rc < 0) + return rc; + + return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME; +} + +int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) +{ + SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; + SmsMsgHdr_ST *msg; + UINT32 mem_address = firmware->StartAddress; + u8* payload = firmware->Payload; + int rc = 0; + + if (coredev->preload_handler) + { + rc = coredev->preload_handler(coredev->context); + if (rc < 0) + return rc; + } + + // PAGE_SIZE buffer shall be enough and dma aligned + msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); + if (!msg) + return -ENOMEM; + + if (coredev->mode != DEVICE_MODE_NONE) + { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); + mem_address = *(UINT32*) &payload[20]; + } + + while (size && rc >= 0) + { + SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; + int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); + + SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + payload_size)); + + DataMsg->MemAddr = mem_address; + memcpy(DataMsg->Payload, payload, payload_size); + + if (coredev->device_flags & SMS_ROM_NO_RESPONSE && coredev->mode == DEVICE_MODE_NONE) + rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); + else + rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); + + payload += payload_size; + size -= payload_size; + mem_address += payload_size; + } + + if (rc >= 0) + { + if (coredev->mode == DEVICE_MODE_NONE) + { + SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg; + + SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5); + + TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point + TriggerMsg->msgData[1] = 5; // Priority + TriggerMsg->msgData[2] = 0x200; // Stack size + TriggerMsg->msgData[3] = 0; // Parameter + TriggerMsg->msgData[4] = 4; // Task ID + + if (coredev->device_flags & SMS_ROM_NO_RESPONSE) + { + rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); + msleep(100); + } + else + rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); + } + else + { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); + + rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); + } + } + + printk("%s %d \n", __func__, rc); + + kfree(msg); + + return (rc >= 0 && coredev->postload_handler) ? + coredev->postload_handler(coredev->context) : + rc; +} + +/** + * loads specified firmware into a buffer and calls device loadfirmware_handler + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param filename null-terminated string specifies firmware file name + * @param loadfirmware_handler device handler that loads firmware + * + * @return 0 on success, <0 on error. + */ +int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler) +{ + int rc = -ENOENT; + + const struct firmware *fw; + u8* fw_buffer; + + if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) + return -EINVAL; + + rc = request_firmware(&fw, filename, coredev->device); + if (rc < 0) + { + printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename); + return rc; + } + + fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); + if (fw_buffer) + { + memcpy(fw_buffer, fw->data, fw->size); + + rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? + smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : + loadfirmware_handler(coredev->context, fw_buffer, fw->size); + + kfree(fw_buffer); + } + else + { + printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__); + rc = -ENOMEM; + } + + release_firmware(fw); + + return rc; +} + +/** + * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return 0 on success, <0 on error. + */ +void smscore_unregister_device(smscore_device_t *coredev) +{ + smscore_buffer_t *cb; + int num_buffers = 0; + + kmutex_lock(&g_smscore_deviceslock); + + smscore_notify_clients(coredev); + smscore_notify_callbacks(coredev, NULL, 0); + + // at this point all buffers should be back + // onresponse must no longer be called + + while (1) + { + while ((cb = smscore_getbuffer(coredev))) + { + kfree(cb); + num_buffers ++; + } + + if (num_buffers == coredev->num_buffers) + break; + + printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers); + msleep(100); + } + + printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers); + + if (coredev->common_buffer) + dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); + + list_del(&coredev->entry); + kfree(coredev); + + kmutex_unlock(&g_smscore_deviceslock); + + printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev); +} + +int smscore_detect_mode(smscore_device_t *coredev) +{ + void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); + int rc; + + if (!buffer) + return -ENOMEM; + + SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); + + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + if (rc == -ETIME) + { + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__); + + if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) + { + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + if (rc < 0) + { + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc); + } + } + else + rc = -ETIME; + } + + kfree(buffer); + + return rc; +} + +char *smscore_fw_lkup[] = +{ + "dvb_nova_12mhz.inp", + "dvb_nova_12mhz.inp", + "tdmb_nova.inp", + "none", + "dvb_nova_12mhz.inp", + "isdbt_nova_12mhz.inp", + "isdbt_nova_12mhz.inp", + "cmmb_nova_12mhz.inp", + "none", +}; + +/** + * calls device handler to change mode of operation + * NOTE: stellar/usb may disconnect when changing mode + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param mode requested mode of operation + * + * @return 0 on success, <0 on error. + */ +int smscore_set_device_mode(smscore_device_t *coredev, int mode) +{ + void *buffer; + int rc = 0; + + if (coredev->device_flags & SMS_DEVICE_FAMILY2) + { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) + { + printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode); + return -EINVAL; + } + + if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) + { + rc = smscore_detect_mode(coredev); + if (rc < 0) + return rc; + } + + if (coredev->mode == mode) + { + printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode); + return 0; + } + + if (!(coredev->modes_supported & (1 << mode))) + { + rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL); + if (rc < 0) + return rc; + } + else + { + printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode); + } + + buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + if (buffer) + { + SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); + + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); + msg->msgData[0] = mode; + + rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); + + kfree(buffer); + } + else + rc = -ENOMEM; + } + else + { + if (coredev->detectmode_handler) + coredev->detectmode_handler(coredev->context, &coredev->mode); + + if (coredev->mode != mode && coredev->setmode_handler) + rc = coredev->setmode_handler(coredev->context, mode); + } + + smscore_registry_setmode(coredev->devpath, mode); + + if (rc >= 0) + { + coredev->mode = mode; + coredev->device_flags &= ~SMS_DEVICE_NOT_READY; + } + + return rc; +} + +/** + * calls device handler to get current mode of operation + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return current mode + */ +int smscore_get_device_mode(smscore_device_t *coredev) +{ + return coredev->mode; +} + +smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type) +{ + smscore_client_t *client = NULL; + struct list_head *next, *first; + unsigned long flags; + + if (!data_type) + return NULL; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->clients; + + for (next = first->next; next != first; next = next->next) + { + if (((smscore_client_t*) next)->data_type == data_type) + { + client = (smscore_client_t*) next; + break; + } + } + + spin_unlock_irqrestore(&coredev->clientslock, flags); + + return client; +} + +smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) +{ + smscore_client_t *client = NULL; + struct list_head *next, *first; + unsigned long flags; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->subclients; + + for (next = first->next; next != first; next = next->next) + { + if (((smscore_subclient_t*) next)->id == id) + { + client = ((smscore_subclient_t*) next)->client; + break; + } + } + + spin_unlock_irqrestore(&coredev->clientslock, flags); + + return client; +} + +/** + * find client by response id/type, call clients onresponse handler + * return buffer to pool on error + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param cb pointer to response buffer descriptor + * + */ +void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) +{ + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); + smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType); + int rc = -EBUSY; + + static unsigned long last_sample_time = 0; + static int data_total = 0; + unsigned long time_now = jiffies_to_msecs(jiffies); + + if (!last_sample_time) + last_sample_time = time_now; + + if (time_now - last_sample_time > 10000) + { + printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); + + last_sample_time = time_now; + data_total = 0; + } + + data_total += cb->size; + + if (!client) + client = smscore_getclient_by_id(coredev, phdr->msgDstId); + + if (client) + rc = client->onresponse_handler(client->context, cb); + + if (rc < 0) + { + switch (phdr->msgType) + { + case MSG_SMS_GET_VERSION_EX_RES: + { + SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; + printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); + + coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; + coredev->modes_supported = ver->SupportedProtocols; + + complete(&coredev->version_ex_done); + break; + } + + case MSG_SMS_INIT_DEVICE_RES: + printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__); + complete(&coredev->init_device_done); + break; + + case MSG_SW_RELOAD_START_RES: + printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__); + complete(&coredev->reload_start_done); + break; + + case MSG_SMS_DATA_DOWNLOAD_RES: + complete(&coredev->data_download_done); + break; + + case MSG_SW_RELOAD_EXEC_RES: + printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__); + break; + + case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: + printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__); + complete(&coredev->trigger_done); + break; + + case MSG_SMS_SLEEP_RESUME_COMP_IND: + complete(&coredev->resume_done); + break; + + default: + printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId); + } + + smscore_putbuffer(coredev, cb); + } +} + +/** + * return pointer to next free buffer descriptor from core pool + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * + * @return pointer to descriptor on success, NULL on error. + */ +smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) +{ + smscore_buffer_t *cb = NULL; + unsigned long flags; + + spin_lock_irqsave(&coredev->bufferslock, flags); + + if (!list_empty(&coredev->buffers)) + { + cb = (smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); + } + + spin_unlock_irqrestore(&coredev->bufferslock, flags); + + return cb; +} + +/** + * return buffer descriptor to a pool + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param cb pointer buffer descriptor + * + */ +void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) +{ + list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); +} + +int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id) +{ + smscore_client_t *existing_client; + smscore_subclient_t *subclient; + + if (!id) + return 0; + + existing_client = smscore_getclient_by_id(coredev, id); + if (existing_client == client) + return 0; + + if (existing_client) + return -EBUSY; + + subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL); + if (!subclient) + return -ENOMEM; + + subclient->client = client; + subclient->id = id; + + list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock); + + return 0; +} + +/** + * creates smsclient object, check that id is taken by another client + * + * @param coredev pointer to a coredev object from clients hotplug + * @param initial_id all messages with this id would be sent to this client + * @param data_type all messages of this type would be sent to this client + * @param onresponse_handler client handler that is called to process incoming messages + * @param onremove_handler client handler that is called when device is removed + * @param context client-specific context + * @param client pointer to a value that receives created smsclient object + * + * @return 0 on success, <0 on error. + */ +int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) +{ + smscore_client_t* newclient; + int rc; + + // check that no other channel with same data type exists + if (params->data_type && smscore_getclient_by_type(coredev, params->data_type)) + return -EEXIST; + + newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); + if (!newclient) + return -ENOMEM; + + // check that no other channel with same id exists + rc = smscore_validate_client(coredev, newclient, params->initial_id); + if (rc < 0) + { + kfree(newclient); + return rc; + } + + newclient->coredev = coredev; + newclient->data_type = params->data_type; + newclient->onresponse_handler = params->onresponse_handler; + newclient->onremove_handler = params->onremove_handler; + newclient->context = params->context; + + list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); + + *client = newclient; + + printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id); + + return 0; +} + +/** + * frees smsclient object and all subclients associated with it + * + * @param client pointer to smsclient object returned by smscore_register_client + * + */ +void smscore_unregister_client(smscore_client_t *client) +{ + smscore_device_t *coredev = client->coredev; + struct list_head *next, *first; + unsigned long flags; + + spin_lock_irqsave(&coredev->clientslock, flags); + + first = &coredev->subclients; + + for (next = first->next; next != first;) + { + smscore_subclient_t *subclient = (smscore_subclient_t *) next; + next = next->next; + + if (subclient->client == client) + { + list_del(&subclient->entry); + kfree(subclient); + } + } + + printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type); + + list_del(&client->entry); + kfree(client); + + spin_unlock_irqrestore(&coredev->clientslock, flags); +} + +/** + * verifies that source id is not taken by another client, + * calls device handler to send requests to the device + * + * @param client pointer to smsclient object returned by smscore_register_client + * @param buffer pointer to a request buffer + * @param size size (in bytes) of request buffer + * + * @return 0 on success, <0 on error. + */ +int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) +{ + smscore_device_t* coredev = client->coredev; + SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; + + // check that no other channel with same id exists + int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId); + if (rc < 0) + return rc; + + return coredev->sendrequest_handler(coredev->context, buffer, size); +} + +/** + * return the size of large (common) buffer + * + * @param coredev pointer to a coredev object from clients hotplug + * + * @return size (in bytes) of the buffer + */ +int smscore_get_common_buffer_size(smscore_device_t *coredev) +{ + return coredev->common_buffer_size; +} + +/** + * maps common buffer (if supported by platform) + * + * @param coredev pointer to a coredev object from clients hotplug + * @param vma pointer to vma struct from mmap handler + * + * @return 0 on success, <0 on error. + */ +int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma) +{ + unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); + + if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) + { + printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__); + return -EINVAL; + } + + if ((end - start) != size) + { + printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (int)(end - start), (int) size); + return -EINVAL; + } + + if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) + { + printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__); + return -EAGAIN; + } + + return 0; +} + +int smscore_module_init(void) +{ + int rc = 0; + + INIT_LIST_HEAD(&g_smscore_notifyees); + INIT_LIST_HEAD(&g_smscore_devices); + kmutex_init(&g_smscore_deviceslock); + + INIT_LIST_HEAD(&g_smscore_registry); + kmutex_init(&g_smscore_registrylock); + + /* USB Register */ + rc = smsusb_register(); + + /* DVB Register */ + rc = smsdvb_register(); + + printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); + + return rc; +} + +void smscore_module_exit(void) +{ + + kmutex_lock(&g_smscore_deviceslock); + while (!list_empty(&g_smscore_notifyees)) + { + smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next; + + list_del(¬ifyee->entry); + kfree(notifyee); + } + kmutex_unlock(&g_smscore_deviceslock); + + kmutex_lock(&g_smscore_registrylock); + while (!list_empty(&g_smscore_registry)) + { + smscore_registry_entry_t *entry = (smscore_registry_entry_t *) g_smscore_registry.next; + + list_del(&entry->entry); + kfree(entry); + } + kmutex_unlock(&g_smscore_registrylock); + + /* DVB UnRegister */ + smsdvb_unregister(); + + /* Unregister USB */ + smsusb_unregister(); + + printk(KERN_INFO "%s\n", __FUNCTION__); +} + +module_init(smscore_module_init); +module_exit(smscore_module_exit); + +MODULE_DESCRIPTION("smscore"); +MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h new file mode 100644 index 000000000000..679487df8a53 --- /dev/null +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -0,0 +1,531 @@ +/* + * Driver for the Siano SMS1xxx USB dongle + * + * author: Anatoly Greenblat + * + * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __smscoreapi_h__ +#define __smscoreapi_h__ + +#include +#include +#include +#include +#include +#include + +#include "dmxdev.h" +#include "dvbdev.h" +#include "dvb_demux.h" +#include "dvb_frontend.h" + +#include + +typedef struct mutex kmutex_t; + +#define kmutex_init(_p_) mutex_init(_p_) +#define kmutex_lock(_p_) mutex_lock(_p_) +#define kmutex_trylock(_p_) mutex_trylock(_p_) +#define kmutex_unlock(_p_) mutex_unlock(_p_) + + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#define SMS_ALLOC_ALIGNMENT 128 +#define SMS_DMA_ALIGNMENT 16 +#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) + +#define SMS_DEVICE_FAMILY2 1 +#define SMS_ROM_NO_RESPONSE 2 +#define SMS_DEVICE_NOT_READY 0x8000000 + +typedef struct _smscore_device smscore_device_t; +typedef struct _smscore_client smscore_client_t; +typedef struct _smscore_buffer smscore_buffer_t; + +typedef int (*hotplug_t)(smscore_device_t *coredev, struct device *device, int arrival); + +typedef int (*setmode_t)(void *context, int mode); +typedef void (*detectmode_t)(void *context, int *mode); +typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); +typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); +typedef int (*preload_t)(void *context); +typedef int (*postload_t)(void *context); + +typedef int (*onresponse_t)(void *context, smscore_buffer_t *cb); +typedef void (*onremove_t)(void *context); + +typedef struct _smscore_buffer +{ + // public members, once passed to clients can be changed freely + struct list_head entry; + int size; + int offset; + + // private members, read-only for clients + void *p; + dma_addr_t phys; + unsigned long offset_in_common; +} *psmscore_buffer_t; + +typedef struct _smsdevice_params +{ + struct device *device; + + int buffer_size; + int num_buffers; + + char devpath[32]; + unsigned long flags; + + setmode_t setmode_handler; + detectmode_t detectmode_handler; + sendrequest_t sendrequest_handler; + preload_t preload_handler; + postload_t postload_handler; + + void *context; +} smsdevice_params_t; + +typedef struct _smsclient_params +{ + int initial_id; + int data_type; + onresponse_t onresponse_handler; + onremove_t onremove_handler; + + void *context; +} smsclient_params_t; + +// GPIO definitions for antenna frequency domain control (SMS8021) +#define SMS_ANTENNA_GPIO_0 1 +#define SMS_ANTENNA_GPIO_1 0 + +#define BW_8_MHZ 0 +#define BW_7_MHZ 1 +#define BW_6_MHZ 2 +#define BW_5_MHZ 3 +#define BW_ISDBT_1SEG 4 +#define BW_ISDBT_3SEG 5 + +#define MSG_HDR_FLAG_SPLIT_MSG 4 + +#define MAX_GPIO_PIN_NUMBER 31 + +#define HIF_TASK 11 +#define SMS_HOST_LIB 150 +#define DVBT_BDA_CONTROL_MSG_ID 201 + +#define SMS_MAX_PAYLOAD_SIZE 240 +#define SMS_TUNE_TIMEOUT 500 + +#define MSG_SMS_GPIO_CONFIG_REQ 507 +#define MSG_SMS_GPIO_CONFIG_RES 508 +#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 +#define MSG_SMS_GPIO_SET_LEVEL_RES 510 +#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 +#define MSG_SMS_GPIO_GET_LEVEL_RES 512 +#define MSG_SMS_RF_TUNE_REQ 561 +#define MSG_SMS_RF_TUNE_RES 562 +#define MSG_SMS_INIT_DEVICE_REQ 578 +#define MSG_SMS_INIT_DEVICE_RES 579 +#define MSG_SMS_ADD_PID_FILTER_REQ 601 +#define MSG_SMS_ADD_PID_FILTER_RES 602 +#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 +#define MSG_SMS_REMOVE_PID_FILTER_RES 604 +#define MSG_SMS_DAB_CHANNEL 607 +#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 +#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 +#define MSG_SMS_GET_STATISTICS_REQ 615 +#define MSG_SMS_GET_STATISTICS_RES 616 +#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 +#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 +#define MSG_SMS_GET_STATISTICS_EX_REQ 653 +#define MSG_SMS_GET_STATISTICS_EX_RES 654 +#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 +#define MSG_SMS_DATA_DOWNLOAD_REQ 660 +#define MSG_SMS_DATA_DOWNLOAD_RES 661 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 +#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 +#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 +#define MSG_SMS_GET_VERSION_EX_REQ 668 +#define MSG_SMS_GET_VERSION_EX_RES 669 +#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 +#define MSG_SMS_I2C_SET_FREQ_REQ 685 +#define MSG_SMS_GENERIC_I2C_REQ 687 +#define MSG_SMS_GENERIC_I2C_RES 688 +#define MSG_SMS_DVBT_BDA_DATA 693 +#define MSG_SW_RELOAD_REQ 697 +#define MSG_SMS_DATA_MSG 699 +#define MSG_SW_RELOAD_START_REQ 702 +#define MSG_SW_RELOAD_START_RES 703 +#define MSG_SW_RELOAD_EXEC_REQ 704 +#define MSG_SW_RELOAD_EXEC_RES 705 +#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 +#define MSG_SMS_ISDBT_TUNE_REQ 776 +#define MSG_SMS_ISDBT_TUNE_RES 777 + +#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ + (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ + (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ +} while (0) +#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) + +typedef enum +{ + DEVICE_MODE_NONE = -1, + DEVICE_MODE_DVBT = 0, + DEVICE_MODE_DVBH, + DEVICE_MODE_DAB_TDMB, + DEVICE_MODE_DAB_TDMB_DABIP, + DEVICE_MODE_DVBT_BDA, + DEVICE_MODE_ISDBT, + DEVICE_MODE_ISDBT_BDA, + DEVICE_MODE_CMMB, + DEVICE_MODE_RAW_TUNER, + DEVICE_MODE_MAX, +} SMS_DEVICE_MODE; + +typedef unsigned char UINT8; +typedef unsigned short UINT16; +typedef unsigned int UINT32; +typedef int INT32; + +typedef struct SmsMsgHdr_S +{ + UINT16 msgType; + UINT8 msgSrcId; + UINT8 msgDstId; + UINT16 msgLength; // Length is of the entire message, including header + UINT16 msgFlags; +} SmsMsgHdr_ST; + +typedef struct SmsMsgData_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 msgData[1]; +} SmsMsgData_ST; + +typedef struct SmsDataDownload_S +{ + SmsMsgHdr_ST xMsgHeader; + UINT32 MemAddr; + UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; +} SmsDataDownload_ST; + +typedef struct SmsVersionRes_S +{ + SmsMsgHdr_ST xMsgHeader; + + UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" + UINT8 Step; // 0 - Step A + UINT8 MetalFix; // 0 - Metal 0 + + UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E + UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols + + UINT8 VersionMajor; + UINT8 VersionMinor; + UINT8 VersionPatch; + UINT8 VersionFieldPatch; + + UINT8 RomVersionMajor; + UINT8 RomVersionMinor; + UINT8 RomVersionPatch; + UINT8 RomVersionFieldPatch; + + UINT8 TextLabel[34]; +} SmsVersionRes_ST; + +typedef struct SmsFirmware_S +{ + UINT32 CheckSum; + UINT32 Length; + UINT32 StartAddress; + UINT8 Payload[1]; +} SmsFirmware_ST; + +typedef struct SMSHOSTLIB_STATISTICS_S +{ + UINT32 Reserved; //!< Reserved + + /// Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + /// Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + /// Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H + UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos + UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H + UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H + UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H + UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H + + /// Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding + /// Common params + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + + /// Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + + /// DAB/T-DMB + UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] + + /// DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + +} SMSHOSTLIB_STATISTICS_ST; + +typedef struct +{ + UINT32 RequestResult; + + SMSHOSTLIB_STATISTICS_ST Stat; + + // Split the calc of the SNR in DAB + UINT32 Signal; //!< dB + UINT32 Noise; //!< dB + +} SmsMsgStatisticsInfo_ST; + +typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S +{ + // Per-layer information + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist + UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count + UINT32 BERBitCount; //!< Post Viterbi Total Bits Count + UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A + UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist + UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist + UINT32 TMCCErrors; //!< TMCC errors +} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in Hz + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 TransmissionMode; //!< ISDB-T transmission mode + UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) + UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise + UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network + + // Per-layer information + // Layers A, B and C + SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_ISDBT_ST; + +typedef struct SMSHOSTLIB_STATISTICS_DVB_S +{ + UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + //!< This fiels MUST always first in any statistics structure + + UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by + //!< the host is smaller than FullSize, the struct will be truncated + // Common parameters + UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked + UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked + UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on + + // Reception quality + INT32 SNR; //!< dB + UINT32 BER; //!< Post Viterbi BER [1E-5] + UINT32 BERErrorCount; //!< Number of errornous SYNC bits. + UINT32 BERBitCount; //!< Total number of SYNC bits. + UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A + UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H + INT32 RSSI; //!< dBm + INT32 InBandPwr; //!< In band power in dBM + INT32 CarrierOffset; //!< Carrier Offset in bin/1024 + + // Transmission parameters + UINT32 Frequency; //!< Frequency in Hz + UINT32 Bandwidth; //!< Bandwidth in MHz + UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET + UINT32 TransmissionMode; //!< FFT mode carriers in Kilos + UINT32 GuardInterval; //!< Guard Interval, 1 divided by value + UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET + UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET + UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET + + // Burst parameters, valid only for DVB-H + UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H + UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H + UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H + UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H + UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H + UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H + UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H + UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets + UINT32 TotalTSPackets; //!< Total number of transport-stream packets + UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H + UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H + UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received + + // DVB-H TPS parameters + UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator + + // Interface information + UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + +} SMSHOSTLIB_STATISTICS_DVB_ST; + +typedef struct SMSHOSTLIB_GPIO_CONFIG_S +{ + UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 + UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 + UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 + UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 + UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 +} SMSHOSTLIB_GPIO_CONFIG_ST; + +typedef struct SMSHOSTLIB_I2C_REQ_S +{ + UINT32 DeviceAddress; // I2c device address + UINT32 WriteCount; // number of bytes to write + UINT32 ReadCount; // number of bytes to read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_REQ_ST; + +typedef struct SMSHOSTLIB_I2C_RES_S +{ + UINT32 Status; // non-zero value in case of failure + UINT32 ReadCount; // number of bytes read + UINT8 Data[1]; +} SMSHOSTLIB_I2C_RES_ST; + +typedef struct _smsdvb_client +{ + struct list_head entry; + + smscore_device_t *coredev; + smscore_client_t *smsclient; + + struct dvb_adapter adapter; + struct dvb_demux demux; + struct dmxdev dmxdev; + struct dvb_frontend frontend; + + fe_status_t fe_status; + int fe_ber, fe_snr, fe_signal_strength; + + struct completion tune_done, stat_done; + + // todo: save freq/band instead whole struct + struct dvb_frontend_parameters fe_params; + +} smsdvb_client_t; + +extern void smscore_registry_setmode(char *devpath, int mode); +extern int smscore_registry_getmode(char *devpath); + +extern int smscore_register_hotplug(hotplug_t hotplug); +extern void smscore_unregister_hotplug(hotplug_t hotplug); + +extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev); +extern void smscore_unregister_device(smscore_device_t *coredev); + +extern int smscore_start_device(smscore_device_t *coredev); +extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler); + +extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); +extern int smscore_get_device_mode(smscore_device_t *coredev); + +extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client); +extern void smscore_unregister_client(smscore_client_t *client); + +extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size); +extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb); + +extern int smscore_get_common_buffer_size(smscore_device_t *coredev); +extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma); + +extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); +extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); + +/* smsdvb.c */ +int smsdvb_register(void); +void smsdvb_unregister(void); + +/* smsusb.c */ +int smsusb_register(void); +void smsusb_unregister(void); + +#endif // __smscoreapi_h__ diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c new file mode 100644 index 000000000000..e1a14a812c25 --- /dev/null +++ b/drivers/media/dvb/siano/smsdvb.c @@ -0,0 +1,425 @@ +/* + * Driver for the Siano SMS10xx USB dongle + * + * author: Anatoly Greenblat + * + * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include "smscoreapi.h" + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +struct list_head g_smsdvb_clients; +kmutex_t g_smsdvb_clientslock; + +int smsdvb_onresponse(void *context, smscore_buffer_t *cb) +{ + smsdvb_client_t *client = (smsdvb_client_t *) context; + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset); + + switch(phdr->msgType) + { + case MSG_SMS_DVBT_BDA_DATA: + dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST)); + break; + + case MSG_SMS_RF_TUNE_RES: + complete(&client->tune_done); + break; + + case MSG_SMS_GET_STATISTICS_RES: + { + SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1); + + if (p->Stat.IsDemodLocked) + { + client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; + client->fe_snr = p->Stat.SNR; + client->fe_ber = p->Stat.BER; + + if (p->Stat.InBandPwr < -95) + client->fe_signal_strength = 0; + else if (p->Stat.InBandPwr > -29) + client->fe_signal_strength = 100; + else + client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2; + } + else + { + client->fe_status = 0; + client->fe_snr = + client->fe_ber = + client->fe_signal_strength = 0; + } + + complete(&client->stat_done); + break; + } + } + + smscore_putbuffer(client->coredev, cb); + + return 0; +} + +void smsdvb_unregister_client(smsdvb_client_t* client) +{ + // must be called under clientslock + + list_del(&client->entry); + + smscore_unregister_client(client->smsclient); + dvb_unregister_frontend(&client->frontend); + dvb_dmxdev_release(&client->dmxdev); + dvb_dmx_release(&client->demux); + dvb_unregister_adapter(&client->adapter); + kfree(client); +} + +void smsdvb_onremove(void *context) +{ + kmutex_lock(&g_smsdvb_clientslock); + + smsdvb_unregister_client((smsdvb_client_t*) context); + + kmutex_unlock(&g_smsdvb_clientslock); +} + +static int smsdvb_start_feed(struct dvb_demux_feed *feed) +{ + smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + SmsMsgData_ST PidMsg; + + printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_stop_feed(struct dvb_demux_feed *feed) +{ + smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + SmsMsgData_ST PidMsg; + + printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + + PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + PidMsg.xMsgHeader.msgDstId = HIF_TASK; + PidMsg.xMsgHeader.msgFlags = 0; + PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; + PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); + PidMsg.msgData[0] = feed->pid; + + return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); +} + +static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion) +{ + int rc = smsclient_sendrequest(client->smsclient, buffer, size); + if (rc < 0) + return rc; + + return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME; +} + +static int smsdvb_send_statistics_request(smsdvb_client_t *client) +{ + SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done); +} + +static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *stat = client->fe_status; + + return rc; +} + +static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *ber = client->fe_ber; + + return rc; +} + +static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *strength = client->fe_signal_strength; + + return rc; +} + +static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + int rc = smsdvb_send_statistics_request(client); + + if (!rc) + *snr = client->fe_snr; + + return rc; +} + +static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) +{ + printk("%s\n", __FUNCTION__); + + tune->min_delay_ms = 400; + tune->step_size = 250000; + tune->max_drift = 0; + return 0; +} + +static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + + struct + { + SmsMsgHdr_ST Msg; + u32 Data[3]; + } Msg; + + Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + Msg.Msg.msgDstId = HIF_TASK; + Msg.Msg.msgFlags = 0; + Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; + Msg.Msg.msgLength = sizeof(Msg); + Msg.Data[0] = fep->frequency; + Msg.Data[2] = 12000000; + + printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth); + + switch(fep->u.ofdm.bandwidth) + { + case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; + case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; + case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; +// case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: return -EINVAL; + } + + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); +} + +static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + + printk("%s\n", __FUNCTION__); + + // todo: + memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); + return 0; +} + +static void smsdvb_release(struct dvb_frontend *fe) +{ + // do nothing +} + +static struct dvb_frontend_ops smsdvb_fe_ops = { + .info = { + .name = "Siano Mobile Digital SMS10xx", + .type = FE_OFDM, + .frequency_min = 44250000, + .frequency_max = 867250000, + .frequency_stepsize = 250000, + .caps = FE_CAN_INVERSION_AUTO | + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, + }, + + .release = smsdvb_release, + + .set_frontend = smsdvb_set_frontend, + .get_frontend = smsdvb_get_frontend, + .get_tune_settings = smsdvb_get_tune_settings, + + .read_status = smsdvb_read_status, + .read_ber = smsdvb_read_ber, + .read_signal_strength = smsdvb_read_signal_strength, + .read_snr = smsdvb_read_snr, +}; + +int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival) +{ + smsclient_params_t params; + smsdvb_client_t* client; + int rc; + + // device removal handled by onremove callback + if (!arrival) + return 0; + + if (smscore_get_device_mode(coredev) != 4) + { + rc = smscore_set_device_mode(coredev, 4); + if (rc < 0) + return rc; + } + + client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); + if (!client) + { + printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); + return -ENOMEM; + } + + // register dvb adapter + rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); + if (rc < 0) + { + printk("%s dvb_register_adapter() failed %d\n", __func__, rc); + goto adapter_error; + } + + // init dvb demux + client->demux.dmx.capabilities = DMX_TS_FILTERING; + client->demux.filternum = 32; // todo: nova ??? + client->demux.feednum = 32; + client->demux.start_feed = smsdvb_start_feed; + client->demux.stop_feed = smsdvb_stop_feed; + + rc = dvb_dmx_init(&client->demux); + if (rc < 0) + { + printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc); + goto dvbdmx_error; + } + + // init dmxdev + client->dmxdev.filternum = 32; + client->dmxdev.demux = &client->demux.dmx; + client->dmxdev.capabilities = 0; + + rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); + if (rc < 0) + { + printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc); + goto dmxdev_error; + } + + // init and register frontend + memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); + + rc = dvb_register_frontend(&client->adapter, &client->frontend); + if (rc < 0) + { + printk("%s frontend registration failed %d\n", __FUNCTION__, rc); + goto frontend_error; + } + + params.initial_id = 0; + params.data_type = MSG_SMS_DVBT_BDA_DATA; + params.onresponse_handler = smsdvb_onresponse; + params.onremove_handler = smsdvb_onremove; + params.context = client; + + rc = smscore_register_client(coredev, ¶ms, &client->smsclient); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); + goto client_error; + } + + client->coredev = coredev; + + init_completion(&client->tune_done); + init_completion(&client->stat_done); + + kmutex_lock(&g_smsdvb_clientslock); + + list_add(&client->entry, &g_smsdvb_clients); + + kmutex_unlock(&g_smsdvb_clientslock); + + printk(KERN_INFO "%s success\n", __FUNCTION__); + + return 0; + +client_error: + dvb_unregister_frontend(&client->frontend); + +frontend_error: + dvb_dmxdev_release(&client->dmxdev); + +dmxdev_error: + dvb_dmx_release(&client->demux); + +dvbdmx_error: + dvb_unregister_adapter(&client->adapter); + +adapter_error: + kfree(client); + return rc; +} + +int smsdvb_register(void) +{ + int rc; + + INIT_LIST_HEAD(&g_smsdvb_clients); + kmutex_init(&g_smsdvb_clientslock); + + rc = smscore_register_hotplug(smsdvb_hotplug); + + printk(KERN_INFO "%s\n", __FUNCTION__); + + return rc; +} + +void smsdvb_unregister(void) +{ + smscore_unregister_hotplug(smsdvb_hotplug); + + kmutex_lock(&g_smsdvb_clientslock); + + while (!list_empty(&g_smsdvb_clients)) + smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); + + kmutex_unlock(&g_smsdvb_clientslock); + +} + diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c new file mode 100644 index 000000000000..20aa878d9d5f --- /dev/null +++ b/drivers/media/dvb/siano/smsusb.c @@ -0,0 +1,436 @@ +/* + * Driver for the Siano SMS10xx USB dongle + * + * author: Anatoly Greenblat + * + * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "smscoreapi.h" + +#define USB1_BUFFER_SIZE 0x1000 +#define USB2_BUFFER_SIZE 0x4000 + +#define MAX_BUFFERS 50 +#define MAX_URBS 10 + +typedef struct _smsusb_device smsusb_device_t; + +typedef struct _smsusb_urb +{ + smscore_buffer_t *cb; + smsusb_device_t *dev; + + struct urb urb; +} smsusb_urb_t; + +typedef struct _smsusb_device +{ + struct usb_device* udev; + smscore_device_t *coredev; + + smsusb_urb_t surbs[MAX_URBS]; + + int response_alignment; + int buffer_size; +} *psmsusb_device_t; + +int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb); + +void smsusb_onresponse(struct urb *urb) +{ + smsusb_urb_t *surb = (smsusb_urb_t *) urb->context; + smsusb_device_t *dev = surb->dev; + + if (urb->status < 0) + { + printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length); + return; + } + + if (urb->actual_length > 0) + { + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p; + + if (urb->actual_length >= phdr->msgLength) + { + surb->cb->size = phdr->msgLength; + + if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) + { + surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3); + + // sanity check + if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) + { + printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length); + goto exit_and_resubmit; + } + + // move buffer pointer and copy header to its new location + memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST)); + } + else + surb->cb->offset = 0; + + smscore_onresponse(dev->coredev, surb->cb); + surb->cb = NULL; + } + else + { + printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length); + } + } + +exit_and_resubmit: + smsusb_submit_urb(dev, surb); +} + +int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) +{ + if (!surb->cb) + { + surb->cb = smscore_getbuffer(dev->coredev); + if (!surb->cb) + { + printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__); + return -ENOMEM; + } + } + + usb_fill_bulk_urb( + &surb->urb, + dev->udev, + usb_rcvbulkpipe(dev->udev, 0x81), + surb->cb->p, + dev->buffer_size, + smsusb_onresponse, + surb + ); + surb->urb.transfer_dma = surb->cb->phys; + surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + return usb_submit_urb(&surb->urb, GFP_ATOMIC); +} + +void smsusb_stop_streaming(smsusb_device_t* dev) +{ + int i; + + for (i = 0; i < MAX_URBS; i ++) + { + usb_kill_urb(&dev->surbs[i].urb); + + if (dev->surbs[i].cb) + { + smscore_putbuffer(dev->coredev, dev->surbs[i].cb); + dev->surbs[i].cb = NULL; + } + } +} + +int smsusb_start_streaming(smsusb_device_t* dev) +{ + int i, rc; + + for (i = 0; i < MAX_URBS; i ++) + { + rc = smsusb_submit_urb(dev, &dev->surbs[i]); + if (rc < 0) + { + printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__); + smsusb_stop_streaming(dev); + break; + } + } + + return rc; +} + +int smsusb_sendrequest(void *context, void *buffer, size_t size) +{ + smsusb_device_t* dev = (smsusb_device_t*) context; + int dummy; + + return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); +} + +char *smsusb1_fw_lkup[] = +{ + "dvbt_stellar_usb.inp", + "dvbh_stellar_usb.inp", + "tdmb_stellar_usb.inp", + "none", + "dvbt_bda_stellar_usb.inp", +}; + +int smsusb1_load_firmware(struct usb_device *udev, int id) +{ + const struct firmware *fw; + u8* fw_buffer; + int rc, dummy; + + if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) + { + printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id); + return -EINVAL; + } + + rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); + if (rc < 0) + { + printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id); + return rc; + } + + fw_buffer = kmalloc(fw->size, GFP_KERNEL); + if (fw_buffer) + { + memcpy(fw_buffer, fw->data, fw->size); + + rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); + + printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc); + + kfree(fw_buffer); + } + else + { + printk(KERN_INFO "failed to allocate firmware buffer\n"); + rc = -ENOMEM; + } + + release_firmware(fw); + + return rc; +} + +void smsusb1_detectmode(void *context, int *mode) +{ + char *product_string = ((smsusb_device_t *) context)->udev->product; + + *mode = DEVICE_MODE_NONE; + + if (!product_string) + { + product_string = "none"; + printk("%s product string not found\n", __FUNCTION__); + } + else + { + if (strstr(product_string, "DVBH")) + *mode = 1; + else if (strstr(product_string, "BDA")) + *mode = 4; + else if (strstr(product_string, "DVBT")) + *mode = 0; + else if (strstr(product_string, "TDMB")) + *mode = 2; + } + + printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string); +} + +int smsusb1_setmode(void *context, int mode) +{ + SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) + { + printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode); + return -EINVAL; + } + + return smsusb_sendrequest(context, &Msg, sizeof(Msg)); +} + +void smsusb_term_device(struct usb_interface *intf) +{ + smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf); + + if (dev) + { + smsusb_stop_streaming(dev); + + // unregister from smscore + if (dev->coredev) + smscore_unregister_device(dev->coredev); + + kfree(dev); + + printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev); + } + + usb_set_intfdata(intf, NULL); +} + +int smsusb_init_device(struct usb_interface *intf) +{ + smsdevice_params_t params; + smsusb_device_t* dev; + int i, rc; + + // create device object + dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); + if (!dev) + { + printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__); + return -ENOMEM; + } + + memset(¶ms, 0, sizeof(params)); + usb_set_intfdata(intf, dev); + dev->udev = interface_to_usbdev(intf); + + switch (dev->udev->descriptor.idProduct) + { + case 0x100: + dev->buffer_size = USB1_BUFFER_SIZE; + + params.setmode_handler = smsusb1_setmode; + params.detectmode_handler = smsusb1_detectmode; + break; + + default: + dev->buffer_size = USB2_BUFFER_SIZE; + dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); + + params.flags |= SMS_DEVICE_FAMILY2; + break; + } + + params.device = &dev->udev->dev; + params.buffer_size = dev->buffer_size; + params.num_buffers = MAX_BUFFERS; + params.sendrequest_handler = smsusb_sendrequest; + params.context = dev; + snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); + + // register in smscore + rc = smscore_register_device(¶ms, &dev->coredev); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc); + smsusb_term_device(intf); + return rc; + } + + // initialize urbs + for (i = 0; i < MAX_URBS; i ++) + { + dev->surbs[i].dev = dev; + usb_init_urb(&dev->surbs[i].urb); + } + + rc = smsusb_start_streaming(dev); + if (rc < 0) + { + printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__); + smsusb_term_device(intf); + return rc; + } + + rc = smscore_start_device(dev->coredev); + if (rc < 0) + { + printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__); + smsusb_term_device(intf); + return rc; + } + + printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + + return rc; +} + +int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + char devpath[32]; + int i, rc; + + if (intf->num_altsetting > 0) + { + rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); + if (rc < 0) + { + printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc); + return rc; + } + } + + printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) + printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); + + if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0) + { + printk(KERN_INFO "rom interface 0 is not used\n"); + return -ENODEV; + } + + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) + { + snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath); + return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); + } + + return smsusb_init_device(intf); +} + +void smsusb_disconnect(struct usb_interface *intf) +{ + smsusb_term_device(intf); +} + +static struct usb_device_id smsusb_id_table [] = { + { USB_DEVICE(0x187F, 0x0010) }, + { USB_DEVICE(0x187F, 0x0100) }, + { USB_DEVICE(0x187F, 0x0200) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE (usb, smsusb_id_table); + +static struct usb_driver smsusb_driver = { + .name = "smsusb", + .probe = smsusb_probe, + .disconnect = smsusb_disconnect, + .id_table = smsusb_id_table, +}; + +int smsusb_register(void) +{ + int rc = usb_register(&smsusb_driver); + if (rc) + printk(KERN_INFO "usb_register failed. Error number %d\n", rc); + + printk(KERN_INFO "%s\n", __FUNCTION__); + + return rc; +} + +void smsusb_unregister(void) +{ + /* Regular USB Cleanup */ + usb_deregister(&smsusb_driver); + printk(KERN_INFO "%s\n", __FUNCTION__); +} + diff --git a/drivers/media/mdtv/Kconfig b/drivers/media/mdtv/Kconfig deleted file mode 100644 index a7faca0b7020..000000000000 --- a/drivers/media/mdtv/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# -# Mobile Digital TV device configuration -# - -config MDTV_SIANO_STELLAR_USB - tristate "Siano SMS10xx USB dongle support" - default m - ---help--- - Choose Y here if you have USB dongle with SMS10xx chipset. - - Further documentation on this driver can be found on the WWW at - . - - To compile this driver as a module, choose M here: the - modules will be called smschar and smsnet. - diff --git a/drivers/media/mdtv/Makefile b/drivers/media/mdtv/Makefile deleted file mode 100644 index 16b9c488c9d1..000000000000 --- a/drivers/media/mdtv/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -smscore-objs := smscoreapi.o smsusb.o smsdvb.o - -obj-$(CONFIG_MDTV_SIANO_STELLAR_USB) += smscore.o - -EXTRA_CFLAGS += -Idrivers/media/video -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) - diff --git a/drivers/media/mdtv/smscoreapi.c b/drivers/media/mdtv/smscoreapi.c deleted file mode 100644 index b261fe2cee5e..000000000000 --- a/drivers/media/mdtv/smscoreapi.c +++ /dev/null @@ -1,1178 +0,0 @@ - -/* - * Driver for the Siano SMS10xx USB dongle - * - * Copyright (c) 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*! - - \file smscoreapi.c - - \brief Siano core API module - This file contains implementation for the interface to sms core component - - \par Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - - \par This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 3 as - published by the Free Software Foundation; - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. - - \author Anatoly Greenblat - -*/ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "smscoreapi.h" - -typedef struct _smscore_device_notifyee -{ - struct list_head entry; - hotplug_t hotplug; -} smscore_device_notifyee_t; - -typedef struct _smscore_client -{ - struct list_head entry; - smscore_device_t *coredev; - - void *context; - - int data_type; - - onresponse_t onresponse_handler; - onremove_t onremove_handler; -} *psmscore_client_t; - -typedef struct _smscore_subclient -{ - struct list_head entry; - smscore_client_t *client; - - int id; -} smscore_subclient_t; - -typedef struct _smscore_device -{ - struct list_head entry; - - struct list_head clients; - struct list_head subclients; - spinlock_t clientslock; - - struct list_head buffers; - spinlock_t bufferslock; - int num_buffers; - - void *common_buffer; - int common_buffer_size; - dma_addr_t common_buffer_phys; - - void *context; - struct device *device; - - char devpath[32]; - unsigned long device_flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - int mode, modes_supported; - - struct completion version_ex_done, data_download_done, trigger_done; - struct completion init_device_done, reload_start_done, resume_done; -} *psmscore_device_t; - -typedef struct _smscore_registry_entry -{ - struct list_head entry; - char devpath[32]; - int mode; -} smscore_registry_entry_t; - -struct list_head g_smscore_notifyees; -struct list_head g_smscore_devices; -kmutex_t g_smscore_deviceslock; - -struct list_head g_smscore_registry; -kmutex_t g_smscore_registrylock; - -static int default_mode = 1; -module_param(default_mode, int, 0644); -MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); - -int smscore_registry_getmode(char* devpath) -{ - smscore_registry_entry_t *entry; - struct list_head *next; - - kmutex_lock(&g_smscore_registrylock); - - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) - { - entry = (smscore_registry_entry_t *) next; - - if (!strcmp(entry->devpath, devpath)) - { - kmutex_unlock(&g_smscore_registrylock); - return entry->mode; - } - } - - entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); - if (entry) - { - entry->mode = default_mode; - strcpy(entry->devpath, devpath); - - list_add(&entry->entry, &g_smscore_registry); - } - - kmutex_unlock(&g_smscore_registrylock); - - return default_mode; -} - -void smscore_registry_setmode(char* devpath, int mode) -{ - smscore_registry_entry_t *entry; - struct list_head *next; - - kmutex_lock(&g_smscore_registrylock); - - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) - { - entry = (smscore_registry_entry_t *) next; - - if (!strcmp(entry->devpath, devpath)) - { - entry->mode = mode; - break; - } - } - - kmutex_unlock(&g_smscore_registrylock); -} - - -void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock) -{ - unsigned long flags; - - spin_lock_irqsave(lock, flags); - - list_add(new, head); - - spin_unlock_irqrestore(lock, flags); -} - -/** - * register a client callback that called when device plugged in/unplugged - * NOTE: if devices exist callback is called immediately for each device - * - * @param hotplug callback - * - * @return 0 on success, <0 on error. - */ -int smscore_register_hotplug(hotplug_t hotplug) -{ - smscore_device_notifyee_t *notifyee; - struct list_head *next, *first; - int rc = 0; - - kmutex_lock(&g_smscore_deviceslock); - - notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); - if (notifyee) - { - // now notify callback about existing devices - first = &g_smscore_devices; - for (next = first->next; next != first && !rc; next = next->next) - { - smscore_device_t *coredev = (smscore_device_t *) next; - rc = hotplug(coredev, coredev->device, 1); - } - - if (rc >= 0) - { - notifyee->hotplug = hotplug; - list_add(¬ifyee->entry, &g_smscore_notifyees); - } - else - kfree(notifyee); - } - else - rc = -ENOMEM; - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} - -/** - * unregister a client callback that called when device plugged in/unplugged - * - * @param hotplug callback - * - */ -void smscore_unregister_hotplug(hotplug_t hotplug) -{ - struct list_head *next, *first; - - kmutex_lock(&g_smscore_deviceslock); - - first = &g_smscore_notifyees; - - for (next = first->next; next != first;) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next; - next = next->next; - - if (notifyee->hotplug == hotplug) - { - list_del(¬ifyee->entry); - kfree(notifyee); - } - } - - kmutex_unlock(&g_smscore_deviceslock); -} - -void smscore_notify_clients(smscore_device_t *coredev) -{ - smscore_client_t* client; - - // the client must call smscore_unregister_client from remove handler - while (!list_empty(&coredev->clients)) - { - client = (smscore_client_t *) coredev->clients.next; - client->onremove_handler(client->context); - } -} - -int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival) -{ - struct list_head *next, *first; - int rc = 0; - - // note: must be called under g_deviceslock - - first = &g_smscore_notifyees; - - for (next = first->next; next != first; next = next->next) - { - rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); - if (rc < 0) - break; - } - - return rc; -} - -smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys) -{ - smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); - if (!cb) - { - printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__); - return NULL; - } - - cb->p = buffer; - cb->offset_in_common = buffer - (u8*) common_buffer; - cb->phys = common_buffer_phys + cb->offset_in_common; - - return cb; -} - -/** - * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies - * registered hotplugs about new device. - * - * @param params device pointer to struct with device specific parameters and handlers - * @param coredev pointer to a value that receives created coredev object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) -{ - smscore_device_t* dev; - u8 *buffer; - - dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); - if (!dev) - { - printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__); - return -ENOMEM; - } - - // init list entry so it could be safe in smscore_unregister_device - INIT_LIST_HEAD(&dev->entry); - - // init queues - INIT_LIST_HEAD(&dev->clients); - INIT_LIST_HEAD(&dev->subclients); - INIT_LIST_HEAD(&dev->buffers); - - // init locks - spin_lock_init(&dev->clientslock); - spin_lock_init(&dev->bufferslock); - - // init completion events - init_completion(&dev->version_ex_done); - init_completion(&dev->data_download_done); - init_completion(&dev->trigger_done); - init_completion(&dev->init_device_done); - init_completion(&dev->reload_start_done); - init_completion(&dev->resume_done); - - // alloc common buffer - dev->common_buffer_size = params->buffer_size * params->num_buffers; - dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA); - if (!dev->common_buffer) - { - smscore_unregister_device(dev); - return -ENOMEM; - } - - // prepare dma buffers - for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers ++, buffer += params->buffer_size) - { - smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); - if (!cb) - { - smscore_unregister_device(dev); - return -ENOMEM; - } - - smscore_putbuffer(dev, cb); - } - - printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers); - - dev->mode = DEVICE_MODE_NONE; - dev->context = params->context; - dev->device = params->device; - dev->setmode_handler = params->setmode_handler; - dev->detectmode_handler = params->detectmode_handler; - dev->sendrequest_handler = params->sendrequest_handler; - dev->preload_handler = params->preload_handler; - dev->postload_handler = params->postload_handler; - - dev->device_flags = params->flags; - strcpy(dev->devpath, params->devpath); - - // add device to devices list - kmutex_lock(&g_smscore_deviceslock); - list_add(&dev->entry, &g_smscore_devices); - kmutex_unlock(&g_smscore_deviceslock); - - *coredev = dev; - - printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); - - return 0; -} - -/** - * sets initial device mode and notifies client hotplugs that device is ready - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * - * @return 0 on success, <0 on error. - */ -int smscore_start_device(smscore_device_t *coredev) -{ - int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); - if (rc < 0) - return rc; - - kmutex_lock(&g_smscore_deviceslock); - - rc = smscore_notify_callbacks(coredev, coredev->device, 1); - - printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc); - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} - -int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion) -{ - int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) - return rc; - - return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME; -} - -int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) -{ - SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; - SmsMsgHdr_ST *msg; - UINT32 mem_address = firmware->StartAddress; - u8* payload = firmware->Payload; - int rc = 0; - - if (coredev->preload_handler) - { - rc = coredev->preload_handler(coredev->context); - if (rc < 0) - return rc; - } - - // PAGE_SIZE buffer shall be enough and dma aligned - msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); - if (!msg) - return -ENOMEM; - - if (coredev->mode != DEVICE_MODE_NONE) - { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); - mem_address = *(UINT32*) &payload[20]; - } - - while (size && rc >= 0) - { - SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; - int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + payload_size)); - - DataMsg->MemAddr = mem_address; - memcpy(DataMsg->Payload, payload, payload_size); - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE && coredev->mode == DEVICE_MODE_NONE) - rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); - else - rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); - - payload += payload_size; - size -= payload_size; - mem_address += payload_size; - } - - if (rc >= 0) - { - if (coredev->mode == DEVICE_MODE_NONE) - { - SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg; - - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5); - - TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point - TriggerMsg->msgData[1] = 5; // Priority - TriggerMsg->msgData[2] = 0x200; // Stack size - TriggerMsg->msgData[3] = 0; // Parameter - TriggerMsg->msgData[4] = 4; // Task ID - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) - { - rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); - msleep(100); - } - else - rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); - } - else - { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); - - rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); - } - } - - printk("%s %d \n", __func__, rc); - - kfree(msg); - - return (rc >= 0 && coredev->postload_handler) ? - coredev->postload_handler(coredev->context) : - rc; -} - -/** - * loads specified firmware into a buffer and calls device loadfirmware_handler - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * @param filename null-terminated string specifies firmware file name - * @param loadfirmware_handler device handler that loads firmware - * - * @return 0 on success, <0 on error. - */ -int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler) -{ - int rc = -ENOENT; - - const struct firmware *fw; - u8* fw_buffer; - - if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) - return -EINVAL; - - rc = request_firmware(&fw, filename, coredev->device); - if (rc < 0) - { - printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename); - return rc; - } - - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); - if (fw_buffer) - { - memcpy(fw_buffer, fw->data, fw->size); - - rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : - loadfirmware_handler(coredev->context, fw_buffer, fw->size); - - kfree(fw_buffer); - } - else - { - printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__); - rc = -ENOMEM; - } - - release_firmware(fw); - - return rc; -} - -/** - * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * - * @return 0 on success, <0 on error. - */ -void smscore_unregister_device(smscore_device_t *coredev) -{ - smscore_buffer_t *cb; - int num_buffers = 0; - - kmutex_lock(&g_smscore_deviceslock); - - smscore_notify_clients(coredev); - smscore_notify_callbacks(coredev, NULL, 0); - - // at this point all buffers should be back - // onresponse must no longer be called - - while (1) - { - while ((cb = smscore_getbuffer(coredev))) - { - kfree(cb); - num_buffers ++; - } - - if (num_buffers == coredev->num_buffers) - break; - - printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers); - msleep(100); - } - - printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers); - - if (coredev->common_buffer) - dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); - - list_del(&coredev->entry); - kfree(coredev); - - kmutex_unlock(&g_smscore_deviceslock); - - printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev); -} - -int smscore_detect_mode(smscore_device_t *coredev) -{ - void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); - int rc; - - if (!buffer) - return -ENOMEM; - - SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); - - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); - if (rc == -ETIME) - { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__); - - if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) - { - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); - if (rc < 0) - { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc); - } - } - else - rc = -ETIME; - } - - kfree(buffer); - - return rc; -} - -char *smscore_fw_lkup[] = -{ - "dvb_nova_12mhz.inp", - "dvb_nova_12mhz.inp", - "tdmb_nova.inp", - "none", - "dvb_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "cmmb_nova_12mhz.inp", - "none", -}; - -/** - * calls device handler to change mode of operation - * NOTE: stellar/usb may disconnect when changing mode - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * @param mode requested mode of operation - * - * @return 0 on success, <0 on error. - */ -int smscore_set_device_mode(smscore_device_t *coredev, int mode) -{ - void *buffer; - int rc = 0; - - if (coredev->device_flags & SMS_DEVICE_FAMILY2) - { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) - { - printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode); - return -EINVAL; - } - - if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) - { - rc = smscore_detect_mode(coredev); - if (rc < 0) - return rc; - } - - if (coredev->mode == mode) - { - printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode); - return 0; - } - - if (!(coredev->modes_supported & (1 << mode))) - { - rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL); - if (rc < 0) - return rc; - } - else - { - printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode); - } - - buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) - { - SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); - msg->msgData[0] = mode; - - rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); - - kfree(buffer); - } - else - rc = -ENOMEM; - } - else - { - if (coredev->detectmode_handler) - coredev->detectmode_handler(coredev->context, &coredev->mode); - - if (coredev->mode != mode && coredev->setmode_handler) - rc = coredev->setmode_handler(coredev->context, mode); - } - - smscore_registry_setmode(coredev->devpath, mode); - - if (rc >= 0) - { - coredev->mode = mode; - coredev->device_flags &= ~SMS_DEVICE_NOT_READY; - } - - return rc; -} - -/** - * calls device handler to get current mode of operation - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * - * @return current mode - */ -int smscore_get_device_mode(smscore_device_t *coredev) -{ - return coredev->mode; -} - -smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type) -{ - smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - - if (!data_type) - return NULL; - - spin_lock_irqsave(&coredev->clientslock, flags); - - first = &coredev->clients; - - for (next = first->next; next != first; next = next->next) - { - if (((smscore_client_t*) next)->data_type == data_type) - { - client = (smscore_client_t*) next; - break; - } - } - - spin_unlock_irqrestore(&coredev->clientslock, flags); - - return client; -} - -smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) -{ - smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - first = &coredev->subclients; - - for (next = first->next; next != first; next = next->next) - { - if (((smscore_subclient_t*) next)->id == id) - { - client = ((smscore_subclient_t*) next)->client; - break; - } - } - - spin_unlock_irqrestore(&coredev->clientslock, flags); - - return client; -} - -/** - * find client by response id/type, call clients onresponse handler - * return buffer to pool on error - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * @param cb pointer to response buffer descriptor - * - */ -void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) -{ - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); - smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType); - int rc = -EBUSY; - - static unsigned long last_sample_time = 0; - static int data_total = 0; - unsigned long time_now = jiffies_to_msecs(jiffies); - - if (!last_sample_time) - last_sample_time = time_now; - - if (time_now - last_sample_time > 10000) - { - printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); - - last_sample_time = time_now; - data_total = 0; - } - - data_total += cb->size; - - if (!client) - client = smscore_getclient_by_id(coredev, phdr->msgDstId); - - if (client) - rc = client->onresponse_handler(client->context, cb); - - if (rc < 0) - { - switch (phdr->msgType) - { - case MSG_SMS_GET_VERSION_EX_RES: - { - SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; - printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); - - coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; - coredev->modes_supported = ver->SupportedProtocols; - - complete(&coredev->version_ex_done); - break; - } - - case MSG_SMS_INIT_DEVICE_RES: - printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__); - complete(&coredev->init_device_done); - break; - - case MSG_SW_RELOAD_START_RES: - printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__); - complete(&coredev->reload_start_done); - break; - - case MSG_SMS_DATA_DOWNLOAD_RES: - complete(&coredev->data_download_done); - break; - - case MSG_SW_RELOAD_EXEC_RES: - printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__); - break; - - case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__); - complete(&coredev->trigger_done); - break; - - case MSG_SMS_SLEEP_RESUME_COMP_IND: - complete(&coredev->resume_done); - break; - - default: - printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId); - } - - smscore_putbuffer(coredev, cb); - } -} - -/** - * return pointer to next free buffer descriptor from core pool - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * - * @return pointer to descriptor on success, NULL on error. - */ -smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) -{ - smscore_buffer_t *cb = NULL; - unsigned long flags; - - spin_lock_irqsave(&coredev->bufferslock, flags); - - if (!list_empty(&coredev->buffers)) - { - cb = (smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - } - - spin_unlock_irqrestore(&coredev->bufferslock, flags); - - return cb; -} - -/** - * return buffer descriptor to a pool - * - * @param coredev pointer to a coredev object returned by smscore_register_device - * @param cb pointer buffer descriptor - * - */ -void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) -{ - list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); -} - -int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id) -{ - smscore_client_t *existing_client; - smscore_subclient_t *subclient; - - if (!id) - return 0; - - existing_client = smscore_getclient_by_id(coredev, id); - if (existing_client == client) - return 0; - - if (existing_client) - return -EBUSY; - - subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL); - if (!subclient) - return -ENOMEM; - - subclient->client = client; - subclient->id = id; - - list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock); - - return 0; -} - -/** - * creates smsclient object, check that id is taken by another client - * - * @param coredev pointer to a coredev object from clients hotplug - * @param initial_id all messages with this id would be sent to this client - * @param data_type all messages of this type would be sent to this client - * @param onresponse_handler client handler that is called to process incoming messages - * @param onremove_handler client handler that is called when device is removed - * @param context client-specific context - * @param client pointer to a value that receives created smsclient object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) -{ - smscore_client_t* newclient; - int rc; - - // check that no other channel with same data type exists - if (params->data_type && smscore_getclient_by_type(coredev, params->data_type)) - return -EEXIST; - - newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); - if (!newclient) - return -ENOMEM; - - // check that no other channel with same id exists - rc = smscore_validate_client(coredev, newclient, params->initial_id); - if (rc < 0) - { - kfree(newclient); - return rc; - } - - newclient->coredev = coredev; - newclient->data_type = params->data_type; - newclient->onresponse_handler = params->onresponse_handler; - newclient->onremove_handler = params->onremove_handler; - newclient->context = params->context; - - list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); - - *client = newclient; - - printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id); - - return 0; -} - -/** - * frees smsclient object and all subclients associated with it - * - * @param client pointer to smsclient object returned by smscore_register_client - * - */ -void smscore_unregister_client(smscore_client_t *client) -{ - smscore_device_t *coredev = client->coredev; - struct list_head *next, *first; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - first = &coredev->subclients; - - for (next = first->next; next != first;) - { - smscore_subclient_t *subclient = (smscore_subclient_t *) next; - next = next->next; - - if (subclient->client == client) - { - list_del(&subclient->entry); - kfree(subclient); - } - } - - printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type); - - list_del(&client->entry); - kfree(client); - - spin_unlock_irqrestore(&coredev->clientslock, flags); -} - -/** - * verifies that source id is not taken by another client, - * calls device handler to send requests to the device - * - * @param client pointer to smsclient object returned by smscore_register_client - * @param buffer pointer to a request buffer - * @param size size (in bytes) of request buffer - * - * @return 0 on success, <0 on error. - */ -int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) -{ - smscore_device_t* coredev = client->coredev; - SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; - - // check that no other channel with same id exists - int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId); - if (rc < 0) - return rc; - - return coredev->sendrequest_handler(coredev->context, buffer, size); -} - -/** - * return the size of large (common) buffer - * - * @param coredev pointer to a coredev object from clients hotplug - * - * @return size (in bytes) of the buffer - */ -int smscore_get_common_buffer_size(smscore_device_t *coredev) -{ - return coredev->common_buffer_size; -} - -/** - * maps common buffer (if supported by platform) - * - * @param coredev pointer to a coredev object from clients hotplug - * @param vma pointer to vma struct from mmap handler - * - * @return 0 on success, <0 on error. - */ -int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma) -{ - unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); - - if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) - { - printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__); - return -EINVAL; - } - - if ((end - start) != size) - { - printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (int)(end - start), (int) size); - return -EINVAL; - } - - if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) - { - printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__); - return -EAGAIN; - } - - return 0; -} - -int smscore_module_init(void) -{ - int rc = 0; - - INIT_LIST_HEAD(&g_smscore_notifyees); - INIT_LIST_HEAD(&g_smscore_devices); - kmutex_init(&g_smscore_deviceslock); - - INIT_LIST_HEAD(&g_smscore_registry); - kmutex_init(&g_smscore_registrylock); - - /* USB Register */ - rc = smsusb_register(); - - /* DVB Register */ - rc = smsdvb_register(); - - printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); - - return rc; -} - -void smscore_module_exit(void) -{ - - kmutex_lock(&g_smscore_deviceslock); - while (!list_empty(&g_smscore_notifyees)) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next; - - list_del(¬ifyee->entry); - kfree(notifyee); - } - kmutex_unlock(&g_smscore_deviceslock); - - kmutex_lock(&g_smscore_registrylock); - while (!list_empty(&g_smscore_registry)) - { - smscore_registry_entry_t *entry = (smscore_registry_entry_t *) g_smscore_registry.next; - - list_del(&entry->entry); - kfree(entry); - } - kmutex_unlock(&g_smscore_registrylock); - - /* DVB UnRegister */ - smsdvb_unregister(); - - /* Unregister USB */ - smsusb_unregister(); - - printk(KERN_INFO "%s\n", __FUNCTION__); -} - -module_init(smscore_module_init); -module_exit(smscore_module_exit); - -MODULE_DESCRIPTION("smscore"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/mdtv/smscoreapi.h b/drivers/media/mdtv/smscoreapi.h deleted file mode 100644 index 53c1d35da68f..000000000000 --- a/drivers/media/mdtv/smscoreapi.h +++ /dev/null @@ -1,531 +0,0 @@ -/* - * Driver for the Siano SMS10xx USB dongle - * - * Copyright (c) 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __smscoreapi_h__ -#define __smscoreapi_h__ - -#include -#include -#include -#include -#include -#include - -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - -#include - -typedef struct mutex kmutex_t; - -#define kmutex_init(_p_) mutex_init(_p_) -#define kmutex_lock(_p_) mutex_lock(_p_) -#define kmutex_trylock(_p_) mutex_trylock(_p_) -#define kmutex_unlock(_p_) mutex_unlock(_p_) - - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#define SMS_ALLOC_ALIGNMENT 128 -#define SMS_DMA_ALIGNMENT 16 -#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) - -#define SMS_DEVICE_FAMILY2 1 -#define SMS_ROM_NO_RESPONSE 2 -#define SMS_DEVICE_NOT_READY 0x8000000 - -typedef struct _smscore_device smscore_device_t; -typedef struct _smscore_client smscore_client_t; -typedef struct _smscore_buffer smscore_buffer_t; - -typedef int (*hotplug_t)(smscore_device_t *coredev, struct device *device, int arrival); - -typedef int (*setmode_t)(void *context, int mode); -typedef void (*detectmode_t)(void *context, int *mode); -typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); -typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); -typedef int (*preload_t)(void *context); -typedef int (*postload_t)(void *context); - -typedef int (*onresponse_t)(void *context, smscore_buffer_t *cb); -typedef void (*onremove_t)(void *context); - -typedef struct _smscore_buffer -{ - // public members, once passed to clients can be changed freely - struct list_head entry; - int size; - int offset; - - // private members, read-only for clients - void *p; - dma_addr_t phys; - unsigned long offset_in_common; -} *psmscore_buffer_t; - -typedef struct _smsdevice_params -{ - struct device *device; - - int buffer_size; - int num_buffers; - - char devpath[32]; - unsigned long flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - void *context; -} smsdevice_params_t; - -typedef struct _smsclient_params -{ - int initial_id; - int data_type; - onresponse_t onresponse_handler; - onremove_t onremove_handler; - - void *context; -} smsclient_params_t; - -// GPIO definitions for antenna frequency domain control (SMS8021) -#define SMS_ANTENNA_GPIO_0 1 -#define SMS_ANTENNA_GPIO_1 0 - -#define BW_8_MHZ 0 -#define BW_7_MHZ 1 -#define BW_6_MHZ 2 -#define BW_5_MHZ 3 -#define BW_ISDBT_1SEG 4 -#define BW_ISDBT_3SEG 5 - -#define MSG_HDR_FLAG_SPLIT_MSG 4 - -#define MAX_GPIO_PIN_NUMBER 31 - -#define HIF_TASK 11 -#define SMS_HOST_LIB 150 -#define DVBT_BDA_CONTROL_MSG_ID 201 - -#define SMS_MAX_PAYLOAD_SIZE 240 -#define SMS_TUNE_TIMEOUT 500 - -#define MSG_SMS_GPIO_CONFIG_REQ 507 -#define MSG_SMS_GPIO_CONFIG_RES 508 -#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 -#define MSG_SMS_GPIO_SET_LEVEL_RES 510 -#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 -#define MSG_SMS_GPIO_GET_LEVEL_RES 512 -#define MSG_SMS_RF_TUNE_REQ 561 -#define MSG_SMS_RF_TUNE_RES 562 -#define MSG_SMS_INIT_DEVICE_REQ 578 -#define MSG_SMS_INIT_DEVICE_RES 579 -#define MSG_SMS_ADD_PID_FILTER_REQ 601 -#define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_GET_STATISTICS_RES 616 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_GET_STATISTICS_EX_REQ 653 -#define MSG_SMS_GET_STATISTICS_EX_RES 654 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 -#define MSG_SMS_DATA_DOWNLOAD_REQ 660 -#define MSG_SMS_DATA_DOWNLOAD_RES 661 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 -#define MSG_SMS_GET_VERSION_EX_REQ 668 -#define MSG_SMS_GET_VERSION_EX_RES 669 -#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 -#define MSG_SMS_I2C_SET_FREQ_REQ 685 -#define MSG_SMS_GENERIC_I2C_REQ 687 -#define MSG_SMS_GENERIC_I2C_RES 688 -#define MSG_SMS_DVBT_BDA_DATA 693 -#define MSG_SW_RELOAD_REQ 697 -#define MSG_SMS_DATA_MSG 699 -#define MSG_SW_RELOAD_START_REQ 702 -#define MSG_SW_RELOAD_START_RES 703 -#define MSG_SW_RELOAD_EXEC_REQ 704 -#define MSG_SW_RELOAD_EXEC_RES 705 -#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 -#define MSG_SMS_ISDBT_TUNE_REQ 776 -#define MSG_SMS_ISDBT_TUNE_RES 777 - -#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ - (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ - (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ -} while (0) -#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) - -typedef enum -{ - DEVICE_MODE_NONE = -1, - DEVICE_MODE_DVBT = 0, - DEVICE_MODE_DVBH, - DEVICE_MODE_DAB_TDMB, - DEVICE_MODE_DAB_TDMB_DABIP, - DEVICE_MODE_DVBT_BDA, - DEVICE_MODE_ISDBT, - DEVICE_MODE_ISDBT_BDA, - DEVICE_MODE_CMMB, - DEVICE_MODE_RAW_TUNER, - DEVICE_MODE_MAX, -} SMS_DEVICE_MODE; - -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -typedef int INT32; - -typedef struct SmsMsgHdr_S -{ - UINT16 msgType; - UINT8 msgSrcId; - UINT8 msgDstId; - UINT16 msgLength; // Length is of the entire message, including header - UINT16 msgFlags; -} SmsMsgHdr_ST; - -typedef struct SmsMsgData_S -{ - SmsMsgHdr_ST xMsgHeader; - UINT32 msgData[1]; -} SmsMsgData_ST; - -typedef struct SmsDataDownload_S -{ - SmsMsgHdr_ST xMsgHeader; - UINT32 MemAddr; - UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; -} SmsDataDownload_ST; - -typedef struct SmsVersionRes_S -{ - SmsMsgHdr_ST xMsgHeader; - - UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" - UINT8 Step; // 0 - Step A - UINT8 MetalFix; // 0 - Metal 0 - - UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E - UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols - - UINT8 VersionMajor; - UINT8 VersionMinor; - UINT8 VersionPatch; - UINT8 VersionFieldPatch; - - UINT8 RomVersionMajor; - UINT8 RomVersionMinor; - UINT8 RomVersionPatch; - UINT8 RomVersionFieldPatch; - - UINT8 TextLabel[34]; -} SmsVersionRes_ST; - -typedef struct SmsFirmware_S -{ - UINT32 CheckSum; - UINT32 Length; - UINT32 StartAddress; - UINT8 Payload[1]; -} SmsFirmware_ST; - -typedef struct SMSHOSTLIB_STATISTICS_S -{ - UINT32 Reserved; //!< Reserved - - /// Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - /// Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - /// Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H - UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos - UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H - UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H - UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H - - /// Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding - /// Common params - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - - /// Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - - /// DAB/T-DMB - UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] - - /// DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered - -} SMSHOSTLIB_STATISTICS_ST; - -typedef struct -{ - UINT32 RequestResult; - - SMSHOSTLIB_STATISTICS_ST Stat; - - // Split the calc of the SNR in DAB - UINT32 Signal; //!< dB - UINT32 Noise; //!< dB - -} SmsMsgStatisticsInfo_ST; - -typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S -{ - // Per-layer information - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist - UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count - UINT32 BERBitCount; //!< Post Viterbi Total Bits Count - UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist - UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist - UINT32 TMCCErrors; //!< TMCC errors -} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S -{ - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in Hz - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 TransmissionMode; //!< ISDB-T transmission mode - UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) - UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise - UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network - - // Per-layer information - // Layers A, B and C - SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - -} SMSHOSTLIB_STATISTICS_ISDBT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_DVB_S -{ - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET - UINT32 TransmissionMode; //!< FFT mode carriers in Kilos - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET - - // Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H - UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received - - // DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered - UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - -} SMSHOSTLIB_STATISTICS_DVB_ST; - -typedef struct SMSHOSTLIB_GPIO_CONFIG_S -{ - UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 - UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 - UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 - UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 - UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 -} SMSHOSTLIB_GPIO_CONFIG_ST; - -typedef struct SMSHOSTLIB_I2C_REQ_S -{ - UINT32 DeviceAddress; // I2c device address - UINT32 WriteCount; // number of bytes to write - UINT32 ReadCount; // number of bytes to read - UINT8 Data[1]; -} SMSHOSTLIB_I2C_REQ_ST; - -typedef struct SMSHOSTLIB_I2C_RES_S -{ - UINT32 Status; // non-zero value in case of failure - UINT32 ReadCount; // number of bytes read - UINT8 Data[1]; -} SMSHOSTLIB_I2C_RES_ST; - -typedef struct _smsdvb_client -{ - struct list_head entry; - - smscore_device_t *coredev; - smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_signal_strength; - - struct completion tune_done, stat_done; - - // todo: save freq/band instead whole struct - struct dvb_frontend_parameters fe_params; - -} smsdvb_client_t; - -extern void smscore_registry_setmode(char *devpath, int mode); -extern int smscore_registry_getmode(char *devpath); - -extern int smscore_register_hotplug(hotplug_t hotplug); -extern void smscore_unregister_hotplug(hotplug_t hotplug); - -extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev); -extern void smscore_unregister_device(smscore_device_t *coredev); - -extern int smscore_start_device(smscore_device_t *coredev); -extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler); - -extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); -extern int smscore_get_device_mode(smscore_device_t *coredev); - -extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client); -extern void smscore_unregister_client(smscore_client_t *client); - -extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size); -extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb); - -extern int smscore_get_common_buffer_size(smscore_device_t *coredev); -extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma); - -extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); -extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); - -/* smsdvb.c */ -int smsdvb_register(void); -void smsdvb_unregister(void); - -/* smsusb.c */ -int smsusb_register(void); -void smsusb_unregister(void); - -#endif // __smscoreapi_h__ diff --git a/drivers/media/mdtv/smsdvb.c b/drivers/media/mdtv/smsdvb.c deleted file mode 100644 index f56658c5599d..000000000000 --- a/drivers/media/mdtv/smsdvb.c +++ /dev/null @@ -1,425 +0,0 @@ -/* - * Driver for the Siano SMS10xx USB dongle - * - * Copyright (c) 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include - -#include "smscoreapi.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct list_head g_smsdvb_clients; -kmutex_t g_smsdvb_clientslock; - -int smsdvb_onresponse(void *context, smscore_buffer_t *cb) -{ - smsdvb_client_t *client = (smsdvb_client_t *) context; - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset); - - switch(phdr->msgType) - { - case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST)); - break; - - case MSG_SMS_RF_TUNE_RES: - complete(&client->tune_done); - break; - - case MSG_SMS_GET_STATISTICS_RES: - { - SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1); - - if (p->Stat.IsDemodLocked) - { - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - client->fe_snr = p->Stat.SNR; - client->fe_ber = p->Stat.BER; - - if (p->Stat.InBandPwr < -95) - client->fe_signal_strength = 0; - else if (p->Stat.InBandPwr > -29) - client->fe_signal_strength = 100; - else - client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2; - } - else - { - client->fe_status = 0; - client->fe_snr = - client->fe_ber = - client->fe_signal_strength = 0; - } - - complete(&client->stat_done); - break; - } - } - - smscore_putbuffer(client->coredev, cb); - - return 0; -} - -void smsdvb_unregister_client(smsdvb_client_t* client) -{ - // must be called under clientslock - - list_del(&client->entry); - - smscore_unregister_client(client->smsclient); - dvb_unregister_frontend(&client->frontend); - dvb_dmxdev_release(&client->dmxdev); - dvb_dmx_release(&client->demux); - dvb_unregister_adapter(&client->adapter); - kfree(client); -} - -void smsdvb_onremove(void *context) -{ - kmutex_lock(&g_smsdvb_clientslock); - - smsdvb_unregister_client((smsdvb_client_t*) context); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -static int smsdvb_start_feed(struct dvb_demux_feed *feed) -{ - smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); - SmsMsgData_ST PidMsg; - - printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_stop_feed(struct dvb_demux_feed *feed) -{ - smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); - SmsMsgData_ST PidMsg; - - printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion) -{ - int rc = smsclient_sendrequest(client->smsclient, buffer, size); - if (rc < 0) - return rc; - - return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME; -} - -static int smsdvb_send_statistics_request(smsdvb_client_t *client) -{ - SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done); -} - -static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *stat = client->fe_status; - - return rc; -} - -static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *ber = client->fe_ber; - - return rc; -} - -static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *strength = client->fe_signal_strength; - - return rc; -} - -static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *snr = client->fe_snr; - - return rc; -} - -static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) -{ - printk("%s\n", __FUNCTION__); - - tune->min_delay_ms = 400; - tune->step_size = 250000; - tune->max_drift = 0; - return 0; -} - -static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - - struct - { - SmsMsgHdr_ST Msg; - u32 Data[3]; - } Msg; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - Msg.Data[0] = fep->frequency; - Msg.Data[2] = 12000000; - - printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth); - - switch(fep->u.ofdm.bandwidth) - { - case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; - case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; - case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; -// case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: return -EINVAL; - } - - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); -} - -static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) -{ - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - - printk("%s\n", __FUNCTION__); - - // todo: - memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); - return 0; -} - -static void smsdvb_release(struct dvb_frontend *fe) -{ - // do nothing -} - -static struct dvb_frontend_ops smsdvb_fe_ops = { - .info = { - .name = "Siano Mobile Digital SMS10xx", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = smsdvb_release, - - .set_frontend = smsdvb_set_frontend, - .get_frontend = smsdvb_get_frontend, - .get_tune_settings = smsdvb_get_tune_settings, - - .read_status = smsdvb_read_status, - .read_ber = smsdvb_read_ber, - .read_signal_strength = smsdvb_read_signal_strength, - .read_snr = smsdvb_read_snr, -}; - -int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival) -{ - smsclient_params_t params; - smsdvb_client_t* client; - int rc; - - // device removal handled by onremove callback - if (!arrival) - return 0; - - if (smscore_get_device_mode(coredev) != 4) - { - rc = smscore_set_device_mode(coredev, 4); - if (rc < 0) - return rc; - } - - client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); - if (!client) - { - printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); - return -ENOMEM; - } - - // register dvb adapter - rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); - if (rc < 0) - { - printk("%s dvb_register_adapter() failed %d\n", __func__, rc); - goto adapter_error; - } - - // init dvb demux - client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; // todo: nova ??? - client->demux.feednum = 32; - client->demux.start_feed = smsdvb_start_feed; - client->demux.stop_feed = smsdvb_stop_feed; - - rc = dvb_dmx_init(&client->demux); - if (rc < 0) - { - printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc); - goto dvbdmx_error; - } - - // init dmxdev - client->dmxdev.filternum = 32; - client->dmxdev.demux = &client->demux.dmx; - client->dmxdev.capabilities = 0; - - rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); - if (rc < 0) - { - printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc); - goto dmxdev_error; - } - - // init and register frontend - memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); - - rc = dvb_register_frontend(&client->adapter, &client->frontend); - if (rc < 0) - { - printk("%s frontend registration failed %d\n", __FUNCTION__, rc); - goto frontend_error; - } - - params.initial_id = 0; - params.data_type = MSG_SMS_DVBT_BDA_DATA; - params.onresponse_handler = smsdvb_onresponse; - params.onremove_handler = smsdvb_onremove; - params.context = client; - - rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); - goto client_error; - } - - client->coredev = coredev; - - init_completion(&client->tune_done); - init_completion(&client->stat_done); - - kmutex_lock(&g_smsdvb_clientslock); - - list_add(&client->entry, &g_smsdvb_clients); - - kmutex_unlock(&g_smsdvb_clientslock); - - printk(KERN_INFO "%s success\n", __FUNCTION__); - - return 0; - -client_error: - dvb_unregister_frontend(&client->frontend); - -frontend_error: - dvb_dmxdev_release(&client->dmxdev); - -dmxdev_error: - dvb_dmx_release(&client->demux); - -dvbdmx_error: - dvb_unregister_adapter(&client->adapter); - -adapter_error: - kfree(client); - return rc; -} - -int smsdvb_register(void) -{ - int rc; - - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - rc = smscore_register_hotplug(smsdvb_hotplug); - - printk(KERN_INFO "%s\n", __FUNCTION__); - - return rc; -} - -void smsdvb_unregister(void) -{ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); - - kmutex_unlock(&g_smsdvb_clientslock); - -} - diff --git a/drivers/media/mdtv/smsusb.c b/drivers/media/mdtv/smsusb.c deleted file mode 100644 index c0f77a328ca9..000000000000 --- a/drivers/media/mdtv/smsusb.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Driver for the Siano SMS10xx USB dongle - * - * Copyright (c) 2008 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include -#include - -#include "smscoreapi.h" - -#define USB1_BUFFER_SIZE 0x1000 -#define USB2_BUFFER_SIZE 0x4000 - -#define MAX_BUFFERS 50 -#define MAX_URBS 10 - -typedef struct _smsusb_device smsusb_device_t; - -typedef struct _smsusb_urb -{ - smscore_buffer_t *cb; - smsusb_device_t *dev; - - struct urb urb; -} smsusb_urb_t; - -typedef struct _smsusb_device -{ - struct usb_device* udev; - smscore_device_t *coredev; - - smsusb_urb_t surbs[MAX_URBS]; - - int response_alignment; - int buffer_size; -} *psmsusb_device_t; - -int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb); - -void smsusb_onresponse(struct urb *urb) -{ - smsusb_urb_t *surb = (smsusb_urb_t *) urb->context; - smsusb_device_t *dev = surb->dev; - - if (urb->status < 0) - { - printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length); - return; - } - - if (urb->actual_length > 0) - { - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p; - - if (urb->actual_length >= phdr->msgLength) - { - surb->cb->size = phdr->msgLength; - - if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) - { - surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3); - - // sanity check - if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) - { - printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length); - goto exit_and_resubmit; - } - - // move buffer pointer and copy header to its new location - memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST)); - } - else - surb->cb->offset = 0; - - smscore_onresponse(dev->coredev, surb->cb); - surb->cb = NULL; - } - else - { - printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length); - } - } - -exit_and_resubmit: - smsusb_submit_urb(dev, surb); -} - -int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) -{ - if (!surb->cb) - { - surb->cb = smscore_getbuffer(dev->coredev); - if (!surb->cb) - { - printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__); - return -ENOMEM; - } - } - - usb_fill_bulk_urb( - &surb->urb, - dev->udev, - usb_rcvbulkpipe(dev->udev, 0x81), - surb->cb->p, - dev->buffer_size, - smsusb_onresponse, - surb - ); - surb->urb.transfer_dma = surb->cb->phys; - surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - return usb_submit_urb(&surb->urb, GFP_ATOMIC); -} - -void smsusb_stop_streaming(smsusb_device_t* dev) -{ - int i; - - for (i = 0; i < MAX_URBS; i ++) - { - usb_kill_urb(&dev->surbs[i].urb); - - if (dev->surbs[i].cb) - { - smscore_putbuffer(dev->coredev, dev->surbs[i].cb); - dev->surbs[i].cb = NULL; - } - } -} - -int smsusb_start_streaming(smsusb_device_t* dev) -{ - int i, rc; - - for (i = 0; i < MAX_URBS; i ++) - { - rc = smsusb_submit_urb(dev, &dev->surbs[i]); - if (rc < 0) - { - printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__); - smsusb_stop_streaming(dev); - break; - } - } - - return rc; -} - -int smsusb_sendrequest(void *context, void *buffer, size_t size) -{ - smsusb_device_t* dev = (smsusb_device_t*) context; - int dummy; - - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); -} - -char *smsusb1_fw_lkup[] = -{ - "dvbt_stellar_usb.inp", - "dvbh_stellar_usb.inp", - "tdmb_stellar_usb.inp", - "none", - "dvbt_bda_stellar_usb.inp", -}; - -int smsusb1_load_firmware(struct usb_device *udev, int id) -{ - const struct firmware *fw; - u8* fw_buffer; - int rc, dummy; - - if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) - { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id); - return -EINVAL; - } - - rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); - if (rc < 0) - { - printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id); - return rc; - } - - fw_buffer = kmalloc(fw->size, GFP_KERNEL); - if (fw_buffer) - { - memcpy(fw_buffer, fw->data, fw->size); - - rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); - - printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc); - - kfree(fw_buffer); - } - else - { - printk(KERN_INFO "failed to allocate firmware buffer\n"); - rc = -ENOMEM; - } - - release_firmware(fw); - - return rc; -} - -void smsusb1_detectmode(void *context, int *mode) -{ - char *product_string = ((smsusb_device_t *) context)->udev->product; - - *mode = DEVICE_MODE_NONE; - - if (!product_string) - { - product_string = "none"; - printk("%s product string not found\n", __FUNCTION__); - } - else - { - if (strstr(product_string, "DVBH")) - *mode = 1; - else if (strstr(product_string, "BDA")) - *mode = 4; - else if (strstr(product_string, "DVBT")) - *mode = 0; - else if (strstr(product_string, "TDMB")) - *mode = 2; - } - - printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string); -} - -int smsusb1_setmode(void *context, int mode) -{ - SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; - - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) - { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode); - return -EINVAL; - } - - return smsusb_sendrequest(context, &Msg, sizeof(Msg)); -} - -void smsusb_term_device(struct usb_interface *intf) -{ - smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf); - - if (dev) - { - smsusb_stop_streaming(dev); - - // unregister from smscore - if (dev->coredev) - smscore_unregister_device(dev->coredev); - - kfree(dev); - - printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev); - } - - usb_set_intfdata(intf, NULL); -} - -int smsusb_init_device(struct usb_interface *intf) -{ - smsdevice_params_t params; - smsusb_device_t* dev; - int i, rc; - - // create device object - dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); - if (!dev) - { - printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__); - return -ENOMEM; - } - - memset(¶ms, 0, sizeof(params)); - usb_set_intfdata(intf, dev); - dev->udev = interface_to_usbdev(intf); - - switch (dev->udev->descriptor.idProduct) - { - case 0x100: - dev->buffer_size = USB1_BUFFER_SIZE; - - params.setmode_handler = smsusb1_setmode; - params.detectmode_handler = smsusb1_detectmode; - break; - - default: - dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); - - params.flags |= SMS_DEVICE_FAMILY2; - break; - } - - params.device = &dev->udev->dev; - params.buffer_size = dev->buffer_size; - params.num_buffers = MAX_BUFFERS; - params.sendrequest_handler = smsusb_sendrequest; - params.context = dev; - snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); - - // register in smscore - rc = smscore_register_device(¶ms, &dev->coredev); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc); - smsusb_term_device(intf); - return rc; - } - - // initialize urbs - for (i = 0; i < MAX_URBS; i ++) - { - dev->surbs[i].dev = dev; - usb_init_urb(&dev->surbs[i].urb); - } - - rc = smsusb_start_streaming(dev); - if (rc < 0) - { - printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__); - smsusb_term_device(intf); - return rc; - } - - rc = smscore_start_device(dev->coredev); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__); - smsusb_term_device(intf); - return rc; - } - - printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); - - return rc; -} - -int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - char devpath[32]; - int i, rc; - - if (intf->num_altsetting > 0) - { - rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); - if (rc < 0) - { - printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc); - return rc; - } - } - - printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) - printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - - if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0) - { - printk(KERN_INFO "rom interface 0 is not used\n"); - return -ENODEV; - } - - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) - { - snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath); - return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); - } - - return smsusb_init_device(intf); -} - -void smsusb_disconnect(struct usb_interface *intf) -{ - smsusb_term_device(intf); -} - -static struct usb_device_id smsusb_id_table [] = { - { USB_DEVICE(0x187F, 0x0010) }, - { USB_DEVICE(0x187F, 0x0100) }, - { USB_DEVICE(0x187F, 0x0200) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, smsusb_id_table); - -static struct usb_driver smsusb_driver = { - .name = "smsusb", - .probe = smsusb_probe, - .disconnect = smsusb_disconnect, - .id_table = smsusb_id_table, -}; - -int smsusb_register(void) -{ - int rc = usb_register(&smsusb_driver); - if (rc) - printk(KERN_INFO "usb_register failed. Error number %d\n", rc); - - printk(KERN_INFO "%s\n", __FUNCTION__); - - return rc; -} - -void smsusb_unregister(void) -{ - /* Regular USB Cleanup */ - usb_deregister(&smsusb_driver); - printk(KERN_INFO "%s\n", __FUNCTION__); -} - -- cgit v1.2.3 From 18658117ff844e8117f6b363cb7fa8c5f8ad2cb8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 22 May 2008 18:30:17 -0300 Subject: V4L/DVB (8273): sms1xxx: replace __FUNCTION__ with __func__ Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 56 ++++++++++++++++++------------------ drivers/media/dvb/siano/smsdvb.c | 24 ++++++++-------- drivers/media/dvb/siano/smsusb.c | 40 +++++++++++++------------- 3 files changed, 60 insertions(+), 60 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d3ba1fcde54a..e55138e6627a 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -285,7 +285,7 @@ smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); if (!cb) { - printk(KERN_INFO "%s kmalloc(...) failed\n", __FUNCTION__); + printk(KERN_INFO "%s kmalloc(...) failed\n", __func__); return NULL; } @@ -313,7 +313,7 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); if (!dev) { - printk(KERN_INFO "%s kzalloc(...) failed\n", __FUNCTION__); + printk(KERN_INFO "%s kzalloc(...) failed\n", __func__); return -ENOMEM; } @@ -359,7 +359,7 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored smscore_putbuffer(dev, cb); } - printk(KERN_INFO "%s allocated %d buffers\n", __FUNCTION__, dev->num_buffers); + printk(KERN_INFO "%s allocated %d buffers\n", __func__, dev->num_buffers); dev->mode = DEVICE_MODE_NONE; dev->context = params->context; @@ -380,7 +380,7 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored *coredev = dev; - printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + printk(KERN_INFO "%s device %p created\n", __func__, dev); return 0; } @@ -402,7 +402,7 @@ int smscore_start_device(smscore_device_t *coredev) rc = smscore_notify_callbacks(coredev, coredev->device, 1); - printk(KERN_INFO "%s device %p started, rc %d\n", __FUNCTION__, coredev, rc); + printk(KERN_INFO "%s device %p started, rc %d\n", __func__, coredev, rc); kmutex_unlock(&g_smscore_deviceslock); @@ -526,7 +526,7 @@ int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmwar rc = request_firmware(&fw, filename, coredev->device); if (rc < 0) { - printk(KERN_INFO "%s failed to open \"%s\"\n", __FUNCTION__, filename); + printk(KERN_INFO "%s failed to open \"%s\"\n", __func__, filename); return rc; } @@ -543,7 +543,7 @@ int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmwar } else { - printk(KERN_INFO "%s failed to allocate firmware buffer\n", __FUNCTION__); + printk(KERN_INFO "%s failed to allocate firmware buffer\n", __func__); rc = -ENOMEM; } @@ -583,11 +583,11 @@ void smscore_unregister_device(smscore_device_t *coredev) if (num_buffers == coredev->num_buffers) break; - printk(KERN_INFO "%s waiting for %d buffer(s)\n", __FUNCTION__, coredev->num_buffers - num_buffers); + printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, coredev->num_buffers - num_buffers); msleep(100); } - printk(KERN_INFO "%s freed %d buffers\n", __FUNCTION__, num_buffers); + printk(KERN_INFO "%s freed %d buffers\n", __func__, num_buffers); if (coredev->common_buffer) dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); @@ -597,7 +597,7 @@ void smscore_unregister_device(smscore_device_t *coredev) kmutex_unlock(&g_smscore_deviceslock); - printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, coredev); + printk(KERN_INFO "%s device %p destroyed\n", __func__, coredev); } int smscore_detect_mode(smscore_device_t *coredev) @@ -614,14 +614,14 @@ int smscore_detect_mode(smscore_device_t *coredev) rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc == -ETIME) { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __FUNCTION__); + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __func__); if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) { rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc < 0) { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __FUNCTION__, rc); + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __func__, rc); } } else @@ -664,7 +664,7 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { - printk(KERN_INFO "%s invalid mode specified %d\n", __FUNCTION__, mode); + printk(KERN_INFO "%s invalid mode specified %d\n", __func__, mode); return -EINVAL; } @@ -677,7 +677,7 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) if (coredev->mode == mode) { - printk(KERN_INFO "%s device mode %d already set\n", __FUNCTION__, mode); + printk(KERN_INFO "%s device mode %d already set\n", __func__, mode); return 0; } @@ -689,7 +689,7 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) } else { - printk(KERN_INFO "%s mode %d supported by running firmware\n", __FUNCTION__, mode); + printk(KERN_INFO "%s mode %d supported by running firmware\n", __func__, mode); } buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); @@ -834,7 +834,7 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) case MSG_SMS_GET_VERSION_EX_RES: { SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; - printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __FUNCTION__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); + printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __func__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; coredev->modes_supported = ver->SupportedProtocols; @@ -844,12 +844,12 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) } case MSG_SMS_INIT_DEVICE_RES: - printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __FUNCTION__); + printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __func__); complete(&coredev->init_device_done); break; case MSG_SW_RELOAD_START_RES: - printk("%s: MSG_SW_RELOAD_START_RES\n", __FUNCTION__); + printk("%s: MSG_SW_RELOAD_START_RES\n", __func__); complete(&coredev->reload_start_done); break; @@ -858,11 +858,11 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) break; case MSG_SW_RELOAD_EXEC_RES: - printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __FUNCTION__); + printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __func__); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __FUNCTION__); + printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __func__); complete(&coredev->trigger_done); break; @@ -871,7 +871,7 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) break; default: - printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __FUNCTION__, client, rc, phdr->msgType, phdr->msgDstId); + printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __func__, client, rc, phdr->msgType, phdr->msgDstId); } smscore_putbuffer(coredev, cb); @@ -986,7 +986,7 @@ int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *param *client = newclient; - printk(KERN_INFO "%s %p %d %d\n", __FUNCTION__, params->context, params->data_type, params->initial_id); + printk(KERN_INFO "%s %p %d %d\n", __func__, params->context, params->data_type, params->initial_id); return 0; } @@ -1019,7 +1019,7 @@ void smscore_unregister_client(smscore_client_t *client) } } - printk(KERN_INFO "%s %p %d\n", __FUNCTION__, client->context, client->data_type); + printk(KERN_INFO "%s %p %d\n", __func__, client->context, client->data_type); list_del(&client->entry); kfree(client); @@ -1076,19 +1076,19 @@ int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) { - printk(KERN_INFO "%s invalid vm flags\n", __FUNCTION__); + printk(KERN_INFO "%s invalid vm flags\n", __func__); return -EINVAL; } if ((end - start) != size) { - printk(KERN_INFO "%s invalid size %d expected %d\n", __FUNCTION__, (int)(end - start), (int) size); + printk(KERN_INFO "%s invalid size %d expected %d\n", __func__, (int)(end - start), (int) size); return -EINVAL; } if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) { - printk(KERN_INFO "%s remap_page_range failed\n", __FUNCTION__); + printk(KERN_INFO "%s remap_page_range failed\n", __func__); return -EAGAIN; } @@ -1112,7 +1112,7 @@ int smscore_module_init(void) /* DVB Register */ rc = smsdvb_register(); - printk(KERN_INFO "%s, rc %d\n", __FUNCTION__, rc); + printk(KERN_INFO "%s, rc %d\n", __func__, rc); return rc; } @@ -1146,7 +1146,7 @@ void smscore_module_exit(void) /* Unregister USB */ smsusb_unregister(); - printk(KERN_INFO "%s\n", __FUNCTION__); + printk(KERN_INFO "%s\n", __func__); } module_init(smscore_module_init); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index e1a14a812c25..1a75033c35de 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -107,7 +107,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; - printk("%s add pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + printk("%s add pid %d(%x)\n", __func__, feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -124,7 +124,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; - printk("%s remove pid %d(%x)\n", __FUNCTION__, feed->pid, feed->pid); + printk("%s remove pid %d(%x)\n", __func__, feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -197,7 +197,7 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { - printk("%s\n", __FUNCTION__); + printk("%s\n", __func__); tune->min_delay_ms = 400; tune->step_size = 250000; @@ -223,7 +223,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_para Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; - printk("%s freq %d band %d\n", __FUNCTION__, fep->frequency, fep->u.ofdm.bandwidth); + printk("%s freq %d band %d\n", __func__, fep->frequency, fep->u.ofdm.bandwidth); switch(fep->u.ofdm.bandwidth) { @@ -242,7 +242,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_para { smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - printk("%s\n", __FUNCTION__); + printk("%s\n", __func__); // todo: memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); @@ -303,7 +303,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); if (!client) { - printk(KERN_INFO "%s kmalloc() failed\n", __FUNCTION__); + printk(KERN_INFO "%s kmalloc() failed\n", __func__); return -ENOMEM; } @@ -325,7 +325,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival rc = dvb_dmx_init(&client->demux); if (rc < 0) { - printk("%s dvb_dmx_init failed %d\n\n", __FUNCTION__, rc); + printk("%s dvb_dmx_init failed %d\n\n", __func__, rc); goto dvbdmx_error; } @@ -337,7 +337,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); if (rc < 0) { - printk("%s dvb_dmxdev_init failed %d\n", __FUNCTION__, rc); + printk("%s dvb_dmxdev_init failed %d\n", __func__, rc); goto dmxdev_error; } @@ -347,7 +347,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival rc = dvb_register_frontend(&client->adapter, &client->frontend); if (rc < 0) { - printk("%s frontend registration failed %d\n", __FUNCTION__, rc); + printk("%s frontend registration failed %d\n", __func__, rc); goto frontend_error; } @@ -360,7 +360,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival rc = smscore_register_client(coredev, ¶ms, &client->smsclient); if (rc < 0) { - printk(KERN_INFO "%s smscore_register_client() failed %d\n", __FUNCTION__, rc); + printk(KERN_INFO "%s smscore_register_client() failed %d\n", __func__, rc); goto client_error; } @@ -375,7 +375,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival kmutex_unlock(&g_smsdvb_clientslock); - printk(KERN_INFO "%s success\n", __FUNCTION__); + printk(KERN_INFO "%s success\n", __func__); return 0; @@ -405,7 +405,7 @@ int smsdvb_register(void) rc = smscore_register_hotplug(smsdvb_hotplug); - printk(KERN_INFO "%s\n", __FUNCTION__); + printk(KERN_INFO "%s\n", __func__); return rc; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 20aa878d9d5f..e15f0342d069 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -62,7 +62,7 @@ void smsusb_onresponse(struct urb *urb) if (urb->status < 0) { - printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __FUNCTION__, urb->status, urb->actual_length); + printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __func__, urb->status, urb->actual_length); return; } @@ -81,7 +81,7 @@ void smsusb_onresponse(struct urb *urb) // sanity check if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) { - printk("%s: invalid response msglen %d offset %d size %d\n", __FUNCTION__, phdr->msgLength, surb->cb->offset, urb->actual_length); + printk("%s: invalid response msglen %d offset %d size %d\n", __func__, phdr->msgLength, surb->cb->offset, urb->actual_length); goto exit_and_resubmit; } @@ -96,7 +96,7 @@ void smsusb_onresponse(struct urb *urb) } else { - printk("%s invalid response msglen %d actual %d\n", __FUNCTION__, phdr->msgLength, urb->actual_length); + printk("%s invalid response msglen %d actual %d\n", __func__, phdr->msgLength, urb->actual_length); } } @@ -111,7 +111,7 @@ int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) surb->cb = smscore_getbuffer(dev->coredev); if (!surb->cb) { - printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __FUNCTION__); + printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __func__); return -ENOMEM; } } @@ -156,7 +156,7 @@ int smsusb_start_streaming(smsusb_device_t* dev) rc = smsusb_submit_urb(dev, &dev->surbs[i]); if (rc < 0) { - printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __FUNCTION__); + printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __func__); smsusb_stop_streaming(dev); break; } @@ -190,14 +190,14 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, id); + printk(KERN_INFO "%s invalid firmware id specified %d\n", __func__, id); return -EINVAL; } rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); if (rc < 0) { - printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __FUNCTION__, smsusb1_fw_lkup[id], id); + printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __func__, smsusb1_fw_lkup[id], id); return rc; } @@ -208,7 +208,7 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); - printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __FUNCTION__, fw->size, dummy, rc); + printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __func__, fw->size, dummy, rc); kfree(fw_buffer); } @@ -232,7 +232,7 @@ void smsusb1_detectmode(void *context, int *mode) if (!product_string) { product_string = "none"; - printk("%s product string not found\n", __FUNCTION__); + printk("%s product string not found\n", __func__); } else { @@ -246,7 +246,7 @@ void smsusb1_detectmode(void *context, int *mode) *mode = 2; } - printk("%s: %d \"%s\"\n", __FUNCTION__, *mode, product_string); + printk("%s: %d \"%s\"\n", __func__, *mode, product_string); } int smsusb1_setmode(void *context, int mode) @@ -255,7 +255,7 @@ int smsusb1_setmode(void *context, int mode) if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __FUNCTION__, mode); + printk(KERN_INFO "%s invalid firmware id specified %d\n", __func__, mode); return -EINVAL; } @@ -276,7 +276,7 @@ void smsusb_term_device(struct usb_interface *intf) kfree(dev); - printk(KERN_INFO "%s device %p destroyed\n", __FUNCTION__, dev); + printk(KERN_INFO "%s device %p destroyed\n", __func__, dev); } usb_set_intfdata(intf, NULL); @@ -292,7 +292,7 @@ int smsusb_init_device(struct usb_interface *intf) dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); if (!dev) { - printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __FUNCTION__); + printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __func__); return -ENOMEM; } @@ -328,7 +328,7 @@ int smsusb_init_device(struct usb_interface *intf) rc = smscore_register_device(¶ms, &dev->coredev); if (rc < 0) { - printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __FUNCTION__, rc); + printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __func__, rc); smsusb_term_device(intf); return rc; } @@ -343,7 +343,7 @@ int smsusb_init_device(struct usb_interface *intf) rc = smsusb_start_streaming(dev); if (rc < 0) { - printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __FUNCTION__); + printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __func__); smsusb_term_device(intf); return rc; } @@ -351,12 +351,12 @@ int smsusb_init_device(struct usb_interface *intf) rc = smscore_start_device(dev->coredev); if (rc < 0) { - printk(KERN_INFO "%s smscore_start_device(...) failed\n", __FUNCTION__); + printk(KERN_INFO "%s smscore_start_device(...) failed\n", __func__); smsusb_term_device(intf); return rc; } - printk(KERN_INFO "%s device %p created\n", __FUNCTION__, dev); + printk(KERN_INFO "%s device %p created\n", __func__, dev); return rc; } @@ -372,7 +372,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __FUNCTION__, rc); + printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __func__, rc); return rc; } } @@ -422,7 +422,7 @@ int smsusb_register(void) if (rc) printk(KERN_INFO "usb_register failed. Error number %d\n", rc); - printk(KERN_INFO "%s\n", __FUNCTION__); + printk(KERN_INFO "%s\n", __func__); return rc; } @@ -431,6 +431,6 @@ void smsusb_unregister(void) { /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); - printk(KERN_INFO "%s\n", __FUNCTION__); + printk(KERN_INFO "%s\n", __func__); } -- cgit v1.2.3 From 3617691fb98b81850640a9b61fb932b798ad4504 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 22 May 2008 18:32:40 -0300 Subject: V4L/DVB (8274): sms1xxx: build cleanup after driver relocation Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 14 -------------- drivers/media/Makefile | 1 - 2 files changed, 15 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index e6a5879ea5f6..7a7803b5d497 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -115,20 +115,6 @@ source "drivers/media/radio/Kconfig" source "drivers/media/dvb/Kconfig" -# -# Mobile Digital TV devices (DVB-H, T-DMB, etc.) -# -menuconfig MDTV_ADAPTERS - bool "Mobile Digital TV adapter" - default y - -if MDTV_ADAPTERS - -source "drivers/media/mdtv/Kconfig" - -endif # MDTV_ADAPTERS - - config DAB boolean "DAB adapters" ---help--- diff --git a/drivers/media/Makefile b/drivers/media/Makefile index ec2102bcb282..09a829d8a7e7 100644 --- a/drivers/media/Makefile +++ b/drivers/media/Makefile @@ -6,4 +6,3 @@ obj-y += common/ video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB_CORE) += dvb/ -obj-$(CONFIG_MDTV_ADAPTERS) += mdtv/ \ No newline at end of file -- cgit v1.2.3 From a83ccdd6a952eb25d3f51dfdc175c1e9bf8f7cae Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 6 May 2008 03:11:51 -0300 Subject: V4L/DVB (8275): sms1xxx: codingstyle cleanup: "foo* bar"/"foo * bar" should be "foo *bar" ERROR: "foo* bar" should be "foo *bar" ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 39 +++++++++++++++++++++--------------- drivers/media/dvb/siano/smscoreapi.h | 10 ++++++--- drivers/media/dvb/siano/smsdvb.c | 11 ++++++---- drivers/media/dvb/siano/smsusb.c | 16 +++++++-------- 4 files changed, 45 insertions(+), 31 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index e55138e6627a..86a4b5de5e1c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -112,7 +112,7 @@ static int default_mode = 1; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -int smscore_registry_getmode(char* devpath) +int smscore_registry_getmode(char *devpath) { smscore_registry_entry_t *entry; struct list_head *next; @@ -144,7 +144,7 @@ int smscore_registry_getmode(char* devpath) return default_mode; } -void smscore_registry_setmode(char* devpath, int mode) +void smscore_registry_setmode(char *devpath, int mode) { smscore_registry_entry_t *entry; struct list_head *next; @@ -166,7 +166,8 @@ void smscore_registry_setmode(char* devpath, int mode) } -void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t* lock) +void list_add_locked(struct list_head *new, struct list_head *head, + spinlock_t *lock) { unsigned long flags; @@ -251,7 +252,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug) void smscore_notify_clients(smscore_device_t *coredev) { - smscore_client_t* client; + smscore_client_t *client; // the client must call smscore_unregister_client from remove handler while (!list_empty(&coredev->clients)) @@ -280,7 +281,8 @@ int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, i return rc; } -smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr_t common_buffer_phys) +smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, + dma_addr_t common_buffer_phys) { smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); if (!cb) @@ -307,7 +309,7 @@ smscore_buffer_t *smscore_createbuffer(u8* buffer, void* common_buffer, dma_addr */ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) { - smscore_device_t* dev; + smscore_device_t *dev; u8 *buffer; dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); @@ -409,7 +411,8 @@ int smscore_start_device(smscore_device_t *coredev) return rc; } -int smscore_sendrequest_and_wait(smscore_device_t *coredev, void* buffer, size_t size, struct completion *completion) +int smscore_sendrequest_and_wait(smscore_device_t *coredev, void *buffer, + size_t size, struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) @@ -423,7 +426,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; SmsMsgHdr_ST *msg; UINT32 mem_address = firmware->StartAddress; - u8* payload = firmware->Payload; + u8 *payload = firmware->Payload; int rc = 0; if (coredev->preload_handler) @@ -513,12 +516,13 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ * * @return 0 on success, <0 on error. */ -int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler) +int smscore_load_firmware(smscore_device_t *coredev, char *filename, + loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; const struct firmware *fw; - u8* fw_buffer; + u8 *fw_buffer; if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) return -EINVAL; @@ -739,7 +743,8 @@ int smscore_get_device_mode(smscore_device_t *coredev) return coredev->mode; } -smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_type) +smscore_client_t *smscore_getclient_by_type(smscore_device_t *coredev, + int data_type) { smscore_client_t *client = NULL; struct list_head *next, *first; @@ -766,7 +771,7 @@ smscore_client_t* smscore_getclient_by_type(smscore_device_t *coredev, int data_ return client; } -smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) +smscore_client_t *smscore_getclient_by_id(smscore_device_t *coredev, int id) { smscore_client_t *client = NULL; struct list_head *next, *first; @@ -801,7 +806,8 @@ smscore_client_t* smscore_getclient_by_id(smscore_device_t *coredev, int id) void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) { SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); - smscore_client_t * client = smscore_getclient_by_type(coredev, phdr->msgType); + smscore_client_t *client = smscore_getclient_by_type(coredev, + phdr->msgType); int rc = -EBUSY; static unsigned long last_sample_time = 0; @@ -957,7 +963,7 @@ int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, */ int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) { - smscore_client_t* newclient; + smscore_client_t *newclient; int rc; // check that no other channel with same data type exists @@ -1039,7 +1045,7 @@ void smscore_unregister_client(smscore_client_t *client) */ int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) { - smscore_device_t* coredev = client->coredev; + smscore_device_t *coredev = client->coredev; SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; // check that no other channel with same id exists @@ -1070,7 +1076,8 @@ int smscore_get_common_buffer_size(smscore_device_t *coredev) * * @return 0 on success, <0 on error. */ -int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma) +int smscore_map_common_buffer(smscore_device_t *coredev, + struct vm_area_struct *vma) { unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 679487df8a53..e44507417d28 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -503,19 +503,23 @@ extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t extern void smscore_unregister_device(smscore_device_t *coredev); extern int smscore_start_device(smscore_device_t *coredev); -extern int smscore_load_firmware(smscore_device_t *coredev, char* filename, loadfirmware_t loadfirmware_handler); +extern int smscore_load_firmware(smscore_device_t *coredev, char *filename, + loadfirmware_t loadfirmware_handler); extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); extern int smscore_get_device_mode(smscore_device_t *coredev); -extern int smscore_register_client(smscore_device_t *coredev, smsclient_params_t* params, smscore_client_t **client); +extern int smscore_register_client(smscore_device_t *coredev, + smsclient_params_t *params, + smscore_client_t **client); extern void smscore_unregister_client(smscore_client_t *client); extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size); extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb); extern int smscore_get_common_buffer_size(smscore_device_t *coredev); -extern int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct * vma); +extern int smscore_map_common_buffer(smscore_device_t *coredev, + struct vm_area_struct *vma); extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 1a75033c35de..717e0e97fd1f 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -79,7 +79,7 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) return 0; } -void smsdvb_unregister_client(smsdvb_client_t* client) +void smsdvb_unregister_client(smsdvb_client_t *client) { // must be called under clientslock @@ -136,7 +136,9 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); } -static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, void* buffer, size_t size, struct completion *completion) +static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, + void *buffer, size_t size, + struct completion *completion) { int rc = smsclient_sendrequest(client->smsclient, buffer, size); if (rc < 0) @@ -283,10 +285,11 @@ static struct dvb_frontend_ops smsdvb_fe_ops = { .read_snr = smsdvb_read_snr, }; -int smsdvb_hotplug(smscore_device_t *coredev, struct device* device, int arrival) +int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, + int arrival) { smsclient_params_t params; - smsdvb_client_t* client; + smsdvb_client_t *client; int rc; // device removal handled by onremove callback diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index e15f0342d069..87dda39a7985 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -44,7 +44,7 @@ typedef struct _smsusb_urb typedef struct _smsusb_device { - struct usb_device* udev; + struct usb_device *udev; smscore_device_t *coredev; smsusb_urb_t surbs[MAX_URBS]; @@ -53,7 +53,7 @@ typedef struct _smsusb_device int buffer_size; } *psmsusb_device_t; -int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb); +int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb); void smsusb_onresponse(struct urb *urb) { @@ -104,7 +104,7 @@ exit_and_resubmit: smsusb_submit_urb(dev, surb); } -int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) +int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb) { if (!surb->cb) { @@ -131,7 +131,7 @@ int smsusb_submit_urb(smsusb_device_t* dev, smsusb_urb_t* surb) return usb_submit_urb(&surb->urb, GFP_ATOMIC); } -void smsusb_stop_streaming(smsusb_device_t* dev) +void smsusb_stop_streaming(smsusb_device_t *dev) { int i; @@ -147,7 +147,7 @@ void smsusb_stop_streaming(smsusb_device_t* dev) } } -int smsusb_start_streaming(smsusb_device_t* dev) +int smsusb_start_streaming(smsusb_device_t *dev) { int i, rc; @@ -167,7 +167,7 @@ int smsusb_start_streaming(smsusb_device_t* dev) int smsusb_sendrequest(void *context, void *buffer, size_t size) { - smsusb_device_t* dev = (smsusb_device_t*) context; + smsusb_device_t *dev = (smsusb_device_t *) context; int dummy; return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); @@ -185,7 +185,7 @@ char *smsusb1_fw_lkup[] = int smsusb1_load_firmware(struct usb_device *udev, int id) { const struct firmware *fw; - u8* fw_buffer; + u8 *fw_buffer; int rc, dummy; if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) @@ -285,7 +285,7 @@ void smsusb_term_device(struct usb_interface *intf) int smsusb_init_device(struct usb_interface *intf) { smsdevice_params_t params; - smsusb_device_t* dev; + smsusb_device_t *dev; int i, rc; // create device object -- cgit v1.2.3 From 55ad310c2f21281f50fa040b7765a4a1151bd420 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 6 May 2008 03:52:44 -0300 Subject: V4L/DVB (8276): sms1xxx: codingstyle cleanup: "(foo*)" should be "(foo *)" ERROR: "(foo*)" should be "(foo *)" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsdvb.c | 12 +++++++----- drivers/media/dvb/siano/smsusb.c | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 717e0e97fd1f..6975e7c61f87 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -32,12 +32,13 @@ kmutex_t g_smsdvb_clientslock; int smsdvb_onresponse(void *context, smscore_buffer_t *cb) { smsdvb_client_t *client = (smsdvb_client_t *) context; - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8*) cb->p) + cb->offset); + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); switch(phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8*)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST)); + dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), + cb->size - sizeof(SmsMsgHdr_ST)); break; case MSG_SMS_RF_TUNE_RES: @@ -46,7 +47,8 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) case MSG_SMS_GET_STATISTICS_RES: { - SmsMsgStatisticsInfo_ST* p = (SmsMsgStatisticsInfo_ST*)(phdr + 1); + SmsMsgStatisticsInfo_ST *p = + (SmsMsgStatisticsInfo_ST *)(phdr + 1); if (p->Stat.IsDemodLocked) { @@ -97,7 +99,7 @@ void smsdvb_onremove(void *context) { kmutex_lock(&g_smsdvb_clientslock); - smsdvb_unregister_client((smsdvb_client_t*) context); + smsdvb_unregister_client((smsdvb_client_t *) context); kmutex_unlock(&g_smsdvb_clientslock); } @@ -420,7 +422,7 @@ void smsdvb_unregister(void) kmutex_lock(&g_smsdvb_clientslock); while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client((smsdvb_client_t*) g_smsdvb_clients.next); + smsdvb_unregister_client((smsdvb_client_t *) g_smsdvb_clients.next); kmutex_unlock(&g_smsdvb_clientslock); diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 87dda39a7985..1677f8591508 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -86,7 +86,8 @@ void smsusb_onresponse(struct urb *urb) } // move buffer pointer and copy header to its new location - memcpy((char*) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST)); + memcpy((char *) phdr + surb->cb->offset, + phdr, sizeof(SmsMsgHdr_ST)); } else surb->cb->offset = 0; @@ -264,7 +265,7 @@ int smsusb1_setmode(void *context, int mode) void smsusb_term_device(struct usb_interface *intf) { - smsusb_device_t *dev = (smsusb_device_t*) usb_get_intfdata(intf); + smsusb_device_t *dev = (smsusb_device_t *) usb_get_intfdata(intf); if (dev) { -- cgit v1.2.3 From f17407a85db3b86526d54e65698348873a6df617 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 14 Jun 2008 00:43:26 -0300 Subject: V4L/DVB (8277): sms1xxx: update latest siano drop to 1.2.17 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 363 ++++++++++++++++++++++------------- drivers/media/dvb/siano/smscoreapi.h | 11 ++ drivers/media/dvb/siano/smsdvb.c | 7 +- drivers/media/dvb/siano/smsusb.c | 48 +++-- 4 files changed, 273 insertions(+), 156 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 86a4b5de5e1c..76fa0f50775c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -33,32 +33,47 @@ #include "smscoreapi.h" +#define PERROR(fmt, args...) printk( KERN_ERR "smscore error: line %d- %s(): " fmt,__LINE__, __func__, ## args) + +#ifdef SMSCORE_DEBUG + +#undef PWARNING +# define PWARNING(fmt, args...) printk( KERN_INFO "smscore warning: line %d- %s(): " fmt,__LINE__, __func__, ## args) +#undef PDEBUG /* undef it, just in case */ +# define PDEBUG(fmt, args...) printk( KERN_INFO "smscore - %s(): " fmt, __func__, ## args) + +#else /*SMSCORE_DEBUG*/ + +#define PDEBUG(fmt, args...) +#define PWARNING(fmt, args...) + +#endif + + typedef struct _smscore_device_notifyee { struct list_head entry; hotplug_t hotplug; } smscore_device_notifyee_t; +typedef struct _smscore_subclient +{ + struct list_head entry; + int id; + int data_type; +} smscore_idlist_t; + typedef struct _smscore_client { struct list_head entry; smscore_device_t *coredev; - void *context; - - int data_type; - + struct list_head idlist; onresponse_t onresponse_handler; onremove_t onremove_handler; } *psmscore_client_t; -typedef struct _smscore_subclient -{ - struct list_head entry; - smscore_client_t *client; - int id; -} smscore_subclient_t; typedef struct _smscore_device { @@ -99,6 +114,7 @@ typedef struct _smscore_registry_entry struct list_head entry; char devpath[32]; int mode; + sms_device_type_st type; } smscore_registry_entry_t; struct list_head g_smscore_notifyees; @@ -109,63 +125,102 @@ struct list_head g_smscore_registry; kmutex_t g_smscore_registrylock; static int default_mode = 1; + module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -int smscore_registry_getmode(char *devpath) +static smscore_registry_entry_t *smscore_find_registry ( char *devpath ) { smscore_registry_entry_t *entry; struct list_head *next; kmutex_lock(&g_smscore_registrylock); - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) { entry = (smscore_registry_entry_t *) next; - if (!strcmp(entry->devpath, devpath)) { kmutex_unlock(&g_smscore_registrylock); - return entry->mode; + return entry; } } - entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); if (entry) { entry->mode = default_mode; strcpy(entry->devpath, devpath); - list_add(&entry->entry, &g_smscore_registry); } - + else + printk ( KERN_ERR "%s failed to create smscore_registry.\n", __func__ ); kmutex_unlock(&g_smscore_registrylock); + return entry; +} +int smscore_registry_getmode ( char *devpath ) +{ + smscore_registry_entry_t *entry; + + entry = smscore_find_registry ( devpath ); + if ( entry ) + { + return entry->mode; + } + else + { + printk ( KERN_ERR "%s No registry found.\n", __func__ ); + } return default_mode; } -void smscore_registry_setmode(char *devpath, int mode) +sms_device_type_st smscore_registry_gettype ( char *devpath ) { smscore_registry_entry_t *entry; - struct list_head *next; - kmutex_lock(&g_smscore_registrylock); + entry = smscore_find_registry ( devpath ); + if ( entry ) + { + return entry->type; + } + else + { + printk ( KERN_ERR "%s No registry found.\n", __func__ ); + } + return -1; +} - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) +void smscore_registry_setmode ( char *devpath, int mode ) { - entry = (smscore_registry_entry_t *) next; + smscore_registry_entry_t *entry; - if (!strcmp(entry->devpath, devpath)) + entry = smscore_find_registry ( devpath ); + if ( entry ) { entry->mode = mode; - break; + } + else + { + printk ( KERN_ERR "%s No registry found.\n", __func__ ); } } - kmutex_unlock(&g_smscore_registrylock); +void smscore_registry_settype ( char *devpath, sms_device_type_st type ) +{ + smscore_registry_entry_t *entry; + + entry = smscore_find_registry ( devpath ); + if ( entry ) + { + entry->type = type; + } + else + { + printk ( KERN_ERR "%s No registry found.\n", __func__ ); +} } + void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t *lock) { @@ -324,7 +379,6 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored // init queues INIT_LIST_HEAD(&dev->clients); - INIT_LIST_HEAD(&dev->subclients); INIT_LIST_HEAD(&dev->buffers); // init locks @@ -375,6 +429,8 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored dev->device_flags = params->flags; strcpy(dev->devpath, params->devpath); + smscore_registry_settype ( dev->devpath, params->device_type ); + // add device to devices list kmutex_lock(&g_smscore_deviceslock); list_add(&dev->entry, &g_smscore_devices); @@ -398,7 +454,10 @@ int smscore_start_device(smscore_device_t *coredev) { int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); if (rc < 0) + { + printk ( KERN_INFO "%s set device mode faile , rc %d\n", __func__, rc ); return rc; + } kmutex_lock(&g_smscore_deviceslock); @@ -416,9 +475,12 @@ int smscore_sendrequest_and_wait(smscore_device_t *coredev, void *buffer, { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) + { + printk(KERN_INFO "%s sendrequest returned error %d\n", __func__, rc); return rc; + } - return wait_for_completion_timeout(completion, msecs_to_jiffies(1000)) ? 0 : -ETIME; + return wait_for_completion_timeout(completion, msecs_to_jiffies(10000)) ? 0 : -ETIME; } int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) @@ -429,6 +491,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ u8 *payload = firmware->Payload; int rc = 0; + printk(KERN_INFO "%s loading FW to addr 0x%x size %d\n", __func__, mem_address,firmware->Length); if (coredev->preload_handler) { rc = coredev->preload_handler(coredev->context); @@ -443,6 +506,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ if (coredev->mode != DEVICE_MODE_NONE) { + PDEBUG("Sending reload command\n"); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); mem_address = *(UINT32*) &payload[20]; @@ -496,13 +560,14 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); } + msleep ( 500 ); } - printk("%s %d \n", __func__, rc); + printk("%s rc=%d, postload=%p \n", __func__, rc, coredev->postload_handler); kfree(msg); - return (rc >= 0 && coredev->postload_handler) ? + return ((rc >= 0) && coredev->postload_handler) ? coredev->postload_handler(coredev->context) : rc; } @@ -516,8 +581,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ * * @return 0 on success, <0 on error. */ -int smscore_load_firmware(smscore_device_t *coredev, char *filename, - loadfirmware_t loadfirmware_handler) +int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; @@ -533,7 +597,7 @@ int smscore_load_firmware(smscore_device_t *coredev, char *filename, printk(KERN_INFO "%s failed to open \"%s\"\n", __func__, filename); return rc; } - + printk(KERN_INFO "%s read FW %s, size=%d\"\n", __func__, filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { @@ -556,6 +620,12 @@ int smscore_load_firmware(smscore_device_t *coredev, char *filename, return rc; } +int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8* buffer, int size, int new_mode) +{ + PERROR("Feature not implemented yet\n"); + return -EFAULT; +} + /** * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object * @@ -567,6 +637,7 @@ void smscore_unregister_device(smscore_device_t *coredev) { smscore_buffer_t *cb; int num_buffers = 0; + int retry = 0; kmutex_lock(&g_smscore_deviceslock); @@ -583,9 +654,13 @@ void smscore_unregister_device(smscore_device_t *coredev) kfree(cb); num_buffers ++; } - if (num_buffers == coredev->num_buffers) break; + if (++retry > 10) + { + printk(KERN_INFO "%s exiting although not all buffers released.\n", __func__); + break; + } printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, coredev->num_buffers - num_buffers); msleep(100); @@ -637,19 +712,20 @@ int smscore_detect_mode(smscore_device_t *coredev) return rc; } -char *smscore_fw_lkup[] = +char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - "dvb_nova_12mhz.inp", - "dvb_nova_12mhz.inp", - "tdmb_nova.inp", - "none", - "dvb_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "isdbt_nova_12mhz.inp", - "cmmb_nova_12mhz.inp", - "none", + /*Stellar NOVA A0 Nova B0 VEGA*/ + /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "none" "none"}, + /*DABIP*/ {"none", "none", "none", "none"}, + /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, + /*ISDBTBDA*/{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, + /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; + /** * calls device handler to change mode of operation * NOTE: stellar/usb may disconnect when changing mode @@ -663,7 +739,9 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) { void *buffer; int rc = 0; + sms_device_type_st type; + PDEBUG("set device mode to %d\n", mode ); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) @@ -672,12 +750,17 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) return -EINVAL; } + smscore_registry_setmode(coredev->devpath, mode); + if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); if (rc < 0) + { + printk(KERN_INFO "%s mode detect failed %d\n", __func__, rc); return rc; } + } if (coredev->mode == mode) { @@ -687,10 +770,14 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) if (!(coredev->modes_supported & (1 << mode))) { - rc = smscore_load_firmware(coredev, smscore_fw_lkup[mode], NULL); + type = smscore_registry_gettype ( coredev->devpath ); + rc = smscore_load_firmware_from_file ( coredev, smscore_fw_lkup[mode][type], NULL ); if (rc < 0) + { + printk(KERN_INFO "%s load firmware failed %d\n", __func__, rc); return rc; } + } else { printk(KERN_INFO "%s mode %d supported by running firmware\n", __func__, mode); @@ -709,10 +796,21 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) kfree(buffer); } else + { + printk(KERN_INFO "%s Could not allocate buffer for init device message.\n", __func__); rc = -ENOMEM; } + } else { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) + { + printk(KERN_INFO "%s invalid mode specified %d\n", __func__, mode); + return -EINVAL; + } + + smscore_registry_setmode(coredev->devpath, mode); + if (coredev->detectmode_handler) coredev->detectmode_handler(coredev->context, &coredev->mode); @@ -720,14 +818,14 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) rc = coredev->setmode_handler(coredev->context, mode); } - smscore_registry_setmode(coredev->devpath, mode); - if (rc >= 0) { coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; } + if (rc != 0) + printk(KERN_INFO "%s return error code %d.\n", __func__, rc); return rc; } @@ -743,55 +841,40 @@ int smscore_get_device_mode(smscore_device_t *coredev) return coredev->mode; } -smscore_client_t *smscore_getclient_by_type(smscore_device_t *coredev, - int data_type) +/** + * find client by response id & type within the clients list. + * return client handle or NULL. + * + * @param coredev pointer to a coredev object returned by smscore_register_device + * @param data_type client data type (SMS_DONT_CARE for all types) + * @param id client id (SMS_DONT_CARE for all id ) + * + */ +smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, int id) { smscore_client_t *client = NULL; struct list_head *next, *first; unsigned long flags; + struct list_head *firstid, *nextid; - if (!data_type) - return NULL; spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->clients; - - for (next = first->next; next != first; next = next->next) + for (next = first->next; (next != first) && !client; next = next->next) + { + firstid = &((smscore_client_t*)next )->idlist; + for (nextid = firstid->next ; nextid != firstid ; nextid = nextid->next) { - if (((smscore_client_t*) next)->data_type == data_type) + if ((((smscore_idlist_t*)nextid)->id == id) && + (((smscore_idlist_t*)nextid)->data_type == data_type || + (((smscore_idlist_t*)nextid)->data_type == 0))) { client = (smscore_client_t*) next; break; } } - - spin_unlock_irqrestore(&coredev->clientslock, flags); - - return client; -} - -smscore_client_t *smscore_getclient_by_id(smscore_device_t *coredev, int id) -{ - smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - first = &coredev->subclients; - - for (next = first->next; next != first; next = next->next) - { - if (((smscore_subclient_t*) next)->id == id) - { - client = ((smscore_subclient_t*) next)->client; - break; - } } - spin_unlock_irqrestore(&coredev->clientslock, flags); - return client; } @@ -806,8 +889,7 @@ smscore_client_t *smscore_getclient_by_id(smscore_device_t *coredev, int id) void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) { SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); - smscore_client_t *client = smscore_getclient_by_type(coredev, - phdr->msgType); + smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; static unsigned long last_sample_time = 0; @@ -826,10 +908,9 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) } data_total += cb->size; - - if (!client) - client = smscore_getclient_by_id(coredev, phdr->msgDstId); - + /* If no client registered for type & id, check for control client where type is not registered*/ +// if (!client) +// client = smscore_find_client( coredev, 0, phdr->msgDstId); if (client) rc = client->onresponse_handler(client->context, cb); @@ -877,7 +958,8 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) break; default: - printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __func__, client, rc, phdr->msgType, phdr->msgDstId); + //printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __func__, client, rc, phdr->msgType, phdr->msgDstId); + break; } smscore_putbuffer(coredev, cb); @@ -921,30 +1003,35 @@ void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int id) +int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int data_type, int id) { - smscore_client_t *existing_client; - smscore_subclient_t *subclient; + smscore_idlist_t *listentry; + smscore_client_t *registered_client; - if (!id) - return 0; - - existing_client = smscore_getclient_by_id(coredev, id); - if (existing_client == client) + if ( !client ) + { + PERROR("bad parameter.\n"); + return -EFAULT; + } + registered_client = smscore_find_client(coredev, data_type, id); + if (registered_client == client) + { return 0; - - if (existing_client) - return -EBUSY; - - subclient = kzalloc(sizeof(smscore_subclient_t), GFP_KERNEL); - if (!subclient) + } + if (registered_client) + { + PERROR("The msg ID already registered to another client.\n"); + return -EEXIST; + } + listentry = kzalloc ( sizeof ( smscore_idlist_t ), GFP_KERNEL ); + if ( !listentry ) + { + PERROR("Can't allocate memory for client id.\n"); return -ENOMEM; - - subclient->client = client; - subclient->id = id; - - list_add_locked(&subclient->entry, &coredev->subclients, &coredev->clientslock); - + } + listentry->id = id; + listentry->data_type = data_type; + list_add_locked ( &listentry->entry, &client->idlist, &coredev->clientslock ); return 0; } @@ -964,35 +1051,29 @@ int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) { smscore_client_t *newclient; - int rc; - - // check that no other channel with same data type exists - if (params->data_type && smscore_getclient_by_type(coredev, params->data_type)) + // check that no other channel with same parameters exists + if (smscore_find_client(coredev, params->data_type, params->initial_id)) + { + PERROR("Client already exist.\n"); return -EEXIST; + } newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); if (!newclient) - return -ENOMEM; - - // check that no other channel with same id exists - rc = smscore_validate_client(coredev, newclient, params->initial_id); - if (rc < 0) { - kfree(newclient); - return rc; + PERROR("Failed to allocate memory for client.\n"); + return -ENOMEM; } + INIT_LIST_HEAD ( &newclient->idlist); newclient->coredev = coredev; - newclient->data_type = params->data_type; newclient->onresponse_handler = params->onresponse_handler; newclient->onremove_handler = params->onremove_handler; newclient->context = params->context; - list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); - + smscore_validate_client(coredev, newclient, params->data_type, params->initial_id); *client = newclient; - - printk(KERN_INFO "%s %p %d %d\n", __func__, params->context, params->data_type, params->initial_id); + PDEBUG ( "%p %d %d\n", params->context, params->data_type, params->initial_id ); return 0; } @@ -1006,26 +1087,19 @@ int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *param void smscore_unregister_client(smscore_client_t *client) { smscore_device_t *coredev = client->coredev; - struct list_head *next, *first; unsigned long flags; spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->subclients; - for (next = first->next; next != first;) - { - smscore_subclient_t *subclient = (smscore_subclient_t *) next; - next = next->next; - - if (subclient->client == client) + while (!list_empty( &client->idlist)) { - list_del(&subclient->entry); - kfree(subclient); - } + smscore_idlist_t *identry = (smscore_idlist_t*)client->idlist.next; + list_del ( &identry->entry ); + kfree ( identry ); } - printk(KERN_INFO "%s %p %d\n", __func__, client->context, client->data_type); + printk(KERN_INFO "%s %p\n", __func__, client->context); list_del(&client->entry); kfree(client); @@ -1045,11 +1119,26 @@ void smscore_unregister_client(smscore_client_t *client) */ int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) { - smscore_device_t *coredev = client->coredev; + smscore_device_t *coredev; SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; + int rc; + + if ( client == NULL ) + { + printk(KERN_ERR "%s Got NULL client\n", __func__ ); + return -EINVAL; + } + + coredev = client->coredev; // check that no other channel with same id exists - int rc = smscore_validate_client(client->coredev, client, phdr->msgSrcId); + if ( coredev == NULL ) + { + printk(KERN_ERR "%s Got NULL coredev\n", __func__ ); + return -EINVAL; + } + + rc = smscore_validate_client(client->coredev, client, 0, phdr->msgSrcId); if (rc < 0) return rc; @@ -1160,6 +1249,6 @@ module_init(smscore_module_init); module_exit(smscore_module_exit); MODULE_DESCRIPTION("smscore"); -MODULE_AUTHOR("Anatoly Greenblatt,,, (anatolyg@siano-ms.com)"); +MODULE_AUTHOR ( "Siano Mobile Silicon,,, (doronc@siano-ms.com)" ); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index e44507417d28..c0a3be2fae72 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -56,6 +56,14 @@ typedef struct mutex kmutex_t; #define SMS_ROM_NO_RESPONSE 2 #define SMS_DEVICE_NOT_READY 0x8000000 +typedef enum { + SMS_STELLAR= 0, + SMS_NOVA_A0, + SMS_NOVA_B0, + SMS_VEGA, + SMS_NUM_OF_DEVICE_TYPES +} sms_device_type_st; + typedef struct _smscore_device smscore_device_t; typedef struct _smscore_client smscore_client_t; typedef struct _smscore_buffer smscore_buffer_t; @@ -102,6 +110,7 @@ typedef struct _smsdevice_params postload_t postload_handler; void *context; + sms_device_type_st device_type; } smsdevice_params_t; typedef struct _smsclient_params @@ -506,6 +515,8 @@ extern int smscore_start_device(smscore_device_t *coredev); extern int smscore_load_firmware(smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler); +extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8* buffer, int size, int new_mode); + extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); extern int smscore_get_device_mode(smscore_device_t *coredev); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 6975e7c61f87..e050e0da7900 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -300,9 +300,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, if (smscore_get_device_mode(coredev) != 4) { - rc = smscore_set_device_mode(coredev, 4); - if (rc < 0) - return rc; + printk(KERN_ERR "%sSMS Device mode is not set for DVB operation.\n", __func__); + return 0; } client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); @@ -356,7 +355,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, goto frontend_error; } - params.initial_id = 0; + params.initial_id = 1; params.data_type = MSG_SMS_DVBT_BDA_DATA; params.onresponse_handler = smsdvb_onresponse; params.onremove_handler = smsdvb_onremove; diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 1677f8591508..f719b72424d1 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -301,21 +301,32 @@ int smsusb_init_device(struct usb_interface *intf) usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); - switch (dev->udev->descriptor.idProduct) - { - case 0x100: - dev->buffer_size = USB1_BUFFER_SIZE; - - params.setmode_handler = smsusb1_setmode; - params.detectmode_handler = smsusb1_detectmode; - break; + switch (dev->udev->descriptor.idProduct) { + case 0x100: + dev->buffer_size = USB1_BUFFER_SIZE; + + params.setmode_handler = smsusb1_setmode; + params.detectmode_handler = smsusb1_detectmode; + params.device_type = SMS_STELLAR; + printk(KERN_INFO "%s stellar device found\n", __func__ ); + break; + default: + if (dev->udev->descriptor.idProduct == 0x200) { + params.device_type = SMS_NOVA_A0; + printk(KERN_INFO "%s nova A0 found\n", __FUNCTION__ ); + } else if (dev->udev->descriptor.idProduct == 0x201) { + params.device_type = SMS_NOVA_B0; + printk(KERN_INFO "%s nova B0 found\n", __FUNCTION__); + } else { + params.device_type = SMS_VEGA; + printk(KERN_INFO "%s Vega found\n", __FUNCTION__); + } - default: - dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); + dev->buffer_size = USB2_BUFFER_SIZE; + dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); - params.flags |= SMS_DEVICE_FAMILY2; - break; + params.flags |= SMS_DEVICE_FAMILY2; + break; } params.device = &dev->udev->dev; @@ -341,6 +352,7 @@ int smsusb_init_device(struct usb_interface *intf) usb_init_urb(&dev->surbs[i].urb); } + printk(KERN_INFO "%s smsusb_start_streaming(...).\n", __func__); rc = smsusb_start_streaming(dev); if (rc < 0) { @@ -368,6 +380,9 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) char devpath[32]; int i, rc; + rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); + rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); + if (intf->num_altsetting > 0) { rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); @@ -390,11 +405,14 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { - snprintf(devpath, 32, "%d:%s", udev->bus->busnum, udev->devpath); + snprintf(devpath, sizeof(devpath), "usb\\%d-%s", udev->bus->busnum, udev->devpath); + printk(KERN_INFO "stellar device was found.\n"); return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); } - return smsusb_init_device(intf); + rc = smsusb_init_device(intf); + printk(KERN_INFO "%s rc %d\n", __FUNCTION__, rc); + return rc; } void smsusb_disconnect(struct usb_interface *intf) -- cgit v1.2.3 From 494d24c527e5ab43aecb8e77bfdc7e939466b134 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 14 Jun 2008 07:40:41 -0300 Subject: V4L/DVB (8278): sms1xxx: more codingstyle cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 8 ++++---- drivers/media/dvb/siano/smscoreapi.h | 2 +- drivers/media/dvb/siano/smsusb.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 76fa0f50775c..41c63e5622d8 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -347,7 +347,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, } cb->p = buffer; - cb->offset_in_common = buffer - (u8*) common_buffer; + cb->offset_in_common = buffer - (u8 *) common_buffer; cb->phys = common_buffer_phys + cb->offset_in_common; return cb; @@ -620,7 +620,7 @@ int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, l return rc; } -int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8* buffer, int size, int new_mode) +int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, int size, int new_mode) { PERROR("Feature not implemented yet\n"); return -EFAULT; @@ -888,7 +888,7 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, */ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) { - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8*) cb->p + cb->offset); + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; @@ -1120,7 +1120,7 @@ void smscore_unregister_client(smscore_client_t *client) int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) { smscore_device_t *coredev; - SmsMsgHdr_ST* phdr = (SmsMsgHdr_ST*) buffer; + SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) buffer; int rc; if ( client == NULL ) diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index c0a3be2fae72..601bdb8304db 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -515,7 +515,7 @@ extern int smscore_start_device(smscore_device_t *coredev); extern int smscore_load_firmware(smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler); -extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8* buffer, int size, int new_mode); +extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, int size, int new_mode); extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); extern int smscore_get_device_mode(smscore_device_t *coredev); diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index f719b72424d1..02528f12ecf0 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -313,13 +313,13 @@ int smsusb_init_device(struct usb_interface *intf) default: if (dev->udev->descriptor.idProduct == 0x200) { params.device_type = SMS_NOVA_A0; - printk(KERN_INFO "%s nova A0 found\n", __FUNCTION__ ); + printk(KERN_INFO "%s nova A0 found\n", __func__ ); } else if (dev->udev->descriptor.idProduct == 0x201) { params.device_type = SMS_NOVA_B0; - printk(KERN_INFO "%s nova B0 found\n", __FUNCTION__); + printk(KERN_INFO "%s nova B0 found\n", __func__); } else { params.device_type = SMS_VEGA; - printk(KERN_INFO "%s Vega found\n", __FUNCTION__); + printk(KERN_INFO "%s Vega found\n", __func__); } dev->buffer_size = USB2_BUFFER_SIZE; @@ -411,7 +411,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) } rc = smsusb_init_device(intf); - printk(KERN_INFO "%s rc %d\n", __FUNCTION__, rc); + printk(KERN_INFO "%s rc %d\n", __func__, rc); return rc; } -- cgit v1.2.3 From 73104fb3e4e692cb1f9505b548ab073b0859b256 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 14 Jun 2008 18:27:18 -0300 Subject: V4L/DVB (8279): sms1xxx: #define usb vid:pid's Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 02528f12ecf0..ca9bb36544c0 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -32,6 +32,14 @@ #define MAX_BUFFERS 50 #define MAX_URBS 10 +/* TO DO: move these to a header file */ +#define USB_VID_SIANO 0x187f + +#define USB_PID_STELLAR 0x0100 +#define USB_PID_NOVA_A 0x0200 +#define USB_PID_NOVA_B 0x0201 +#define USB_PID_VEGA 0x0300 + typedef struct _smsusb_device smsusb_device_t; typedef struct _smsusb_urb @@ -302,7 +310,8 @@ int smsusb_init_device(struct usb_interface *intf) dev->udev = interface_to_usbdev(intf); switch (dev->udev->descriptor.idProduct) { - case 0x100: + + case USB_PID_STELLAR: dev->buffer_size = USB1_BUFFER_SIZE; params.setmode_handler = smsusb1_setmode; @@ -311,13 +320,17 @@ int smsusb_init_device(struct usb_interface *intf) printk(KERN_INFO "%s stellar device found\n", __func__ ); break; default: - if (dev->udev->descriptor.idProduct == 0x200) { + switch (dev->udev->descriptor.idProduct) { + case USB_PID_NOVA_A: params.device_type = SMS_NOVA_A0; printk(KERN_INFO "%s nova A0 found\n", __func__ ); - } else if (dev->udev->descriptor.idProduct == 0x201) { + break; + default: + case USB_PID_NOVA_B: params.device_type = SMS_NOVA_B0; printk(KERN_INFO "%s nova B0 found\n", __func__); - } else { + break; + case USB_PID_VEGA: params.device_type = SMS_VEGA; printk(KERN_INFO "%s Vega found\n", __func__); } @@ -421,9 +434,9 @@ void smsusb_disconnect(struct usb_interface *intf) } static struct usb_device_id smsusb_id_table [] = { - { USB_DEVICE(0x187F, 0x0010) }, - { USB_DEVICE(0x187F, 0x0100) }, - { USB_DEVICE(0x187F, 0x0200) }, + { USB_DEVICE(USB_VID_SIANO, 0x0010) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_STELLAR) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_A) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, smsusb_id_table); -- cgit v1.2.3 From 822374165d6b11733467cfa2fa18234319198233 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 15:14:13 -0300 Subject: V4L/DVB (8280): sms1xxx: more codingstyle cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 651 +++++++++++++++++------------------ drivers/media/dvb/siano/smscoreapi.h | 394 ++++++++++----------- drivers/media/dvb/siano/smsdvb.c | 175 +++++----- drivers/media/dvb/siano/smsusb.c | 209 +++++------ 4 files changed, 714 insertions(+), 715 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 41c63e5622d8..ba72daf5ced0 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -33,23 +33,23 @@ #include "smscoreapi.h" -#define PERROR(fmt, args...) printk( KERN_ERR "smscore error: line %d- %s(): " fmt,__LINE__, __func__, ## args) +#define PERROR(fmt, args...)\ + printk(KERN_ERR "smscore error: line %d- %s(): " fmt, \ + __LINE__, __func__, ## args) #ifdef SMSCORE_DEBUG - #undef PWARNING -# define PWARNING(fmt, args...) printk( KERN_INFO "smscore warning: line %d- %s(): " fmt,__LINE__, __func__, ## args) +# define PWARNING(fmt, args...) printk(KERN_INFO "smscore warning: " \ + "line %d- %s(): " fmt, \ + __LINE__, __func__, ## args) #undef PDEBUG /* undef it, just in case */ -# define PDEBUG(fmt, args...) printk( KERN_INFO "smscore - %s(): " fmt, __func__, ## args) - +# define PDEBUG(fmt, args...) printk(KERN_INFO "smscore - %s(): " fmt, \ + __func__, ## args) #else /*SMSCORE_DEBUG*/ - #define PDEBUG(fmt, args...) #define PWARNING(fmt, args...) - #endif - typedef struct _smscore_device_notifyee { struct list_head entry; @@ -129,100 +129,86 @@ static int default_mode = 1; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -static smscore_registry_entry_t *smscore_find_registry ( char *devpath ) +static smscore_registry_entry_t *smscore_find_registry(char *devpath) { smscore_registry_entry_t *entry; struct list_head *next; kmutex_lock(&g_smscore_registrylock); - for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) - { + for (next = g_smscore_registry.next; + next != &g_smscore_registry; + next = next->next) { entry = (smscore_registry_entry_t *) next; - if (!strcmp(entry->devpath, devpath)) - { + if (!strcmp(entry->devpath, devpath)) { kmutex_unlock(&g_smscore_registrylock); return entry; } } - entry = (smscore_registry_entry_t *) kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); - if (entry) - { + entry = (smscore_registry_entry_t *) + kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); + if (entry) { entry->mode = default_mode; strcpy(entry->devpath, devpath); list_add(&entry->entry, &g_smscore_registry); - } - else - printk ( KERN_ERR "%s failed to create smscore_registry.\n", __func__ ); + } else + printk(KERN_ERR "%s failed to create smscore_registry.\n", + __func__); kmutex_unlock(&g_smscore_registrylock); return entry; } -int smscore_registry_getmode ( char *devpath ) +int smscore_registry_getmode(char *devpath) { smscore_registry_entry_t *entry; - entry = smscore_find_registry ( devpath ); - if ( entry ) - { + entry = smscore_find_registry(devpath); + if (entry) return entry->mode; - } else - { - printk ( KERN_ERR "%s No registry found.\n", __func__ ); - } + printk(KERN_ERR "%s No registry found.\n", __func__); + return default_mode; } -sms_device_type_st smscore_registry_gettype ( char *devpath ) +sms_device_type_st smscore_registry_gettype(char *devpath) { smscore_registry_entry_t *entry; - entry = smscore_find_registry ( devpath ); - if ( entry ) - { + entry = smscore_find_registry(devpath); + if (entry) return entry->type; - } else - { - printk ( KERN_ERR "%s No registry found.\n", __func__ ); - } + printk(KERN_ERR "%s No registry found.\n", __func__); + return -1; } -void smscore_registry_setmode ( char *devpath, int mode ) - { +void smscore_registry_setmode(char *devpath, int mode) +{ smscore_registry_entry_t *entry; - entry = smscore_find_registry ( devpath ); - if ( entry ) - { - entry->mode = mode; - } + entry = smscore_find_registry(devpath); + if (entry) + entry->mode = mode; else - { - printk ( KERN_ERR "%s No registry found.\n", __func__ ); - } - } + printk(KERN_ERR "%s No registry found.\n", __func__); +} -void smscore_registry_settype ( char *devpath, sms_device_type_st type ) +void smscore_registry_settype(char *devpath, sms_device_type_st type) { smscore_registry_entry_t *entry; - entry = smscore_find_registry ( devpath ); - if ( entry ) - { + entry = smscore_find_registry(devpath); + if (entry) entry->type = type; - } else - { - printk ( KERN_ERR "%s No registry found.\n", __func__ ); -} + printk(KERN_ERR "%s No registry found.\n", __func__); } void list_add_locked(struct list_head *new, struct list_head *head, - spinlock_t *lock) + spinlock_t *lock) { unsigned long flags; @@ -250,25 +236,22 @@ int smscore_register_hotplug(hotplug_t hotplug) kmutex_lock(&g_smscore_deviceslock); notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); - if (notifyee) - { - // now notify callback about existing devices + if (notifyee) { + /* now notify callback about existing devices */ first = &g_smscore_devices; - for (next = first->next; next != first && !rc; next = next->next) - { + for (next = first->next; + next != first && !rc; + next = next->next) { smscore_device_t *coredev = (smscore_device_t *) next; rc = hotplug(coredev, coredev->device, 1); } - if (rc >= 0) - { + if (rc >= 0) { notifyee->hotplug = hotplug; list_add(¬ifyee->entry, &g_smscore_notifyees); - } - else + } else kfree(notifyee); - } - else + } else rc = -ENOMEM; kmutex_unlock(&g_smscore_deviceslock); @@ -290,13 +273,12 @@ void smscore_unregister_hotplug(hotplug_t hotplug) first = &g_smscore_notifyees; - for (next = first->next; next != first;) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) next; + for (next = first->next; next != first;) { + smscore_device_notifyee_t *notifyee = + (smscore_device_notifyee_t *) next; next = next->next; - if (notifyee->hotplug == hotplug) - { + if (notifyee->hotplug == hotplug) { list_del(¬ifyee->entry); kfree(notifyee); } @@ -309,25 +291,24 @@ void smscore_notify_clients(smscore_device_t *coredev) { smscore_client_t *client; - // the client must call smscore_unregister_client from remove handler - while (!list_empty(&coredev->clients)) - { + /* the client must call smscore_unregister_client from remove handler */ + while (!list_empty(&coredev->clients)) { client = (smscore_client_t *) coredev->clients.next; client->onremove_handler(client->context); } } -int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, int arrival) +int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, + int arrival) { struct list_head *next, *first; int rc = 0; - // note: must be called under g_deviceslock + /* note: must be called under g_deviceslock */ first = &g_smscore_notifyees; - for (next = first->next; next != first; next = next->next) - { + for (next = first->next; next != first; next = next->next) { rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); if (rc < 0) break; @@ -340,8 +321,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, dma_addr_t common_buffer_phys) { smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); - if (!cb) - { + if (!cb) { printk(KERN_INFO "%s kmalloc(...) failed\n", __func__); return NULL; } @@ -354,38 +334,38 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, } /** - * creates coredev object for a device, prepares buffers, creates buffer mappings, notifies - * registered hotplugs about new device. + * creates coredev object for a device, prepares buffers, + * creates buffer mappings, notifies registered hotplugs about new device. * * @param params device pointer to struct with device specific parameters and handlers * @param coredev pointer to a value that receives created coredev object * * @return 0 on success, <0 on error. */ -int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev) +int smscore_register_device(smsdevice_params_t *params, + smscore_device_t **coredev) { smscore_device_t *dev; u8 *buffer; dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); - if (!dev) - { + if (!dev) { printk(KERN_INFO "%s kzalloc(...) failed\n", __func__); return -ENOMEM; } - // init list entry so it could be safe in smscore_unregister_device + /* init list entry so it could be safe in smscore_unregister_device */ INIT_LIST_HEAD(&dev->entry); - // init queues + /* init queues */ INIT_LIST_HEAD(&dev->clients); INIT_LIST_HEAD(&dev->buffers); - // init locks + /* init locks */ spin_lock_init(&dev->clientslock); spin_lock_init(&dev->bufferslock); - // init completion events + /* init completion events */ init_completion(&dev->version_ex_done); init_completion(&dev->data_download_done); init_completion(&dev->trigger_done); @@ -393,21 +373,22 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); - // alloc common buffer + /* alloc common buffer */ dev->common_buffer_size = params->buffer_size * params->num_buffers; - dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, &dev->common_buffer_phys, GFP_KERNEL | GFP_DMA); - if (!dev->common_buffer) - { + dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, + &dev->common_buffer_phys, + GFP_KERNEL | GFP_DMA); + if (!dev->common_buffer) { smscore_unregister_device(dev); return -ENOMEM; } - // prepare dma buffers - for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers ++, buffer += params->buffer_size) - { + /* prepare dma buffers */ + for (buffer = dev->common_buffer; + dev->num_buffers < params->num_buffers; + dev->num_buffers ++, buffer += params->buffer_size) { smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); - if (!cb) - { + if (!cb) { smscore_unregister_device(dev); return -ENOMEM; } @@ -415,7 +396,8 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored smscore_putbuffer(dev, cb); } - printk(KERN_INFO "%s allocated %d buffers\n", __func__, dev->num_buffers); + printk(KERN_INFO "%s allocated %d buffers\n", + __func__, dev->num_buffers); dev->mode = DEVICE_MODE_NONE; dev->context = params->context; @@ -429,9 +411,9 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored dev->device_flags = params->flags; strcpy(dev->devpath, params->devpath); - smscore_registry_settype ( dev->devpath, params->device_type ); + smscore_registry_settype(dev->devpath, params->device_type); - // add device to devices list + /* add device to devices list */ kmutex_lock(&g_smscore_deviceslock); list_add(&dev->entry, &g_smscore_devices); kmutex_unlock(&g_smscore_deviceslock); @@ -453,9 +435,8 @@ int smscore_register_device(smsdevice_params_t *params, smscore_device_t **cored int smscore_start_device(smscore_device_t *coredev) { int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); - if (rc < 0) - { - printk ( KERN_INFO "%s set device mode faile , rc %d\n", __func__, rc ); + if (rc < 0) { + printk(KERN_INFO "%s set device mode faile , rc %d\n", __func__, rc); return rc; } @@ -463,7 +444,8 @@ int smscore_start_device(smscore_device_t *coredev) rc = smscore_notify_callbacks(coredev, coredev->device, 1); - printk(KERN_INFO "%s device %p started, rc %d\n", __func__, coredev, rc); + printk(KERN_INFO "%s device %p started, rc %d\n", + __func__, coredev, rc); kmutex_unlock(&g_smscore_deviceslock); @@ -471,44 +453,49 @@ int smscore_start_device(smscore_device_t *coredev) } int smscore_sendrequest_and_wait(smscore_device_t *coredev, void *buffer, - size_t size, struct completion *completion) + size_t size, struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) - { - printk(KERN_INFO "%s sendrequest returned error %d\n", __func__, rc); + if (rc < 0) { + printk(KERN_INFO "%s sendrequest returned error %d\n", + __func__, rc); return rc; } - return wait_for_completion_timeout(completion, msecs_to_jiffies(10000)) ? 0 : -ETIME; + return wait_for_completion_timeout(completion, + msecs_to_jiffies(10000)) ? + 0 : -ETIME; } -int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_t size) +int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, + size_t size) { - SmsFirmware_ST* firmware = (SmsFirmware_ST*) buffer; + SmsFirmware_ST *firmware = (SmsFirmware_ST *) buffer; SmsMsgHdr_ST *msg; UINT32 mem_address = firmware->StartAddress; u8 *payload = firmware->Payload; int rc = 0; - printk(KERN_INFO "%s loading FW to addr 0x%x size %d\n", __func__, mem_address,firmware->Length); - if (coredev->preload_handler) - { + printk(KERN_INFO "%s loading FW to addr 0x%x size %d\n", + __func__, mem_address, firmware->Length); + if (coredev->preload_handler) { rc = coredev->preload_handler(coredev->context); if (rc < 0) return rc; } - // PAGE_SIZE buffer shall be enough and dma aligned + /* PAGE_SIZE buffer shall be enough and dma aligned */ msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); if (!msg) return -ENOMEM; - if (coredev->mode != DEVICE_MODE_NONE) - { + if (coredev->mode != DEVICE_MODE_NONE) { PDEBUG("Sending reload command\n"); - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); + SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, + sizeof(SmsMsgHdr_ST)); + rc = smscore_sendrequest_and_wait(coredev, msg, + msg->msgLength, + &coredev->reload_start_done); mem_address = *(UINT32*) &payload[20]; } @@ -517,12 +504,15 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, (UINT16)(sizeof(SmsMsgHdr_ST) + sizeof(UINT32) + payload_size)); + SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, + (UINT16)(sizeof(SmsMsgHdr_ST) + + sizeof(UINT32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); - if (coredev->device_flags & SMS_ROM_NO_RESPONSE && coredev->mode == DEVICE_MODE_NONE) + if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && + (coredev->mode == DEVICE_MODE_NONE)) rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); else rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); @@ -532,13 +522,13 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ mem_address += payload_size; } - if (rc >= 0) - { - if (coredev->mode == DEVICE_MODE_NONE) - { - SmsMsgData_ST* TriggerMsg = (SmsMsgData_ST*) msg; + if (rc >= 0) { + if (coredev->mode == DEVICE_MODE_NONE) { + SmsMsgData_ST *TriggerMsg = (SmsMsgData_ST *) msg; - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + sizeof(UINT32) * 5); + SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, + sizeof(SmsMsgHdr_ST) + + sizeof(UINT32) * 5); TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point TriggerMsg->msgData[1] = 5; // Priority @@ -546,24 +536,23 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ TriggerMsg->msgData[3] = 0; // Parameter TriggerMsg->msgData[4] = 4; // Task ID - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) - { + if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); msleep(100); - } - else + } else rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); - } - else - { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); + } else { + SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, + sizeof(SmsMsgHdr_ST)); - rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); + rc = coredev->sendrequest_handler(coredev->context, + msg, msg->msgLength); } - msleep ( 500 ); + msleep(500); } - printk("%s rc=%d, postload=%p \n", __func__, rc, coredev->postload_handler); + printk("%s rc=%d, postload=%p \n", __func__, rc, + coredev->postload_handler); kfree(msg); @@ -581,37 +570,39 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, size_ * * @return 0 on success, <0 on error. */ -int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler) +int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, + loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; const struct firmware *fw; u8 *fw_buffer; - if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) + if (loadfirmware_handler == NULL && !(coredev->device_flags & + SMS_DEVICE_FAMILY2)) return -EINVAL; rc = request_firmware(&fw, filename, coredev->device); - if (rc < 0) - { - printk(KERN_INFO "%s failed to open \"%s\"\n", __func__, filename); + if (rc < 0) { + printk(KERN_INFO "%s failed to open \"%s\"\n", + __func__, filename); return rc; } - printk(KERN_INFO "%s read FW %s, size=%d\"\n", __func__, filename, fw->size); - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); - if (fw_buffer) - { + printk(KERN_INFO "%s read FW %s, size=%d\"\n", __func__, + filename, fw->size); + fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), + GFP_KERNEL | GFP_DMA); + if (fw_buffer) { memcpy(fw_buffer, fw->data, fw->size); rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : + smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : loadfirmware_handler(coredev->context, fw_buffer, fw->size); kfree(fw_buffer); - } - else - { - printk(KERN_INFO "%s failed to allocate firmware buffer\n", __func__); + } else { + printk(KERN_INFO "%s failed to allocate firmware buffer\n", + __func__); rc = -ENOMEM; } @@ -620,7 +611,8 @@ int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, l return rc; } -int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, int size, int new_mode) +int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, + int size, int new_mode) { PERROR("Feature not implemented yet\n"); return -EFAULT; @@ -644,32 +636,33 @@ void smscore_unregister_device(smscore_device_t *coredev) smscore_notify_clients(coredev); smscore_notify_callbacks(coredev, NULL, 0); - // at this point all buffers should be back - // onresponse must no longer be called + /* at this point all buffers should be back + * onresponse must no longer be called */ - while (1) - { - while ((cb = smscore_getbuffer(coredev))) - { + while (1) { + while ((cb = smscore_getbuffer(coredev))) { kfree(cb); num_buffers ++; } if (num_buffers == coredev->num_buffers) break; - if (++retry > 10) - { - printk(KERN_INFO "%s exiting although not all buffers released.\n", __func__); + if (++retry > 10) { + printk(KERN_INFO "%s exiting although " + "not all buffers released.\n", __func__); break; } - printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, coredev->num_buffers - num_buffers); + printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, + coredev->num_buffers - num_buffers); msleep(100); } printk(KERN_INFO "%s freed %d buffers\n", __func__, num_buffers); if (coredev->common_buffer) - dma_free_coherent(NULL, coredev->common_buffer_size, coredev->common_buffer, coredev->common_buffer_phys); + dma_free_coherent(NULL, coredev->common_buffer_size, + coredev->common_buffer, + coredev->common_buffer_phys); list_del(&coredev->entry); kfree(coredev); @@ -681,7 +674,8 @@ void smscore_unregister_device(smscore_device_t *coredev) int smscore_detect_mode(smscore_device_t *coredev) { - void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); + void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); int rc; @@ -690,20 +684,17 @@ int smscore_detect_mode(smscore_device_t *coredev) SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); - if (rc == -ETIME) - { + rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, + &coredev->version_ex_done); + if (rc == -ETIME) { printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __func__); - if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) - { + if (wait_for_completion_timeout(&coredev->resume_done, + msecs_to_jiffies(5000))) { rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc < 0) - { printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __func__, rc); - } - } - else + } else rc = -ETIME; } @@ -712,17 +703,16 @@ int smscore_detect_mode(smscore_device_t *coredev) return rc; } -char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = -{ +char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*Stellar NOVA A0 Nova B0 VEGA*/ - /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "none" "none"}, - /*DABIP*/ {"none", "none", "none", "none"}, - /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, - /*ISDBTBDA*/{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} + /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "none", "none"}, + /*DABIP*/ {"none", "none", "none", "none"}, + /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, + /*ISDBTBDA*/{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, + /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; @@ -741,51 +731,44 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) int rc = 0; sms_device_type_st type; - PDEBUG("set device mode to %d\n", mode ); - if (coredev->device_flags & SMS_DEVICE_FAMILY2) - { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) - { - printk(KERN_INFO "%s invalid mode specified %d\n", __func__, mode); + PDEBUG("set device mode to %d\n", mode); + if (coredev->device_flags & SMS_DEVICE_FAMILY2) { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { + printk(KERN_INFO "%s invalid mode specified %d\n", + __func__, mode); return -EINVAL; } smscore_registry_setmode(coredev->devpath, mode); - if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) - { + if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); - if (rc < 0) - { - printk(KERN_INFO "%s mode detect failed %d\n", __func__, rc); + if (rc < 0) { + printk(KERN_INFO "%s mode detect failed %d\n", + __func__, rc); return rc; - } + } } - if (coredev->mode == mode) - { - printk(KERN_INFO "%s device mode %d already set\n", __func__, mode); + if (coredev->mode == mode) { + printk(KERN_INFO "%s device mode %d already set\n", + __func__, mode); return 0; } - if (!(coredev->modes_supported & (1 << mode))) - { - type = smscore_registry_gettype ( coredev->devpath ); - rc = smscore_load_firmware_from_file ( coredev, smscore_fw_lkup[mode][type], NULL ); - if (rc < 0) - { + if (!(coredev->modes_supported & (1 << mode))) { + type = smscore_registry_gettype(coredev->devpath); + rc = smscore_load_firmware_from_file(coredev, smscore_fw_lkup[mode][type], NULL); + if (rc < 0) { printk(KERN_INFO "%s load firmware failed %d\n", __func__, rc); return rc; - } - } - else - { + } + } else printk(KERN_INFO "%s mode %d supported by running firmware\n", __func__, mode); - } - buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) - { + buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (buffer) { SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); @@ -794,32 +777,28 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); kfree(buffer); - } - else - { + } else { printk(KERN_INFO "%s Could not allocate buffer for init device message.\n", __func__); rc = -ENOMEM; - } - } - else - { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) - { - printk(KERN_INFO "%s invalid mode specified %d\n", __func__, mode); + } + } else { + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { + printk(KERN_INFO "%s invalid mode specified %d\n", + __func__, mode); return -EINVAL; } smscore_registry_setmode(coredev->devpath, mode); if (coredev->detectmode_handler) - coredev->detectmode_handler(coredev->context, &coredev->mode); + coredev->detectmode_handler(coredev->context, + &coredev->mode); if (coredev->mode != mode && coredev->setmode_handler) rc = coredev->setmode_handler(coredev->context, mode); } - if (rc >= 0) - { + if (rc >= 0) { coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; } @@ -847,7 +826,7 @@ int smscore_get_device_mode(smscore_device_t *coredev) * * @param coredev pointer to a coredev object returned by smscore_register_device * @param data_type client data type (SMS_DONT_CARE for all types) - * @param id client id (SMS_DONT_CARE for all id ) + * @param id client id (SMS_DONT_CARE for all id) * */ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, int id) @@ -860,20 +839,21 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, spin_lock_irqsave(&coredev->clientslock, flags); first = &coredev->clients; - for (next = first->next; (next != first) && !client; next = next->next) - { - firstid = &((smscore_client_t*)next )->idlist; - for (nextid = firstid->next ; nextid != firstid ; nextid = nextid->next) - { + for (next = first->next; + (next != first) && !client; + next = next->next) { + firstid = &((smscore_client_t*)next)->idlist; + for (nextid = firstid->next; + nextid != firstid; + nextid = nextid->next) { if ((((smscore_idlist_t*)nextid)->id == id) && (((smscore_idlist_t*)nextid)->data_type == data_type || - (((smscore_idlist_t*)nextid)->data_type == 0))) - { - client = (smscore_client_t*) next; - break; + (((smscore_idlist_t*)nextid)->data_type == 0))) { + client = (smscore_client_t*) next; + break; + } } } - } spin_unlock_irqrestore(&coredev->clientslock, flags); return client; } @@ -889,7 +869,8 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) { SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); - smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); + smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, + phdr->msgDstId); int rc = -EBUSY; static unsigned long last_sample_time = 0; @@ -901,67 +882,62 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) if (time_now - last_sample_time > 10000) { - printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); + printk("\n%s data rate %d bytes/secs\n", __func__, + (int)((data_total * 1000) / + (time_now - last_sample_time))); last_sample_time = time_now; data_total = 0; } data_total += cb->size; - /* If no client registered for type & id, check for control client where type is not registered*/ -// if (!client) -// client = smscore_find_client( coredev, 0, phdr->msgDstId); + /* If no client registered for type & id, + * check for control client where type is not registered */ if (client) rc = client->onresponse_handler(client->context, cb); - if (rc < 0) - { - switch (phdr->msgType) + if (rc < 0) { + switch (phdr->msgType) { + case MSG_SMS_GET_VERSION_EX_RES: { - case MSG_SMS_GET_VERSION_EX_RES: - { - SmsVersionRes_ST *ver = (SmsVersionRes_ST*) phdr; - printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d prots 0x%x ver %d.%d\n", __func__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); - - coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; - coredev->modes_supported = ver->SupportedProtocols; - - complete(&coredev->version_ex_done); - break; - } - - case MSG_SMS_INIT_DEVICE_RES: - printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __func__); - complete(&coredev->init_device_done); - break; - - case MSG_SW_RELOAD_START_RES: - printk("%s: MSG_SW_RELOAD_START_RES\n", __func__); - complete(&coredev->reload_start_done); - break; - - case MSG_SMS_DATA_DOWNLOAD_RES: - complete(&coredev->data_download_done); - break; - - case MSG_SW_RELOAD_EXEC_RES: - printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __func__); - break; + SmsVersionRes_ST *ver = (SmsVersionRes_ST *) phdr; + printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d " + "prots 0x%x ver %d.%d\n", __func__, + ver->FirmwareId, ver->SupportedProtocols, + ver->RomVersionMajor, ver->RomVersionMinor); - case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __func__); - complete(&coredev->trigger_done); - break; - - case MSG_SMS_SLEEP_RESUME_COMP_IND: - complete(&coredev->resume_done); - break; + coredev->mode = ver->FirmwareId == 255 ? + DEVICE_MODE_NONE : ver->FirmwareId; + coredev->modes_supported = ver->SupportedProtocols; - default: - //printk(KERN_INFO "%s no client (%p) or error (%d), type:%d dstid:%d\n", __func__, client, rc, phdr->msgType, phdr->msgDstId); - break; + complete(&coredev->version_ex_done); + break; + } + case MSG_SMS_INIT_DEVICE_RES: + printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __func__); + complete(&coredev->init_device_done); + break; + case MSG_SW_RELOAD_START_RES: + printk("%s: MSG_SW_RELOAD_START_RES\n", __func__); + complete(&coredev->reload_start_done); + break; + case MSG_SMS_DATA_DOWNLOAD_RES: + complete(&coredev->data_download_done); + break; + case MSG_SW_RELOAD_EXEC_RES: + printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __func__); + break; + case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: + printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", + __func__); + complete(&coredev->trigger_done); + break; + case MSG_SMS_SLEEP_RESUME_COMP_IND: + complete(&coredev->resume_done); + break; + default: + break; } - smscore_putbuffer(coredev, cb); } } @@ -980,8 +956,7 @@ smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) - { + if (!list_empty(&coredev->buffers)) { cb = (smscore_buffer_t *) coredev->buffers.next; list_del(&cb->entry); } @@ -1003,35 +978,33 @@ void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int data_type, int id) +int smscore_validate_client(smscore_device_t *coredev, + smscore_client_t *client, int data_type, int id) { smscore_idlist_t *listentry; smscore_client_t *registered_client; - if ( !client ) - { + if (!client) { PERROR("bad parameter.\n"); return -EFAULT; } registered_client = smscore_find_client(coredev, data_type, id); - if (registered_client == client) - { + if (registered_client == client) { return 0; } - if (registered_client) - { + if (registered_client) { PERROR("The msg ID already registered to another client.\n"); return -EEXIST; } - listentry = kzalloc ( sizeof ( smscore_idlist_t ), GFP_KERNEL ); - if ( !listentry ) - { + listentry = kzalloc(sizeof(smscore_idlist_t), GFP_KERNEL); + if (!listentry) { PERROR("Can't allocate memory for client id.\n"); return -ENOMEM; } listentry->id = id; listentry->data_type = data_type; - list_add_locked ( &listentry->entry, &client->idlist, &coredev->clientslock ); + list_add_locked(&listentry->entry, &client->idlist, + &coredev->clientslock); return 0; } @@ -1051,29 +1024,31 @@ int smscore_validate_client(smscore_device_t *coredev, smscore_client_t *client, int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) { smscore_client_t *newclient; - // check that no other channel with same parameters exists - if (smscore_find_client(coredev, params->data_type, params->initial_id)) - { + /* check that no other channel with same parameters exists */ + if (smscore_find_client(coredev, params->data_type, + params->initial_id)) { PERROR("Client already exist.\n"); return -EEXIST; } newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); - if (!newclient) - { + if (!newclient) { PERROR("Failed to allocate memory for client.\n"); return -ENOMEM; } - INIT_LIST_HEAD ( &newclient->idlist); + INIT_LIST_HEAD(&newclient->idlist); newclient->coredev = coredev; newclient->onresponse_handler = params->onresponse_handler; newclient->onremove_handler = params->onremove_handler; newclient->context = params->context; - list_add_locked(&newclient->entry, &coredev->clients, &coredev->clientslock); - smscore_validate_client(coredev, newclient, params->data_type, params->initial_id); + list_add_locked(&newclient->entry, &coredev->clients, + &coredev->clientslock); + smscore_validate_client(coredev, newclient, params->data_type, + params->initial_id); *client = newclient; - PDEBUG ( "%p %d %d\n", params->context, params->data_type, params->initial_id ); + PDEBUG("%p %d %d\n", params->context, params->data_type, + params->initial_id); return 0; } @@ -1092,11 +1067,11 @@ void smscore_unregister_client(smscore_client_t *client) spin_lock_irqsave(&coredev->clientslock, flags); - while (!list_empty( &client->idlist)) - { - smscore_idlist_t *identry = (smscore_idlist_t*)client->idlist.next; - list_del ( &identry->entry ); - kfree ( identry ); + while (!list_empty(&client->idlist)) { + smscore_idlist_t *identry = + (smscore_idlist_t*) client->idlist.next; + list_del(&identry->entry); + kfree(identry); } printk(KERN_INFO "%s %p\n", __func__, client->context); @@ -1123,22 +1098,21 @@ int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) buffer; int rc; - if ( client == NULL ) - { - printk(KERN_ERR "%s Got NULL client\n", __func__ ); + if (client == NULL) { + printk(KERN_ERR "%s Got NULL client\n", __func__); return -EINVAL; } coredev = client->coredev; - // check that no other channel with same id exists - if ( coredev == NULL ) - { - printk(KERN_ERR "%s Got NULL coredev\n", __func__ ); + /* check that no other channel with same id exists */ + if (coredev == NULL) { + printk(KERN_ERR "%s Got NULL coredev\n", __func__); return -EINVAL; } - rc = smscore_validate_client(client->coredev, client, 0, phdr->msgSrcId); + rc = smscore_validate_client(client->coredev, client, 0, + phdr->msgSrcId); if (rc < 0) return rc; @@ -1168,21 +1142,25 @@ int smscore_get_common_buffer_size(smscore_device_t *coredev) int smscore_map_common_buffer(smscore_device_t *coredev, struct vm_area_struct *vma) { - unsigned long end = vma->vm_end, start = vma->vm_start, size = PAGE_ALIGN(coredev->common_buffer_size); + unsigned long end = vma->vm_end, + start = vma->vm_start, + size = PAGE_ALIGN(coredev->common_buffer_size); - if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) - { + if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || + (vma->vm_flags & VM_WRITE)) { printk(KERN_INFO "%s invalid vm flags\n", __func__); return -EINVAL; } - if ((end - start) != size) - { - printk(KERN_INFO "%s invalid size %d expected %d\n", __func__, (int)(end - start), (int) size); + if ((end - start) != size) { + printk(KERN_INFO "%s invalid size %d expected %d\n", + __func__, (int)(end - start), (int) size); return -EINVAL; } - if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) + if (remap_pfn_range(vma, start, + coredev->common_buffer_phys >> PAGE_SHIFT, + size, pgprot_noncached(vma->vm_page_prot))) { printk(KERN_INFO "%s remap_page_range failed\n", __func__); return -EAGAIN; @@ -1217,9 +1195,9 @@ void smscore_module_exit(void) { kmutex_lock(&g_smscore_deviceslock); - while (!list_empty(&g_smscore_notifyees)) - { - smscore_device_notifyee_t *notifyee = (smscore_device_notifyee_t *) g_smscore_notifyees.next; + while (!list_empty(&g_smscore_notifyees)) { + smscore_device_notifyee_t *notifyee = + (smscore_device_notifyee_t *) g_smscore_notifyees.next; list_del(¬ifyee->entry); kfree(notifyee); @@ -1227,9 +1205,9 @@ void smscore_module_exit(void) kmutex_unlock(&g_smscore_deviceslock); kmutex_lock(&g_smscore_registrylock); - while (!list_empty(&g_smscore_registry)) - { - smscore_registry_entry_t *entry = (smscore_registry_entry_t *) g_smscore_registry.next; + while (!list_empty(&g_smscore_registry)) { + smscore_registry_entry_t *entry = + (smscore_registry_entry_t *) g_smscore_registry.next; list_del(&entry->entry); kfree(entry); @@ -1249,6 +1227,5 @@ module_init(smscore_module_init); module_exit(smscore_module_exit); MODULE_DESCRIPTION("smscore"); -MODULE_AUTHOR ( "Siano Mobile Silicon,,, (doronc@siano-ms.com)" ); +MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 601bdb8304db..79fa71a5f284 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -82,12 +82,12 @@ typedef void (*onremove_t)(void *context); typedef struct _smscore_buffer { - // public members, once passed to clients can be changed freely + /* public members, once passed to clients can be changed freely */ struct list_head entry; int size; int offset; - // private members, read-only for clients + /* private members, read-only for clients */ void *p; dma_addr_t phys; unsigned long offset_in_common; @@ -123,7 +123,7 @@ typedef struct _smsclient_params void *context; } smsclient_params_t; -// GPIO definitions for antenna frequency domain control (SMS8021) +/* GPIO definitions for antenna frequency domain control (SMS8021) */ #define SMS_ANTENNA_GPIO_0 1 #define SMS_ANTENNA_GPIO_1 0 @@ -223,7 +223,7 @@ typedef struct SmsMsgHdr_S UINT16 msgType; UINT8 msgSrcId; UINT8 msgDstId; - UINT16 msgLength; // Length is of the entire message, including header + UINT16 msgLength; /* Length of entire message, including header */ UINT16 msgFlags; } SmsMsgHdr_ST; @@ -244,24 +244,24 @@ typedef struct SmsVersionRes_S { SmsMsgHdr_ST xMsgHeader; - UINT16 ChipModel; // e.g. 0x1102 for SMS-1102 "Nova" - UINT8 Step; // 0 - Step A - UINT8 MetalFix; // 0 - Metal 0 + UINT16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ + UINT8 Step; /* 0 - Step A */ + UINT8 MetalFix; /* 0 - Metal 0 */ - UINT8 FirmwareId; // 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E - UINT8 SupportedProtocols; // Bitwise OR combination of supported protocols + UINT8 FirmwareId; /* 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E */ + UINT8 SupportedProtocols; /* Bitwise OR combination of supported protocols */ - UINT8 VersionMajor; - UINT8 VersionMinor; - UINT8 VersionPatch; - UINT8 VersionFieldPatch; + UINT8 VersionMajor; + UINT8 VersionMinor; + UINT8 VersionPatch; + UINT8 VersionFieldPatch; - UINT8 RomVersionMajor; - UINT8 RomVersionMinor; - UINT8 RomVersionPatch; - UINT8 RomVersionFieldPatch; + UINT8 RomVersionMajor; + UINT8 RomVersionMinor; + UINT8 RomVersionPatch; + UINT8 RomVersionFieldPatch; - UINT8 TextLabel[34]; + UINT8 TextLabel[34]; } SmsVersionRes_ST; typedef struct SmsFirmware_S @@ -274,59 +274,60 @@ typedef struct SmsFirmware_S typedef struct SMSHOSTLIB_STATISTICS_S { - UINT32 Reserved; //!< Reserved - - /// Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - /// Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 FIB_CRC; //!< CRC errors percentage, valid only for DAB - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - /// Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz, valid only for DVB-T/H - UINT32 TransmissionMode; //!< Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos - UINT32 ModemState; //!< from SMS_DvbModemState_ET , valid only for DVB-T/H - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value , valid only for DVB-T/H - UINT32 CodeRate; //!< Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H - UINT32 Hierarchy; //!< Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H - UINT32 Constellation; //!< Constellation from SMS_Constellation_ET, valid only for DVB-T/H - - /// Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding - /// Common params - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - - /// Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. - - /// DAB/T-DMB - UINT32 PreBER; //!< DAB/T-DMB only: Pre Viterbi BER [1E-5] - - /// DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered + UINT32 Reserved; /* Reserved */ + + /* Common parameters */ + UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + /* Reception quality */ + INT32 SNR; /* dB */ + UINT32 BER; /* Post Viterbi BER [1E-5] */ + UINT32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ + UINT32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ + UINT32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + INT32 RSSI; /* dBm */ + INT32 InBandPwr; /* In band power in dBM */ + INT32 CarrierOffset; /* Carrier Offset in bin/1024 */ + + /* Transmission parameters */ + UINT32 Frequency; /* Frequency in Hz */ + UINT32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ + UINT32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos */ + UINT32 ModemState; /* from SMS_DvbModemState_ET , valid only for DVB-T/H */ + UINT32 GuardInterval; /* Guard Interval, 1 divided by value , valid only for DVB-T/H */ + UINT32 CodeRate; /* Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ + UINT32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ + UINT32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H */ + UINT32 Constellation; /* Constellation from SMS_Constellation_ET, valid only for DVB-T/H */ + + /* Burst parameters, valid only for DVB-H */ + UINT32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ + UINT32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ + UINT32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ + UINT32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ + UINT32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ + UINT32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ + UINT32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + UINT32 TotalTSPackets; /* Total number of transport-stream packets */ + UINT32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding */ + UINT32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding */ + UINT32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding */ + + /* Common params */ + UINT32 BERErrorCount; /* Number of errornous SYNC bits. */ + UINT32 BERBitCount; /* Total number of SYNC bits. */ + + /* Interface information */ + UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ + + /* DAB/T-DMB */ + UINT32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ + + /* DVB-H TPS parameters */ + UINT32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ } SMSHOSTLIB_STATISTICS_ST; @@ -336,147 +337,151 @@ typedef struct SMSHOSTLIB_STATISTICS_ST Stat; - // Split the calc of the SNR in DAB - UINT32 Signal; //!< dB - UINT32 Noise; //!< dB + /* Split the calc of the SNR in DAB */ + UINT32 Signal; /* dB */ + UINT32 Noise; /* dB */ } SmsMsgStatisticsInfo_ST; typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S { - // Per-layer information - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist - UINT32 BER; //!< Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 BERErrorCount; //!< Post Viterbi Error Bits Count - UINT32 BERBitCount; //!< Post Viterbi Total Bits Count - UINT32 PreBER; //!< Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A - UINT32 TS_PER; //!< Transport stream PER [%], 0xFFFFFFFF indicate N/A - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 TILdepthI; //!< Time interleaver depth I parameter, 255 means layer does not exist - UINT32 NumberOfSegments; //!< Number of segments in layer A, 255 means layer does not exist - UINT32 TMCCErrors; //!< TMCC errors + /* Per-layer information */ + UINT32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist */ + UINT32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist */ + UINT32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ + UINT32 BERErrorCount; /* Post Viterbi Error Bits Count */ + UINT32 BERBitCount; /* Post Viterbi Total Bits Count */ + UINT32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ + UINT32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ + UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + UINT32 TotalTSPackets; /* Total number of transport-stream packets */ + UINT32 TILdepthI; /* Time interleaver depth I parameter, 255 means layer does not exist */ + UINT32 NumberOfSegments; /* Number of segments in layer A, 255 means layer does not exist */ + UINT32 TMCCErrors; /* TMCC errors */ } SMSHOSTLIB_ISDBT_LAYER_STAT_ST; typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S { - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in Hz - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 TransmissionMode; //!< ISDB-T transmission mode - UINT32 ModemState; //!< 0 - Acquisition, 1 - Locked - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 SystemType; //!< ISDB-T system type (ISDB-T / ISDB-Tsb) - UINT32 PartialReception; //!< TRUE - partial reception, FALSE otherwise - UINT32 NumOfLayers; //!< Number of ISDB-T layers in the network - - // Per-layer information - // Layers A, B and C - SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; //!< Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + UINT32 StatisticsType; /* Enumerator identifying the type of the + * structure. Values are the same as + * SMSHOSTLIB_DEVICE_MODES_E + * + * This field MUST always be first in any + * statistics structure */ + + UINT32 FullSize; /* Total size of the structure returned by the modem. If the size requested by + * the host is smaller than FullSize, the struct will be truncated */ + + /* Common parameters */ + UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + /* Reception quality */ + INT32 SNR; /* dB */ + INT32 RSSI; /* dBm */ + INT32 InBandPwr; /* In band power in dBM */ + INT32 CarrierOffset; /* Carrier Offset in Hz */ + + /* Transmission parameters */ + UINT32 Frequency; /* Frequency in Hz */ + UINT32 Bandwidth; /* Bandwidth in MHz */ + UINT32 TransmissionMode; /* ISDB-T transmission mode */ + UINT32 ModemState; /* 0 - Acquisition, 1 - Locked */ + UINT32 GuardInterval; /* Guard Interval, 1 divided by value */ + UINT32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ + UINT32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ + UINT32 NumOfLayers; /* Number of ISDB-T layers in the network */ + + /* Per-layer information */ + /* Layers A, B and C */ + SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ + + /* Interface information */ + UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ } SMSHOSTLIB_STATISTICS_ISDBT_ST; typedef struct SMSHOSTLIB_STATISTICS_DVB_S { - UINT32 StatisticsType; //!< Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - //!< This fiels MUST always first in any statistics structure - - UINT32 FullSize; //!< Total size of the structure returned by the modem. If the size requested by - //!< the host is smaller than FullSize, the struct will be truncated - // Common parameters - UINT32 IsRfLocked; //!< 0 - not locked, 1 - locked - UINT32 IsDemodLocked; //!< 0 - not locked, 1 - locked - UINT32 IsExternalLNAOn; //!< 0 - external LNA off, 1 - external LNA on - - // Reception quality - INT32 SNR; //!< dB - UINT32 BER; //!< Post Viterbi BER [1E-5] - UINT32 BERErrorCount; //!< Number of errornous SYNC bits. - UINT32 BERBitCount; //!< Total number of SYNC bits. - UINT32 TS_PER; //!< Transport stream PER, 0xFFFFFFFF indicate N/A - UINT32 MFER; //!< DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H - INT32 RSSI; //!< dBm - INT32 InBandPwr; //!< In band power in dBM - INT32 CarrierOffset; //!< Carrier Offset in bin/1024 - - // Transmission parameters - UINT32 Frequency; //!< Frequency in Hz - UINT32 Bandwidth; //!< Bandwidth in MHz - UINT32 ModemState; //!< from SMSHOSTLIB_DVB_MODEM_STATE_ET - UINT32 TransmissionMode; //!< FFT mode carriers in Kilos - UINT32 GuardInterval; //!< Guard Interval, 1 divided by value - UINT32 CodeRate; //!< Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 LPCodeRate; //!< Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET - UINT32 Hierarchy; //!< Hierarchy from SMSHOSTLIB_HIERARCHY_ET - UINT32 Constellation; //!< Constellation from SMSHOSTLIB_CONSTELLATION_ET - - // Burst parameters, valid only for DVB-H - UINT32 BurstSize; //!< Current burst size in bytes, valid only for DVB-H - UINT32 BurstDuration; //!< Current burst duration in mSec, valid only for DVB-H - UINT32 BurstCycleTime; //!< Current burst cycle time in mSec, valid only for DVB-H - UINT32 CalculatedBurstCycleTime;//!< Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H - UINT32 NumOfRows; //!< Number of rows in MPE table, valid only for DVB-H - UINT32 NumOfPaddCols; //!< Number of padding columns in MPE table, valid only for DVB-H - UINT32 NumOfPunctCols; //!< Number of puncturing columns in MPE table, valid only for DVB-H - UINT32 ErrorTSPackets; //!< Number of erroneous transport-stream packets - UINT32 TotalTSPackets; //!< Total number of transport-stream packets - UINT32 NumOfValidMpeTlbs; //!< Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfInvalidMpeTlbs; //!< Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H - UINT32 NumOfCorrectedMpeTlbs; //!< Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H - UINT32 NumMPEReceived; //!< DVB-H, Num MPE section received - - // DVB-H TPS parameters - UINT32 CellId; //!< TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered - UINT32 DvbhSrvIndHP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - UINT32 DvbhSrvIndLP; //!< DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator - - // Interface information - UINT32 SmsToHostTxErrors; //!< Total number of transmission errors. + UINT32 StatisticsType; /* Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + * This fiels MUST always first in any statistics structure */ + + UINT32 FullSize; /* Total size of the structure returned by the modem. If the size requested by + * the host is smaller than FullSize, the struct will be truncated */ + /* Common parameters */ + UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + + /* Reception quality */ + INT32 SNR; /* dB */ + UINT32 BER; /* Post Viterbi BER [1E-5] */ + UINT32 BERErrorCount; /* Number of errornous SYNC bits. */ + UINT32 BERBitCount; /* Total number of SYNC bits. */ + UINT32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */ + UINT32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + INT32 RSSI; /* dBm */ + INT32 InBandPwr; /* In band power in dBM */ + INT32 CarrierOffset; /* Carrier Offset in bin/1024 */ + + /* Transmission parameters */ + UINT32 Frequency; /* Frequency in Hz */ + UINT32 Bandwidth; /* Bandwidth in MHz */ + UINT32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + UINT32 TransmissionMode; /* FFT mode carriers in Kilos */ + UINT32 GuardInterval; /* Guard Interval, 1 divided by value */ + UINT32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + UINT32 LPCodeRate; /* Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + UINT32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ + UINT32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */ + + /* Burst parameters, valid only for DVB-H */ + UINT32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ + UINT32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ + UINT32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ + UINT32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ + UINT32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ + UINT32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ + UINT32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + UINT32 TotalTSPackets; /* Total number of transport-stream packets */ + UINT32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H */ + UINT32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H */ + UINT32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H */ + UINT32 NumMPEReceived; /* DVB-H, Num MPE section received */ + + /* DVB-H TPS parameters */ + UINT32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ + UINT32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ + UINT32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ + + /* Interface information */ + UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ } SMSHOSTLIB_STATISTICS_DVB_ST; typedef struct SMSHOSTLIB_GPIO_CONFIG_S { - UINT8 Direction; //!< GPIO direction: Input - 0, Output - 1 - UINT8 PullUpDown; //!< PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 - UINT8 InputCharacteristics; //!< Input Characteristics: Normal - 0, Schmitt trigger - 1 - UINT8 OutputSlewRate; //!< Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 - UINT8 OutputDriving; //!< Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 + UINT8 Direction; /* GPIO direction: Input - 0, Output - 1 */ + UINT8 PullUpDown; /* PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 */ + UINT8 InputCharacteristics; /* Input Characteristics: Normal - 0, Schmitt trigger - 1 */ + UINT8 OutputSlewRate; /* Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 */ + UINT8 OutputDriving; /* Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ } SMSHOSTLIB_GPIO_CONFIG_ST; typedef struct SMSHOSTLIB_I2C_REQ_S { - UINT32 DeviceAddress; // I2c device address - UINT32 WriteCount; // number of bytes to write - UINT32 ReadCount; // number of bytes to read + UINT32 DeviceAddress; /* I2c device address */ + UINT32 WriteCount; /* number of bytes to write */ + UINT32 ReadCount; /* number of bytes to read */ UINT8 Data[1]; } SMSHOSTLIB_I2C_REQ_ST; typedef struct SMSHOSTLIB_I2C_RES_S { - UINT32 Status; // non-zero value in case of failure - UINT32 ReadCount; // number of bytes read + UINT32 Status; /* non-zero value in case of failure */ + UINT32 ReadCount; /* number of bytes read */ UINT8 Data[1]; } SMSHOSTLIB_I2C_RES_ST; @@ -492,12 +497,12 @@ typedef struct _smsdvb_client struct dmxdev dmxdev; struct dvb_frontend frontend; - fe_status_t fe_status; - int fe_ber, fe_snr, fe_signal_strength; + fe_status_t fe_status; + int fe_ber, fe_snr, fe_signal_strength; struct completion tune_done, stat_done; - // todo: save freq/band instead whole struct + /* todo: save freq/band instead whole struct */ struct dvb_frontend_parameters fe_params; } smsdvb_client_t; @@ -508,14 +513,17 @@ extern int smscore_registry_getmode(char *devpath); extern int smscore_register_hotplug(hotplug_t hotplug); extern void smscore_unregister_hotplug(hotplug_t hotplug); -extern int smscore_register_device(smsdevice_params_t *params, smscore_device_t **coredev); +extern int smscore_register_device(smsdevice_params_t *params, + smscore_device_t **coredev); extern void smscore_unregister_device(smscore_device_t *coredev); extern int smscore_start_device(smscore_device_t *coredev); extern int smscore_load_firmware(smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler); -extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, int size, int new_mode); +extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, + u8 *buffer, int size, + int new_mode); extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); extern int smscore_get_device_mode(smscore_device_t *coredev); @@ -525,8 +533,10 @@ extern int smscore_register_client(smscore_device_t *coredev, smscore_client_t **client); extern void smscore_unregister_client(smscore_client_t *client); -extern int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size); -extern void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb); +extern int smsclient_sendrequest(smscore_client_t *client, + void *buffer, size_t size); +extern void smscore_onresponse(smscore_device_t *coredev, + smscore_buffer_t *cb); extern int smscore_get_common_buffer_size(smscore_device_t *coredev); extern int smscore_map_common_buffer(smscore_device_t *coredev, @@ -543,4 +553,4 @@ void smsdvb_unregister(void); int smsusb_register(void); void smsusb_unregister(void); -#endif // __smscoreapi_h__ +#endif /* __smscoreapi_h__ */ diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index e050e0da7900..13980fb649c4 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -34,47 +34,49 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) smsdvb_client_t *client = (smsdvb_client_t *) context; SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); - switch(phdr->msgType) - { - case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), - cb->size - sizeof(SmsMsgHdr_ST)); - break; + switch(phdr->msgType) { + case MSG_SMS_DVBT_BDA_DATA: + dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), + cb->size - sizeof(SmsMsgHdr_ST)); + break; + + case MSG_SMS_RF_TUNE_RES: + complete(&client->tune_done); + break; - case MSG_SMS_RF_TUNE_RES: - complete(&client->tune_done); - break; + case MSG_SMS_GET_STATISTICS_RES: + { + SmsMsgStatisticsInfo_ST *p = + (SmsMsgStatisticsInfo_ST *)(phdr + 1); - case MSG_SMS_GET_STATISTICS_RES: + if (p->Stat.IsDemodLocked) { - SmsMsgStatisticsInfo_ST *p = - (SmsMsgStatisticsInfo_ST *)(phdr + 1); - - if (p->Stat.IsDemodLocked) - { - client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - client->fe_snr = p->Stat.SNR; - client->fe_ber = p->Stat.BER; - - if (p->Stat.InBandPwr < -95) - client->fe_signal_strength = 0; - else if (p->Stat.InBandPwr > -29) - client->fe_signal_strength = 100; - else - client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2; - } - else - { - client->fe_status = 0; - client->fe_snr = - client->fe_ber = - client->fe_signal_strength = 0; - } + client->fe_status = FE_HAS_SIGNAL | + FE_HAS_CARRIER | + FE_HAS_VITERBI | + FE_HAS_SYNC | + FE_HAS_LOCK; + + client->fe_snr = p->Stat.SNR; + client->fe_ber = p->Stat.BER; - complete(&client->stat_done); - break; + if (p->Stat.InBandPwr < -95) + client->fe_signal_strength = 0; + else if (p->Stat.InBandPwr > -29) + client->fe_signal_strength = 100; + else + client->fe_signal_strength = + (p->Stat.InBandPwr + 95) * 3 / 2; + } else { + client->fe_status = 0; + client->fe_snr = + client->fe_ber = + client->fe_signal_strength = 0; } - } + + complete(&client->stat_done); + break; + } } smscore_putbuffer(client->coredev, cb); @@ -106,7 +108,8 @@ void smsdvb_onremove(void *context) static int smsdvb_start_feed(struct dvb_demux_feed *feed) { - smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + smsdvb_client_t *client = + container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; printk("%s add pid %d(%x)\n", __func__, feed->pid, feed->pid); @@ -118,12 +121,14 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; - return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); + return smsclient_sendrequest(client->smsclient, + &PidMsg, sizeof(PidMsg)); } static int smsdvb_stop_feed(struct dvb_demux_feed *feed) { - smsdvb_client_t *client = container_of(feed->demux, smsdvb_client_t, demux); + smsdvb_client_t *client = + container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; printk("%s remove pid %d(%x)\n", __func__, feed->pid, feed->pid); @@ -135,7 +140,8 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); PidMsg.msgData[0] = feed->pid; - return smsclient_sendrequest(client->smsclient, &PidMsg, sizeof(PidMsg)); + return smsclient_sendrequest(client->smsclient, + &PidMsg, sizeof(PidMsg)); } static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, @@ -146,13 +152,18 @@ static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, if (rc < 0) return rc; - return wait_for_completion_timeout(completion, msecs_to_jiffies(2000)) ? 0 : -ETIME; + return wait_for_completion_timeout(completion, + msecs_to_jiffies(2000)) ? + 0 : -ETIME; } static int smsdvb_send_statistics_request(smsdvb_client_t *client) { - SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done); + SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, + DVBT_BDA_CONTROL_MSG_ID, + HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->stat_done); } static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) @@ -199,7 +210,8 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) return rc; } -static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) +static int smsdvb_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *tune) { printk("%s\n", __func__); @@ -209,14 +221,15 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend return 0; } -static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int smsdvb_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) { smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); struct { SmsMsgHdr_ST Msg; - u32 Data[3]; + u32 Data[3]; } Msg; Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; @@ -227,29 +240,32 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_para Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; - printk("%s freq %d band %d\n", __func__, fep->frequency, fep->u.ofdm.bandwidth); + printk("%s freq %d band %d\n", __func__, + fep->frequency, fep->u.ofdm.bandwidth); switch(fep->u.ofdm.bandwidth) { case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; -// case BANDWIDTH_5_MHZ: Msg.Data[1] = BW_5_MHZ; break; case BANDWIDTH_AUTO: return -EOPNOTSUPP; default: return -EINVAL; } - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->tune_done); + return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), + &client->tune_done); } -static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +static int smsdvb_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *fep) { smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); printk("%s\n", __func__); // todo: - memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); + memcpy(fep, &client->fe_params, + sizeof(struct dvb_frontend_parameters)); return 0; } @@ -260,19 +276,19 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital SMS10xx", - .type = FE_OFDM, + .name = "Siano Mobile Digital SMS10xx", + .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, .frequency_stepsize = 250000, .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, + FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | + FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_RECOVER | + FE_CAN_HIERARCHY_AUTO, }, .release = smsdvb_release, @@ -287,8 +303,8 @@ static struct dvb_frontend_ops smsdvb_fe_ops = { .read_snr = smsdvb_read_snr, }; -int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, - int arrival) +int smsdvb_hotplug(smscore_device_t *coredev, + struct device *device, int arrival) { smsclient_params_t params; smsdvb_client_t *client; @@ -298,23 +314,21 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, if (!arrival) return 0; - if (smscore_get_device_mode(coredev) != 4) - { + if (smscore_get_device_mode(coredev) != 4) { printk(KERN_ERR "%sSMS Device mode is not set for DVB operation.\n", __func__); return 0; } client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); - if (!client) - { + if (!client) { printk(KERN_INFO "%s kmalloc() failed\n", __func__); return -ENOMEM; } // register dvb adapter - rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); - if (rc < 0) - { + rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", + THIS_MODULE, device, adapter_nr); + if (rc < 0) { printk("%s dvb_register_adapter() failed %d\n", __func__, rc); goto adapter_error; } @@ -327,8 +341,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, client->demux.stop_feed = smsdvb_stop_feed; rc = dvb_dmx_init(&client->demux); - if (rc < 0) - { + if (rc < 0) { printk("%s dvb_dmx_init failed %d\n\n", __func__, rc); goto dvbdmx_error; } @@ -339,18 +352,17 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, client->dmxdev.capabilities = 0; rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); - if (rc < 0) - { + if (rc < 0) { printk("%s dvb_dmxdev_init failed %d\n", __func__, rc); goto dmxdev_error; } // init and register frontend - memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); + memcpy(&client->frontend.ops, &smsdvb_fe_ops, + sizeof(struct dvb_frontend_ops)); rc = dvb_register_frontend(&client->adapter, &client->frontend); - if (rc < 0) - { + if (rc < 0) { printk("%s frontend registration failed %d\n", __func__, rc); goto frontend_error; } @@ -362,9 +374,9 @@ int smsdvb_hotplug(smscore_device_t *coredev, struct device *device, params.context = client; rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_register_client() failed %d\n", __func__, rc); + if (rc < 0) { + printk(KERN_INFO "%s smscore_register_client() failed %d\n", + __func__, rc); goto client_error; } @@ -421,9 +433,8 @@ void smsdvb_unregister(void) kmutex_lock(&g_smsdvb_clientslock); while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client((smsdvb_client_t *) g_smsdvb_clients.next); + smsdvb_unregister_client( + (smsdvb_client_t *) g_smsdvb_clients.next); kmutex_unlock(&g_smsdvb_clientslock); - } - diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index ca9bb36544c0..d9ce3ba0910f 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -57,8 +57,8 @@ typedef struct _smsusb_device smsusb_urb_t surbs[MAX_URBS]; - int response_alignment; - int buffer_size; + int response_alignment; + int buffer_size; } *psmsusb_device_t; int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb); @@ -68,44 +68,50 @@ void smsusb_onresponse(struct urb *urb) smsusb_urb_t *surb = (smsusb_urb_t *) urb->context; smsusb_device_t *dev = surb->dev; - if (urb->status < 0) - { - printk(KERN_INFO "%s error, urb status %d, %d bytes\n", __func__, urb->status, urb->actual_length); + if (urb->status < 0) { + printk(KERN_INFO "%s error, urb status %d, %d bytes\n", + __func__, urb->status, urb->actual_length); return; } - if (urb->actual_length > 0) - { + if (urb->actual_length > 0) { SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p; - if (urb->actual_length >= phdr->msgLength) - { + if (urb->actual_length >= phdr->msgLength) { surb->cb->size = phdr->msgLength; - if (dev->response_alignment && (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) - { - surb->cb->offset = dev->response_alignment + ((phdr->msgFlags >> 8) & 3); - - // sanity check - if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) - { - printk("%s: invalid response msglen %d offset %d size %d\n", __func__, phdr->msgLength, surb->cb->offset, urb->actual_length); + if (dev->response_alignment && + (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) { + + surb->cb->offset = + dev->response_alignment + + ((phdr->msgFlags >> 8) & 3); + + /* sanity check */ + if (((int) phdr->msgLength + + surb->cb->offset) > urb->actual_length) { + printk(KERN_INFO "%s: invalid " + "response msglen %d offset %d " + "size %d\n", __func__, + phdr->msgLength, + surb->cb->offset, + urb->actual_length); goto exit_and_resubmit; } - // move buffer pointer and copy header to its new location + /* move buffer pointer and + * copy header to its new location */ memcpy((char *) phdr + surb->cb->offset, phdr, sizeof(SmsMsgHdr_ST)); - } - else + } else surb->cb->offset = 0; smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; - } - else - { - printk("%s invalid response msglen %d actual %d\n", __func__, phdr->msgLength, urb->actual_length); + } else { + printk(KERN_INFO "%s invalid response " + "msglen %d actual %d\n", __func__, + phdr->msgLength, urb->actual_length); } } @@ -115,12 +121,11 @@ exit_and_resubmit: int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb) { - if (!surb->cb) - { + if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); - if (!surb->cb) - { - printk(KERN_INFO "%s smscore_getbuffer(...) returned NULL\n", __func__); + if (!surb->cb) { + printk(KERN_INFO "%s smscore_getbuffer(...) " + "returned NULL\n", __func__); return -ENOMEM; } } @@ -144,12 +149,10 @@ void smsusb_stop_streaming(smsusb_device_t *dev) { int i; - for (i = 0; i < MAX_URBS; i ++) - { + for (i = 0; i < MAX_URBS; i ++) { usb_kill_urb(&dev->surbs[i].urb); - if (dev->surbs[i].cb) - { + if (dev->surbs[i].cb) { smscore_putbuffer(dev->coredev, dev->surbs[i].cb); dev->surbs[i].cb = NULL; } @@ -160,12 +163,11 @@ int smsusb_start_streaming(smsusb_device_t *dev) { int i, rc; - for (i = 0; i < MAX_URBS; i ++) - { + for (i = 0; i < MAX_URBS; i ++) { rc = smsusb_submit_urb(dev, &dev->surbs[i]); - if (rc < 0) - { - printk(KERN_INFO "%s smsusb_submit_urb(...) failed\n", __func__); + if (rc < 0) { + printk(KERN_INFO "%s smsusb_submit_urb(...) " + "failed\n", __func__); smsusb_stop_streaming(dev); break; } @@ -179,11 +181,11 @@ int smsusb_sendrequest(void *context, void *buffer, size_t size) smsusb_device_t *dev = (smsusb_device_t *) context; int dummy; - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), buffer, size, &dummy, 1000); + return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), + buffer, size, &dummy, 1000); } -char *smsusb1_fw_lkup[] = -{ +char *smsusb1_fw_lkup[] = { "dvbt_stellar_usb.inp", "dvbh_stellar_usb.inp", "tdmb_stellar_usb.inp", @@ -197,32 +199,31 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) u8 *fw_buffer; int rc, dummy; - if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) - { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __func__, id); + if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { + printk(KERN_INFO "%s invalid firmware id specified %d\n", + __func__, id); return -EINVAL; } rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); - if (rc < 0) - { - printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", __func__, smsusb1_fw_lkup[id], id); + if (rc < 0) { + printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", + __func__, smsusb1_fw_lkup[id], id); return rc; } fw_buffer = kmalloc(fw->size, GFP_KERNEL); - if (fw_buffer) - { + if (fw_buffer) { memcpy(fw_buffer, fw->data, fw->size); - rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); + rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), + fw_buffer, fw->size, &dummy, 1000); - printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", __func__, fw->size, dummy, rc); + printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", + __func__, fw->size, dummy, rc); kfree(fw_buffer); - } - else - { + } else { printk(KERN_INFO "failed to allocate firmware buffer\n"); rc = -ENOMEM; } @@ -238,33 +239,29 @@ void smsusb1_detectmode(void *context, int *mode) *mode = DEVICE_MODE_NONE; - if (!product_string) - { + if (!product_string) { product_string = "none"; printk("%s product string not found\n", __func__); - } - else - { - if (strstr(product_string, "DVBH")) - *mode = 1; - else if (strstr(product_string, "BDA")) - *mode = 4; - else if (strstr(product_string, "DVBT")) - *mode = 0; - else if (strstr(product_string, "TDMB")) - *mode = 2; - } + } else if (strstr(product_string, "DVBH")) + *mode = 1; + else if (strstr(product_string, "BDA")) + *mode = 4; + else if (strstr(product_string, "DVBT")) + *mode = 0; + else if (strstr(product_string, "TDMB")) + *mode = 2; printk("%s: %d \"%s\"\n", __func__, *mode, product_string); } int smsusb1_setmode(void *context, int mode) { - SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, + sizeof(SmsMsgHdr_ST), 0 }; - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) - { - printk(KERN_INFO "%s invalid firmware id specified %d\n", __func__, mode); + if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { + printk(KERN_INFO "%s invalid firmware id specified %d\n", + __func__, mode); return -EINVAL; } @@ -275,8 +272,7 @@ void smsusb_term_device(struct usb_interface *intf) { smsusb_device_t *dev = (smsusb_device_t *) usb_get_intfdata(intf); - if (dev) - { + if (dev) { smsusb_stop_streaming(dev); // unregister from smscore @@ -299,9 +295,9 @@ int smsusb_init_device(struct usb_interface *intf) // create device object dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); - if (!dev) - { - printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", __func__); + if (!dev) { + printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", + __func__); return -ENOMEM; } @@ -336,7 +332,9 @@ int smsusb_init_device(struct usb_interface *intf) } dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - sizeof(SmsMsgHdr_ST); + dev->response_alignment = + dev->udev->ep_in[1]->desc.wMaxPacketSize - + sizeof(SmsMsgHdr_ST); params.flags |= SMS_DEVICE_FAMILY2; break; @@ -347,37 +345,37 @@ int smsusb_init_device(struct usb_interface *intf) params.num_buffers = MAX_BUFFERS; params.sendrequest_handler = smsusb_sendrequest; params.context = dev; - snprintf(params.devpath, sizeof(params.devpath), "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); + snprintf(params.devpath, sizeof(params.devpath), + "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); - // register in smscore + /* register in smscore */ rc = smscore_register_device(¶ms, &dev->coredev); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_register_device(...) failed, rc %d\n", __func__, rc); + if (rc < 0) { + printk(KERN_INFO "%s smscore_register_device(...) failed, " + "rc %d\n", __func__, rc); smsusb_term_device(intf); return rc; } // initialize urbs - for (i = 0; i < MAX_URBS; i ++) - { + for (i = 0; i < MAX_URBS; i++) { dev->surbs[i].dev = dev; usb_init_urb(&dev->surbs[i].urb); } printk(KERN_INFO "%s smsusb_start_streaming(...).\n", __func__); rc = smsusb_start_streaming(dev); - if (rc < 0) - { - printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", __func__); + if (rc < 0) { + printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", + __func__); smsusb_term_device(intf); return rc; } rc = smscore_start_device(dev->coredev); - if (rc < 0) - { - printk(KERN_INFO "%s smscore_start_device(...) failed\n", __func__); + if (rc < 0) { + printk(KERN_INFO "%s smscore_start_device(...) failed\n", + __func__); smsusb_term_device(intf); return rc; } @@ -396,29 +394,32 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); - if (intf->num_altsetting > 0) - { + if (intf->num_altsetting > 0) { rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); - if (rc < 0) - { - printk(KERN_INFO "%s usb_set_interface failed, rc %d\n", __func__, rc); + if (rc < 0) { + printk(KERN_INFO "%s usb_set_interface failed, " + "rc %d\n", __func__, rc); return rc; } } - printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); + printk(KERN_INFO "smsusb_probe %d\n", + intf->cur_altsetting->desc.bInterfaceNumber); for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) - printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); + printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, + intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, + intf->cur_altsetting->endpoint[i].desc.bmAttributes, + intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - if (udev->actconfig->desc.bNumInterfaces == 2 && intf->cur_altsetting->desc.bInterfaceNumber == 0) - { + if ((udev->actconfig->desc.bNumInterfaces == 2) && + (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { printk(KERN_INFO "rom interface 0 is not used\n"); return -ENODEV; } - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) - { - snprintf(devpath, sizeof(devpath), "usb\\%d-%s", udev->bus->busnum, udev->devpath); + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { + snprintf(devpath, sizeof(devpath), "usb\\%d-%s", + udev->bus->busnum, udev->devpath); printk(KERN_INFO "stellar device was found.\n"); return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); } @@ -444,7 +445,7 @@ MODULE_DEVICE_TABLE (usb, smsusb_id_table); static struct usb_driver smsusb_driver = { .name = "smsusb", .probe = smsusb_probe, - .disconnect = smsusb_disconnect, + .disconnect = smsusb_disconnect, .id_table = smsusb_id_table, }; -- cgit v1.2.3 From f0333e3de0e06fb9a6662a6df7d3d1cc8e5dbeca Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 15:32:00 -0300 Subject: V4L/DVB (8281): sms1xxx: remove INT / UINT typedefs Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 10 +- drivers/media/dvb/siano/smscoreapi.h | 303 +++++++++++++++++------------------ 2 files changed, 154 insertions(+), 159 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index ba72daf5ced0..5e8869a747f9 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -472,7 +472,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, { SmsFirmware_ST *firmware = (SmsFirmware_ST *) buffer; SmsMsgHdr_ST *msg; - UINT32 mem_address = firmware->StartAddress; + u32 mem_address = firmware->StartAddress; u8 *payload = firmware->Payload; int rc = 0; @@ -496,7 +496,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); - mem_address = *(UINT32*) &payload[20]; + mem_address = *(u32 *) &payload[20]; } while (size && rc >= 0) @@ -505,8 +505,8 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, - (UINT16)(sizeof(SmsMsgHdr_ST) + - sizeof(UINT32) + payload_size)); + (u16)(sizeof(SmsMsgHdr_ST) + + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); @@ -528,7 +528,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(SmsMsgHdr_ST) + - sizeof(UINT32) * 5); + sizeof(u32) * 5); TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point TriggerMsg->msgData[1] = 5; // Priority diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 79fa71a5f284..a5c4c0409a23 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -213,276 +213,271 @@ typedef enum DEVICE_MODE_MAX, } SMS_DEVICE_MODE; -typedef unsigned char UINT8; -typedef unsigned short UINT16; -typedef unsigned int UINT32; -typedef int INT32; - typedef struct SmsMsgHdr_S { - UINT16 msgType; - UINT8 msgSrcId; - UINT8 msgDstId; - UINT16 msgLength; /* Length of entire message, including header */ - UINT16 msgFlags; + u16 msgType; + u8 msgSrcId; + u8 msgDstId; + u16 msgLength; /* Length of entire message, including header */ + u16 msgFlags; } SmsMsgHdr_ST; typedef struct SmsMsgData_S { SmsMsgHdr_ST xMsgHeader; - UINT32 msgData[1]; + u32 msgData[1]; } SmsMsgData_ST; typedef struct SmsDataDownload_S { SmsMsgHdr_ST xMsgHeader; - UINT32 MemAddr; - UINT8 Payload[SMS_MAX_PAYLOAD_SIZE]; + u32 MemAddr; + u8 Payload[SMS_MAX_PAYLOAD_SIZE]; } SmsDataDownload_ST; typedef struct SmsVersionRes_S { SmsMsgHdr_ST xMsgHeader; - UINT16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ - UINT8 Step; /* 0 - Step A */ - UINT8 MetalFix; /* 0 - Metal 0 */ + u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ + u8 Step; /* 0 - Step A */ + u8 MetalFix; /* 0 - Metal 0 */ - UINT8 FirmwareId; /* 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E */ - UINT8 SupportedProtocols; /* Bitwise OR combination of supported protocols */ + u8 FirmwareId; /* 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E */ + u8 SupportedProtocols; /* Bitwise OR combination of supported protocols */ - UINT8 VersionMajor; - UINT8 VersionMinor; - UINT8 VersionPatch; - UINT8 VersionFieldPatch; + u8 VersionMajor; + u8 VersionMinor; + u8 VersionPatch; + u8 VersionFieldPatch; - UINT8 RomVersionMajor; - UINT8 RomVersionMinor; - UINT8 RomVersionPatch; - UINT8 RomVersionFieldPatch; + u8 RomVersionMajor; + u8 RomVersionMinor; + u8 RomVersionPatch; + u8 RomVersionFieldPatch; - UINT8 TextLabel[34]; + u8 TextLabel[34]; } SmsVersionRes_ST; typedef struct SmsFirmware_S { - UINT32 CheckSum; - UINT32 Length; - UINT32 StartAddress; - UINT8 Payload[1]; + u32 CheckSum; + u32 Length; + u32 StartAddress; + u8 Payload[1]; } SmsFirmware_ST; typedef struct SMSHOSTLIB_STATISTICS_S { - UINT32 Reserved; /* Reserved */ + u32 Reserved; /* Reserved */ /* Common parameters */ - UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ /* Reception quality */ - INT32 SNR; /* dB */ - UINT32 BER; /* Post Viterbi BER [1E-5] */ - UINT32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - UINT32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ - UINT32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - INT32 RSSI; /* dBm */ - INT32 InBandPwr; /* In band power in dBM */ - INT32 CarrierOffset; /* Carrier Offset in bin/1024 */ + s32 SNR; /* dB */ + u32 BER; /* Post Viterbi BER [1E-5] */ + u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ + u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ + u32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ /* Transmission parameters */ - UINT32 Frequency; /* Frequency in Hz */ - UINT32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ - UINT32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos */ - UINT32 ModemState; /* from SMS_DvbModemState_ET , valid only for DVB-T/H */ - UINT32 GuardInterval; /* Guard Interval, 1 divided by value , valid only for DVB-T/H */ - UINT32 CodeRate; /* Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ - UINT32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ - UINT32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H */ - UINT32 Constellation; /* Constellation from SMS_Constellation_ET, valid only for DVB-T/H */ + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ + u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos */ + u32 ModemState; /* from SMS_DvbModemState_ET , valid only for DVB-T/H */ + u32 GuardInterval; /* Guard Interval, 1 divided by value , valid only for DVB-T/H */ + u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ + u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ + u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H */ + u32 Constellation; /* Constellation from SMS_Constellation_ET, valid only for DVB-T/H */ /* Burst parameters, valid only for DVB-H */ - UINT32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ - UINT32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ - UINT32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ - UINT32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ - UINT32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ - UINT32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ - UINT32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ - UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - UINT32 TotalTSPackets; /* Total number of transport-stream packets */ - UINT32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding */ - UINT32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding */ - UINT32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding */ + u32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ + u32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ + u32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ + u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ + u32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ + u32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ + u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding */ + u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding */ + u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding */ /* Common params */ - UINT32 BERErrorCount; /* Number of errornous SYNC bits. */ - UINT32 BERBitCount; /* Total number of SYNC bits. */ + u32 BERErrorCount; /* Number of errornous SYNC bits. */ + u32 BERBitCount; /* Total number of SYNC bits. */ /* Interface information */ - UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ + u32 SmsToHostTxErrors; /* Total number of transmission errors. */ /* DAB/T-DMB */ - UINT32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ + u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ /* DVB-H TPS parameters */ - UINT32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ } SMSHOSTLIB_STATISTICS_ST; typedef struct { - UINT32 RequestResult; + u32 RequestResult; SMSHOSTLIB_STATISTICS_ST Stat; /* Split the calc of the SNR in DAB */ - UINT32 Signal; /* dB */ - UINT32 Noise; /* dB */ + u32 Signal; /* dB */ + u32 Noise; /* dB */ } SmsMsgStatisticsInfo_ST; typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S { /* Per-layer information */ - UINT32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist */ - UINT32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist */ - UINT32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - UINT32 BERErrorCount; /* Post Viterbi Error Bits Count */ - UINT32 BERBitCount; /* Post Viterbi Total Bits Count */ - UINT32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - UINT32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ - UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - UINT32 TotalTSPackets; /* Total number of transport-stream packets */ - UINT32 TILdepthI; /* Time interleaver depth I parameter, 255 means layer does not exist */ - UINT32 NumberOfSegments; /* Number of segments in layer A, 255 means layer does not exist */ - UINT32 TMCCErrors; /* TMCC errors */ + u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist */ + u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist */ + u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ + u32 BERErrorCount; /* Post Viterbi Error Bits Count */ + u32 BERBitCount; /* Post Viterbi Total Bits Count */ + u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ + u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ + u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + u32 TILdepthI; /* Time interleaver depth I parameter, 255 means layer does not exist */ + u32 NumberOfSegments; /* Number of segments in layer A, 255 means layer does not exist */ + u32 TMCCErrors; /* TMCC errors */ } SMSHOSTLIB_ISDBT_LAYER_STAT_ST; typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S { - UINT32 StatisticsType; /* Enumerator identifying the type of the + u32 StatisticsType; /* Enumerator identifying the type of the * structure. Values are the same as * SMSHOSTLIB_DEVICE_MODES_E * * This field MUST always be first in any * statistics structure */ - UINT32 FullSize; /* Total size of the structure returned by the modem. If the size requested by + u32 FullSize; /* Total size of the structure returned by the modem. If the size requested by * the host is smaller than FullSize, the struct will be truncated */ /* Common parameters */ - UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ /* Reception quality */ - INT32 SNR; /* dB */ - INT32 RSSI; /* dBm */ - INT32 InBandPwr; /* In band power in dBM */ - INT32 CarrierOffset; /* Carrier Offset in Hz */ + s32 SNR; /* dB */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in Hz */ /* Transmission parameters */ - UINT32 Frequency; /* Frequency in Hz */ - UINT32 Bandwidth; /* Bandwidth in MHz */ - UINT32 TransmissionMode; /* ISDB-T transmission mode */ - UINT32 ModemState; /* 0 - Acquisition, 1 - Locked */ - UINT32 GuardInterval; /* Guard Interval, 1 divided by value */ - UINT32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ - UINT32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ - UINT32 NumOfLayers; /* Number of ISDB-T layers in the network */ + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz */ + u32 TransmissionMode; /* ISDB-T transmission mode */ + u32 ModemState; /* 0 - Acquisition, 1 - Locked */ + u32 GuardInterval; /* Guard Interval, 1 divided by value */ + u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ + u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ + u32 NumOfLayers; /* Number of ISDB-T layers in the network */ /* Per-layer information */ /* Layers A, B and C */ SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ /* Interface information */ - UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ + u32 SmsToHostTxErrors; /* Total number of transmission errors. */ } SMSHOSTLIB_STATISTICS_ISDBT_ST; typedef struct SMSHOSTLIB_STATISTICS_DVB_S { - UINT32 StatisticsType; /* Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E + u32 StatisticsType; /* Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E * This fiels MUST always first in any statistics structure */ - UINT32 FullSize; /* Total size of the structure returned by the modem. If the size requested by + u32 FullSize; /* Total size of the structure returned by the modem. If the size requested by * the host is smaller than FullSize, the struct will be truncated */ /* Common parameters */ - UINT32 IsRfLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - UINT32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ + u32 IsRfLocked; /* 0 - not locked, 1 - locked */ + u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ + u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ /* Reception quality */ - INT32 SNR; /* dB */ - UINT32 BER; /* Post Viterbi BER [1E-5] */ - UINT32 BERErrorCount; /* Number of errornous SYNC bits. */ - UINT32 BERBitCount; /* Total number of SYNC bits. */ - UINT32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */ - UINT32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - INT32 RSSI; /* dBm */ - INT32 InBandPwr; /* In band power in dBM */ - INT32 CarrierOffset; /* Carrier Offset in bin/1024 */ + s32 SNR; /* dB */ + u32 BER; /* Post Viterbi BER [1E-5] */ + u32 BERErrorCount; /* Number of errornous SYNC bits. */ + u32 BERBitCount; /* Total number of SYNC bits. */ + u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */ + u32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + s32 RSSI; /* dBm */ + s32 InBandPwr; /* In band power in dBM */ + s32 CarrierOffset; /* Carrier Offset in bin/1024 */ /* Transmission parameters */ - UINT32 Frequency; /* Frequency in Hz */ - UINT32 Bandwidth; /* Bandwidth in MHz */ - UINT32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ - UINT32 TransmissionMode; /* FFT mode carriers in Kilos */ - UINT32 GuardInterval; /* Guard Interval, 1 divided by value */ - UINT32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ - UINT32 LPCodeRate; /* Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET */ - UINT32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ - UINT32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */ + u32 Frequency; /* Frequency in Hz */ + u32 Bandwidth; /* Bandwidth in MHz */ + u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ + u32 TransmissionMode; /* FFT mode carriers in Kilos */ + u32 GuardInterval; /* Guard Interval, 1 divided by value */ + u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + u32 LPCodeRate; /* Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ + u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */ /* Burst parameters, valid only for DVB-H */ - UINT32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ - UINT32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ - UINT32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ - UINT32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ - UINT32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ - UINT32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ - UINT32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ - UINT32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - UINT32 TotalTSPackets; /* Total number of transport-stream packets */ - UINT32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H */ - UINT32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H */ - UINT32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H */ - UINT32 NumMPEReceived; /* DVB-H, Num MPE section received */ + u32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ + u32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ + u32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ + u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ + u32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ + u32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ + u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ + u32 TotalTSPackets; /* Total number of transport-stream packets */ + u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H */ + u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H */ + u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H */ + u32 NumMPEReceived; /* DVB-H, Num MPE section received */ /* DVB-H TPS parameters */ - UINT32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ - UINT32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - UINT32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ /* Interface information */ - UINT32 SmsToHostTxErrors; /* Total number of transmission errors. */ + u32 SmsToHostTxErrors; /* Total number of transmission errors. */ } SMSHOSTLIB_STATISTICS_DVB_ST; typedef struct SMSHOSTLIB_GPIO_CONFIG_S { - UINT8 Direction; /* GPIO direction: Input - 0, Output - 1 */ - UINT8 PullUpDown; /* PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 */ - UINT8 InputCharacteristics; /* Input Characteristics: Normal - 0, Schmitt trigger - 1 */ - UINT8 OutputSlewRate; /* Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 */ - UINT8 OutputDriving; /* Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ + u8 Direction; /* GPIO direction: Input - 0, Output - 1 */ + u8 PullUpDown; /* PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 */ + u8 InputCharacteristics; /* Input Characteristics: Normal - 0, Schmitt trigger - 1 */ + u8 OutputSlewRate; /* Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 */ + u8 OutputDriving; /* Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ } SMSHOSTLIB_GPIO_CONFIG_ST; typedef struct SMSHOSTLIB_I2C_REQ_S { - UINT32 DeviceAddress; /* I2c device address */ - UINT32 WriteCount; /* number of bytes to write */ - UINT32 ReadCount; /* number of bytes to read */ - UINT8 Data[1]; + u32 DeviceAddress; /* I2c device address */ + u32 WriteCount; /* number of bytes to write */ + u32 ReadCount; /* number of bytes to read */ + u8 Data[1]; } SMSHOSTLIB_I2C_REQ_ST; typedef struct SMSHOSTLIB_I2C_RES_S { - UINT32 Status; /* non-zero value in case of failure */ - UINT32 ReadCount; /* number of bytes read */ - UINT8 Data[1]; + u32 Status; /* non-zero value in case of failure */ + u32 ReadCount; /* number of bytes read */ + u8 Data[1]; } SMSHOSTLIB_I2C_RES_ST; typedef struct _smsdvb_client -- cgit v1.2.3 From fa830e8a014a206103d06a7600ed8c661b427db3 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 15:52:43 -0300 Subject: V4L/DVB (8282): sms1xxx: more codingstyle cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 36 +++++++++++++++++------------------- drivers/media/dvb/siano/smscoreapi.h | 4 ++-- drivers/media/dvb/siano/smsdvb.c | 36 +++++++++++++++++------------------- drivers/media/dvb/siano/smsusb.c | 18 +++++++++--------- 4 files changed, 45 insertions(+), 49 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 5e8869a747f9..e8267178c52c 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -386,7 +386,7 @@ int smscore_register_device(smsdevice_params_t *params, /* prepare dma buffers */ for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; - dev->num_buffers ++, buffer += params->buffer_size) { + dev->num_buffers++, buffer += params->buffer_size) { smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); if (!cb) { smscore_unregister_device(dev); @@ -499,8 +499,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, mem_address = *(u32 *) &payload[20]; } - while (size && rc >= 0) - { + while (size && rc >= 0) { SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); @@ -530,11 +529,11 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, sizeof(SmsMsgHdr_ST) + sizeof(u32) * 5); - TriggerMsg->msgData[0] = firmware->StartAddress; // Entry point - TriggerMsg->msgData[1] = 5; // Priority - TriggerMsg->msgData[2] = 0x200; // Stack size - TriggerMsg->msgData[3] = 0; // Parameter - TriggerMsg->msgData[4] = 4; // Task ID + TriggerMsg->msgData[0] = firmware->StartAddress; /* Entry point */ + TriggerMsg->msgData[1] = 5; /* Priority */ + TriggerMsg->msgData[2] = 0x200; /* Stack size */ + TriggerMsg->msgData[3] = 0; /* Parameter */ + TriggerMsg->msgData[4] = 4; /* Task ID */ if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); @@ -642,7 +641,7 @@ void smscore_unregister_device(smscore_device_t *coredev) while (1) { while ((cb = smscore_getbuffer(coredev))) { kfree(cb); - num_buffers ++; + num_buffers++; } if (num_buffers == coredev->num_buffers) break; @@ -842,14 +841,14 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, for (next = first->next; (next != first) && !client; next = next->next) { - firstid = &((smscore_client_t*)next)->idlist; + firstid = &((smscore_client_t *)next)->idlist; for (nextid = firstid->next; nextid != firstid; nextid = nextid->next) { - if ((((smscore_idlist_t*)nextid)->id == id) && - (((smscore_idlist_t*)nextid)->data_type == data_type || - (((smscore_idlist_t*)nextid)->data_type == 0))) { - client = (smscore_client_t*) next; + if ((((smscore_idlist_t *)nextid)->id == id) && + (((smscore_idlist_t *)nextid)->data_type == data_type || + (((smscore_idlist_t *)nextid)->data_type == 0))) { + client = (smscore_client_t *) next; break; } } @@ -880,8 +879,7 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) if (!last_sample_time) last_sample_time = time_now; - if (time_now - last_sample_time > 10000) - { + if (time_now - last_sample_time > 10000) { printk("\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); @@ -989,9 +987,9 @@ int smscore_validate_client(smscore_device_t *coredev, return -EFAULT; } registered_client = smscore_find_client(coredev, data_type, id); - if (registered_client == client) { + if (registered_client == client) return 0; - } + if (registered_client) { PERROR("The msg ID already registered to another client.\n"); return -EEXIST; @@ -1069,7 +1067,7 @@ void smscore_unregister_client(smscore_client_t *client) while (!list_empty(&client->idlist)) { smscore_idlist_t *identry = - (smscore_idlist_t*) client->idlist.next; + (smscore_idlist_t *) client->idlist.next; list_del(&identry->entry); kfree(identry); } diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index a5c4c0409a23..4860e318a5b8 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -45,7 +45,7 @@ typedef struct mutex kmutex_t; #ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) #endif #define SMS_ALLOC_ALIGNMENT 128 @@ -57,7 +57,7 @@ typedef struct mutex kmutex_t; #define SMS_DEVICE_NOT_READY 0x8000000 typedef enum { - SMS_STELLAR= 0, + SMS_STELLAR = 0, SMS_NOVA_A0, SMS_NOVA_B0, SMS_VEGA, diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 13980fb649c4..e3f09646bb81 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -34,7 +34,7 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) smsdvb_client_t *client = (smsdvb_client_t *) context; SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); - switch(phdr->msgType) { + switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), cb->size - sizeof(SmsMsgHdr_ST)); @@ -49,8 +49,7 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) SmsMsgStatisticsInfo_ST *p = (SmsMsgStatisticsInfo_ST *)(phdr + 1); - if (p->Stat.IsDemodLocked) - { + if (p->Stat.IsDemodLocked) { client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | @@ -85,7 +84,7 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) void smsdvb_unregister_client(smsdvb_client_t *client) { - // must be called under clientslock + /* must be called under clientslock */ list_del(&client->entry); @@ -243,13 +242,12 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, printk("%s freq %d band %d\n", __func__, fep->frequency, fep->u.ofdm.bandwidth); - switch(fep->u.ofdm.bandwidth) - { - case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; - case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; - case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: return -EINVAL; + switch (fep->u.ofdm.bandwidth) { + case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; + case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; + case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; + case BANDWIDTH_AUTO: return -EOPNOTSUPP; + default: return -EINVAL; } return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), @@ -263,7 +261,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, printk("%s\n", __func__); - // todo: + /* todo: */ memcpy(fep, &client->fe_params, sizeof(struct dvb_frontend_parameters)); return 0; @@ -271,7 +269,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, static void smsdvb_release(struct dvb_frontend *fe) { - // do nothing + /* do nothing */ } static struct dvb_frontend_ops smsdvb_fe_ops = { @@ -310,7 +308,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, smsdvb_client_t *client; int rc; - // device removal handled by onremove callback + /* device removal handled by onremove callback */ if (!arrival) return 0; @@ -325,7 +323,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, return -ENOMEM; } - // register dvb adapter + /* register dvb adapter */ rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); if (rc < 0) { @@ -333,9 +331,9 @@ int smsdvb_hotplug(smscore_device_t *coredev, goto adapter_error; } - // init dvb demux + /* init dvb demux */ client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; // todo: nova ??? + client->demux.filternum = 32; /* todo: nova ??? */ client->demux.feednum = 32; client->demux.start_feed = smsdvb_start_feed; client->demux.stop_feed = smsdvb_stop_feed; @@ -346,7 +344,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, goto dvbdmx_error; } - // init dmxdev + /* init dmxdev */ client->dmxdev.filternum = 32; client->dmxdev.demux = &client->demux.dmx; client->dmxdev.capabilities = 0; @@ -357,7 +355,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, goto dmxdev_error; } - // init and register frontend + /* init and register frontend */ memcpy(&client->frontend.ops, &smsdvb_fe_ops, sizeof(struct dvb_frontend_ops)); diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index d9ce3ba0910f..2361f1a5e3c4 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -149,7 +149,7 @@ void smsusb_stop_streaming(smsusb_device_t *dev) { int i; - for (i = 0; i < MAX_URBS; i ++) { + for (i = 0; i < MAX_URBS; i++) { usb_kill_urb(&dev->surbs[i].urb); if (dev->surbs[i].cb) { @@ -163,7 +163,7 @@ int smsusb_start_streaming(smsusb_device_t *dev) { int i, rc; - for (i = 0; i < MAX_URBS; i ++) { + for (i = 0; i < MAX_URBS; i++) { rc = smsusb_submit_urb(dev, &dev->surbs[i]); if (rc < 0) { printk(KERN_INFO "%s smsusb_submit_urb(...) " @@ -275,7 +275,7 @@ void smsusb_term_device(struct usb_interface *intf) if (dev) { smsusb_stop_streaming(dev); - // unregister from smscore + /* unregister from smscore */ if (dev->coredev) smscore_unregister_device(dev->coredev); @@ -293,7 +293,7 @@ int smsusb_init_device(struct usb_interface *intf) smsusb_device_t *dev; int i, rc; - // create device object + /* create device object */ dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); if (!dev) { printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", @@ -313,13 +313,13 @@ int smsusb_init_device(struct usb_interface *intf) params.setmode_handler = smsusb1_setmode; params.detectmode_handler = smsusb1_detectmode; params.device_type = SMS_STELLAR; - printk(KERN_INFO "%s stellar device found\n", __func__ ); + printk(KERN_INFO "%s stellar device found\n", __func__); break; default: switch (dev->udev->descriptor.idProduct) { case USB_PID_NOVA_A: params.device_type = SMS_NOVA_A0; - printk(KERN_INFO "%s nova A0 found\n", __func__ ); + printk(KERN_INFO "%s nova A0 found\n", __func__); break; default: case USB_PID_NOVA_B: @@ -357,7 +357,7 @@ int smsusb_init_device(struct usb_interface *intf) return rc; } - // initialize urbs + /* initialize urbs */ for (i = 0; i < MAX_URBS; i++) { dev->surbs[i].dev = dev; usb_init_urb(&dev->surbs[i].urb); @@ -405,7 +405,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) printk(KERN_INFO "smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i ++) + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, @@ -440,7 +440,7 @@ static struct usb_device_id smsusb_id_table [] = { { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_A) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, smsusb_id_table); +MODULE_DEVICE_TABLE(usb, smsusb_id_table); static struct usb_driver smsusb_driver = { .name = "smsusb", -- cgit v1.2.3 From 59bf6b8e85209f4b875e319b42e8f13af7797826 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 16:50:11 -0300 Subject: V4L/DVB (8283): sms1xxx: 80-column cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 123 ++++++++++++++++++--------- drivers/media/dvb/siano/smscoreapi.h | 156 ++++++++++++++++++++++------------- drivers/media/dvb/siano/smsdvb.c | 3 +- drivers/media/dvb/siano/smsusb.c | 6 +- 4 files changed, 190 insertions(+), 98 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index e8267178c52c..084ddc39c989 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -309,7 +309,8 @@ int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, first = &g_smscore_notifyees; for (next = first->next; next != first; next = next->next) { - rc = ((smscore_device_notifyee_t *) next)->hotplug(coredev, device, arrival); + rc = ((smscore_device_notifyee_t *) next)-> + hotplug(coredev, device, arrival); if (rc < 0) break; } @@ -337,7 +338,8 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, * creates coredev object for a device, prepares buffers, * creates buffer mappings, notifies registered hotplugs about new device. * - * @param params device pointer to struct with device specific parameters and handlers + * @param params device pointer to struct with device specific parameters + * and handlers * @param coredev pointer to a value that receives created coredev object * * @return 0 on success, <0 on error. @@ -387,7 +389,9 @@ int smscore_register_device(smsdevice_params_t *params, for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers++, buffer += params->buffer_size) { - smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); + smscore_buffer_t *cb = + smscore_createbuffer(buffer, dev->common_buffer, + dev->common_buffer_phys); if (!cb) { smscore_unregister_device(dev); return -ENOMEM; @@ -428,15 +432,18 @@ int smscore_register_device(smsdevice_params_t *params, /** * sets initial device mode and notifies client hotplugs that device is ready * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return 0 on success, <0 on error. */ int smscore_start_device(smscore_device_t *coredev) { - int rc = smscore_set_device_mode(coredev, smscore_registry_getmode(coredev->devpath)); + int rc = smscore_set_device_mode( + coredev, smscore_registry_getmode(coredev->devpath)); if (rc < 0) { - printk(KERN_INFO "%s set device mode faile , rc %d\n", __func__, rc); + printk(KERN_INFO "%s set device mode faile , rc %d\n", + __func__, rc); return rc; } @@ -512,9 +519,14 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && (coredev->mode == DEVICE_MODE_NONE)) - rc = coredev->sendrequest_handler(coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); + rc = coredev->sendrequest_handler( + coredev->context, DataMsg, + DataMsg->xMsgHeader.msgLength); else - rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); + rc = smscore_sendrequest_and_wait( + coredev, DataMsg, + DataMsg->xMsgHeader.msgLength, + &coredev->data_download_done); payload += payload_size; size -= payload_size; @@ -529,17 +541,23 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, sizeof(SmsMsgHdr_ST) + sizeof(u32) * 5); - TriggerMsg->msgData[0] = firmware->StartAddress; /* Entry point */ + TriggerMsg->msgData[0] = firmware->StartAddress; + /* Entry point */ TriggerMsg->msgData[1] = 5; /* Priority */ TriggerMsg->msgData[2] = 0x200; /* Stack size */ TriggerMsg->msgData[3] = 0; /* Parameter */ TriggerMsg->msgData[4] = 4; /* Task ID */ if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { - rc = coredev->sendrequest_handler(coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); + rc = coredev->sendrequest_handler( + coredev->context, TriggerMsg, + TriggerMsg->xMsgHeader.msgLength); msleep(100); } else - rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); + rc = smscore_sendrequest_and_wait( + coredev, TriggerMsg, + TriggerMsg->xMsgHeader.msgLength, + &coredev->trigger_done); } else { SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, sizeof(SmsMsgHdr_ST)); @@ -563,7 +581,8 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, /** * loads specified firmware into a buffer and calls device loadfirmware_handler * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param filename null-terminated string specifies firmware file name * @param loadfirmware_handler device handler that loads firmware * @@ -595,8 +614,11 @@ int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, memcpy(fw_buffer, fw->data, fw->size); rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : - loadfirmware_handler(coredev->context, fw_buffer, fw->size); + smscore_load_firmware_family2(coredev, + fw_buffer, + fw->size) : + loadfirmware_handler(coredev->context, + fw_buffer, fw->size); kfree(fw_buffer); } else { @@ -618,9 +640,11 @@ int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, } /** - * notifies all clients registered with the device, notifies hotplugs, frees all buffers and coredev object + * notifies all clients registered with the device, notifies hotplugs, + * frees all buffers and coredev object * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return 0 on success, <0 on error. */ @@ -686,13 +710,17 @@ int smscore_detect_mode(smscore_device_t *coredev) rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc == -ETIME) { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", __func__); + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", + __func__); if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) { - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); + rc = smscore_sendrequest_and_wait( + coredev, msg, msg->msgLength, + &coredev->version_ex_done); if (rc < 0) - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed second try, rc %d\n", __func__, rc); + printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed " + "second try, rc %d\n", __func__, rc); } else rc = -ETIME; } @@ -719,7 +747,8 @@ char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { * calls device handler to change mode of operation * NOTE: stellar/usb may disconnect when changing mode * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param mode requested mode of operation * * @return 0 on success, <0 on error. @@ -757,27 +786,35 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) if (!(coredev->modes_supported & (1 << mode))) { type = smscore_registry_gettype(coredev->devpath); - rc = smscore_load_firmware_from_file(coredev, smscore_fw_lkup[mode][type], NULL); + rc = smscore_load_firmware_from_file( + coredev, smscore_fw_lkup[mode][type], NULL); if (rc < 0) { - printk(KERN_INFO "%s load firmware failed %d\n", __func__, rc); + printk(KERN_INFO "%s load firmware " + "failed %d\n", __func__, rc); return rc; } } else - printk(KERN_INFO "%s mode %d supported by running firmware\n", __func__, mode); + printk(KERN_INFO "%s mode %d supported by running " + "firmware\n", __func__, mode); buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { - SmsMsgData_ST *msg = (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); + SmsMsgData_ST *msg = + (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(SmsMsgData_ST)); + SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, + sizeof(SmsMsgData_ST)); msg->msgData[0] = mode; - rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); + rc = smscore_sendrequest_and_wait( + coredev, msg, msg->xMsgHeader.msgLength, + &coredev->init_device_done); kfree(buffer); } else { - printk(KERN_INFO "%s Could not allocate buffer for init device message.\n", __func__); + printk(KERN_INFO "%s Could not allocate buffer for " + "init device message.\n", __func__); rc = -ENOMEM; } } else { @@ -810,7 +847,8 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) /** * calls device handler to get current mode of operation * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return current mode */ @@ -823,12 +861,14 @@ int smscore_get_device_mode(smscore_device_t *coredev) * find client by response id & type within the clients list. * return client handle or NULL. * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param data_type client data type (SMS_DONT_CARE for all types) * @param id client id (SMS_DONT_CARE for all id) * */ -smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, int id) +smscore_client_t *smscore_find_client(smscore_device_t *coredev, + int data_type, int id) { smscore_client_t *client = NULL; struct list_head *next, *first; @@ -861,15 +901,16 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, int data_type, * find client by response id/type, call clients onresponse handler * return buffer to pool on error * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param cb pointer to response buffer descriptor * */ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) { SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); - smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, - phdr->msgDstId); + smscore_client_t *client = + smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; static unsigned long last_sample_time = 0; @@ -943,7 +984,8 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) /** * return pointer to next free buffer descriptor from core pool * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * * @return pointer to descriptor on success, NULL on error. */ @@ -967,7 +1009,8 @@ smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) /** * return buffer descriptor to a pool * - * @param coredev pointer to a coredev object returned by smscore_register_device + * @param coredev pointer to a coredev object returned by + * smscore_register_device * @param cb pointer buffer descriptor * */ @@ -1019,7 +1062,9 @@ int smscore_validate_client(smscore_device_t *coredev, * * @return 0 on success, <0 on error. */ -int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *params, smscore_client_t **client) +int smscore_register_client(smscore_device_t *coredev, + smsclient_params_t *params, + smscore_client_t **client) { smscore_client_t *newclient; /* check that no other channel with same parameters exists */ @@ -1054,7 +1099,8 @@ int smscore_register_client(smscore_device_t *coredev, smsclient_params_t *param /** * frees smsclient object and all subclients associated with it * - * @param client pointer to smsclient object returned by smscore_register_client + * @param client pointer to smsclient object returned by + * smscore_register_client * */ void smscore_unregister_client(smscore_client_t *client) @@ -1084,7 +1130,8 @@ void smscore_unregister_client(smscore_client_t *client) * verifies that source id is not taken by another client, * calls device handler to send requests to the device * - * @param client pointer to smsclient object returned by smscore_register_client + * @param client pointer to smsclient object returned by + * smscore_register_client * @param buffer pointer to a request buffer * @param size size (in bytes) of request buffer * diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 4860e318a5b8..2a823b37ccf7 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -50,7 +50,8 @@ typedef struct mutex kmutex_t; #define SMS_ALLOC_ALIGNMENT 128 #define SMS_DMA_ALIGNMENT 16 -#define SMS_ALIGN_ADDRESS(addr) ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) +#define SMS_ALIGN_ADDRESS(addr) \ + ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) #define SMS_DEVICE_FAMILY2 1 #define SMS_ROM_NO_RESPONSE 2 @@ -68,7 +69,8 @@ typedef struct _smscore_device smscore_device_t; typedef struct _smscore_client smscore_client_t; typedef struct _smscore_buffer smscore_buffer_t; -typedef int (*hotplug_t)(smscore_device_t *coredev, struct device *device, int arrival); +typedef int (*hotplug_t)(smscore_device_t *coredev, + struct device *device, int arrival); typedef int (*setmode_t)(void *context, int mode); typedef void (*detectmode_t)(void *context, int *mode); @@ -196,7 +198,8 @@ typedef struct _smsclient_params (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ } while (0) -#define SMS_INIT_MSG(ptr, type, len) SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) +#define SMS_INIT_MSG(ptr, type, len) \ + SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) typedef enum { @@ -243,8 +246,11 @@ typedef struct SmsVersionRes_S u8 Step; /* 0 - Step A */ u8 MetalFix; /* 0 - Metal 0 */ - u8 FirmwareId; /* 0xFF � ROM, otherwise the value indicated by SMSHOSTLIB_DEVICE_MODES_E */ - u8 SupportedProtocols; /* Bitwise OR combination of supported protocols */ + u8 FirmwareId; /* 0xFF � ROM, otherwise the + * value indicated by + * SMSHOSTLIB_DEVICE_MODES_E */ + u8 SupportedProtocols; /* Bitwise OR combination of + * supported protocols */ u8 VersionMajor; u8 VersionMinor; @@ -280,36 +286,44 @@ typedef struct SMSHOSTLIB_STATISTICS_S s32 SNR; /* dB */ u32 BER; /* Post Viterbi BER [1E-5] */ u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ - u32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, + * valid only for DVB-T/H */ + u32 MFER; /* DVB-H frame error rate in percentage, + * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ s32 RSSI; /* dBm */ s32 InBandPwr; /* In band power in dBM */ s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - /* Transmission parameters */ + /* Transmission parameters, valid only for DVB-T/H */ u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ - u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, for DVB-T/H FFT mode carriers in Kilos */ - u32 ModemState; /* from SMS_DvbModemState_ET , valid only for DVB-T/H */ - u32 GuardInterval; /* Guard Interval, 1 divided by value , valid only for DVB-T/H */ - u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ - u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET, valid only for DVB-T/H */ - u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET, valid only for DVB-T/H */ - u32 Constellation; /* Constellation from SMS_Constellation_ET, valid only for DVB-T/H */ + u32 Bandwidth; /* Bandwidth in MHz */ + u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, + * for DVB-T/H FFT mode carriers in Kilos */ + u32 ModemState; /* from SMS_DvbModemState_ET */ + u32 GuardInterval; /* Guard Interval, 1 divided by value */ + u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ + u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */ + u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */ + u32 Constellation; /* Constellation from SMS_Constellation_ET */ /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ - u32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ - u32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ - u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ - u32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + u32 BurstSize; /* Current burst size in bytes */ + u32 BurstDuration; /* Current burst duration in mSec */ + u32 BurstCycleTime; /* Current burst cycle time in mSec */ + u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, + * as calculated by demodulator */ + u32 NumOfRows; /* Number of rows in MPE table */ + u32 NumOfPaddCols; /* Number of padding columns in MPE table */ + u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ + /* Burst parameters */ u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding */ - u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding */ - u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding */ + u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include + * errors after MPE RS decoding */ + u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors + * after MPE RS decoding */ + u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected + * by MPE RS decoding */ /* Common params */ u32 BERErrorCount; /* Number of errornous SYNC bits. */ @@ -322,7 +336,8 @@ typedef struct SMSHOSTLIB_STATISTICS_S u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; + * if set to 0xFFFFFFFF cell_id not yet recovered */ } SMSHOSTLIB_STATISTICS_ST; @@ -341,8 +356,10 @@ typedef struct typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S { /* Per-layer information */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, 255 means layer does not exist */ - u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, 255 means layer does not exist */ + u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, + * 255 means layer does not exist */ + u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, + * 255 means layer does not exist */ u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ u32 BERErrorCount; /* Post Viterbi Error Bits Count */ u32 BERBitCount; /* Post Viterbi Total Bits Count */ @@ -350,8 +367,10 @@ typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 TILdepthI; /* Time interleaver depth I parameter, 255 means layer does not exist */ - u32 NumberOfSegments; /* Number of segments in layer A, 255 means layer does not exist */ + u32 TILdepthI; /* Time interleaver depth I parameter, + * 255 means layer does not exist */ + u32 NumberOfSegments; /* Number of segments in layer A, + * 255 means layer does not exist */ u32 TMCCErrors; /* TMCC errors */ } SMSHOSTLIB_ISDBT_LAYER_STAT_ST; @@ -364,8 +383,9 @@ typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S * This field MUST always be first in any * statistics structure */ - u32 FullSize; /* Total size of the structure returned by the modem. If the size requested by - * the host is smaller than FullSize, the struct will be truncated */ + u32 FullSize; /* Total size of the structure returned by the modem. + * If the size requested by the host is smaller than + * FullSize, the struct will be truncated */ /* Common parameters */ u32 IsRfLocked; /* 0 - not locked, 1 - locked */ @@ -390,7 +410,8 @@ typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S /* Per-layer information */ /* Layers A, B and C */ - SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ + SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; /* Per-layer statistics, + see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ /* Interface information */ u32 SmsToHostTxErrors; /* Total number of transmission errors. */ @@ -399,11 +420,15 @@ typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S typedef struct SMSHOSTLIB_STATISTICS_DVB_S { - u32 StatisticsType; /* Enumerator identifying the type of the structure. Values are the same as SMSHOSTLIB_DEVICE_MODES_E - * This fiels MUST always first in any statistics structure */ - - u32 FullSize; /* Total size of the structure returned by the modem. If the size requested by - * the host is smaller than FullSize, the struct will be truncated */ + u32 StatisticsType; /* Enumerator identifying the type of the + * structure. Values are the same as + * SMSHOSTLIB_DEVICE_MODES_E + * This field MUST always first in any + * statistics structure */ + + u32 FullSize; /* Total size of the structure returned by the modem. + * If the size requested by the host is smaller than + * FullSize, the struct will be truncated */ /* Common parameters */ u32 IsRfLocked; /* 0 - not locked, 1 - locked */ u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ @@ -415,7 +440,8 @@ typedef struct SMSHOSTLIB_STATISTICS_DVB_S u32 BERErrorCount; /* Number of errornous SYNC bits. */ u32 BERBitCount; /* Total number of SYNC bits. */ u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */ - u32 MFER; /* DVB-H frame error rate in percentage, 0xFFFFFFFF indicate N/A, valid only for DVB-H */ + u32 MFER; /* DVB-H frame error rate in percentage, + * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ s32 RSSI; /* dBm */ s32 InBandPwr; /* In band power in dBM */ s32 CarrierOffset; /* Carrier Offset in bin/1024 */ @@ -427,29 +453,41 @@ typedef struct SMSHOSTLIB_STATISTICS_DVB_S u32 TransmissionMode; /* FFT mode carriers in Kilos */ u32 GuardInterval; /* Guard Interval, 1 divided by value */ u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ - u32 LPCodeRate; /* Low Priority Code Rate from SMSHOSTLIB_CODE_RATE_ET */ + u32 LPCodeRate; /* Low Priority Code Rate from + * SMSHOSTLIB_CODE_RATE_ET */ u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */ /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes, valid only for DVB-H */ - u32 BurstDuration; /* Current burst duration in mSec, valid only for DVB-H */ - u32 BurstCycleTime; /* Current burst cycle time in mSec, valid only for DVB-H */ - u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, as calculated by demodulator, valid only for DVB-H */ - u32 NumOfRows; /* Number of rows in MPE table, valid only for DVB-H */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table, valid only for DVB-H */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, valid only for DVB-H */ + u32 BurstSize; /* Current burst size in bytes */ + u32 BurstDuration; /* Current burst duration in mSec */ + u32 BurstCycleTime; /* Current burst cycle time in mSec */ + u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, + * as calculated by demodulator */ + u32 NumOfRows; /* Number of rows in MPE table */ + u32 NumOfPaddCols; /* Number of padding columns in MPE table */ + u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ + u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include errors after MPE RS decoding, valid only for DVB-H */ - u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors after MPE RS decoding, valid only for DVB-H */ - u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected by MPE RS decoding, valid only for DVB-H */ + + u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include + * errors after MPE RS decoding */ + u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include + * errors after MPE RS decoding */ + u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were + * corrected by MPE RS decoding */ + u32 NumMPEReceived; /* DVB-H, Num MPE section received */ /* DVB-H TPS parameters */ u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ - u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ - u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - Time Slicing indicator, bit 0 - MPE-FEC indicator */ + u32 DvbhSrvIndHP; /* DVB-H service indication info, + * bit 1 - Time Slicing indicator, + * bit 0 - MPE-FEC indicator */ + u32 DvbhSrvIndLP; /* DVB-H service indication info, + * bit 1 - Time Slicing indicator, + * bit 0 - MPE-FEC indicator */ /* Interface information */ u32 SmsToHostTxErrors; /* Total number of transmission errors. */ @@ -459,10 +497,14 @@ typedef struct SMSHOSTLIB_STATISTICS_DVB_S typedef struct SMSHOSTLIB_GPIO_CONFIG_S { u8 Direction; /* GPIO direction: Input - 0, Output - 1 */ - u8 PullUpDown; /* PullUp/PullDown: None - 0, PullDown - 1, PullUp - 2, Keeper - 3 */ - u8 InputCharacteristics; /* Input Characteristics: Normal - 0, Schmitt trigger - 1 */ - u8 OutputSlewRate; /* Output Slew Rate: Fast slew rate - 0, Slow slew rate - 1 */ - u8 OutputDriving; /* Output driving capability: 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ + u8 PullUpDown; /* PullUp/PullDown: None - 0, + * PullDown - 1, PullUp - 2, Keeper - 3 */ + u8 InputCharacteristics; /* Input Characteristics: Normal - 0, + * Schmitt trigger - 1 */ + u8 OutputSlewRate; /* Output Slew Rate: + * Fast slew rate - 0, Slow slew rate - 1 */ + u8 OutputDriving; /* Output driving capability: + * 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ } SMSHOSTLIB_GPIO_CONFIG_ST; typedef struct SMSHOSTLIB_I2C_REQ_S diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index e3f09646bb81..f46e7facdb6b 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -313,7 +313,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, return 0; if (smscore_get_device_mode(coredev) != 4) { - printk(KERN_ERR "%sSMS Device mode is not set for DVB operation.\n", __func__); + printk(KERN_ERR "%sSMS Device mode is not set for " + "DVB operation.\n", __func__); return 0; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 2361f1a5e3c4..102c5857a23d 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -395,7 +395,8 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); if (intf->num_altsetting > 0) { - rc = usb_set_interface(udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); + rc = usb_set_interface( + udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); if (rc < 0) { printk(KERN_INFO "%s usb_set_interface failed, " "rc %d\n", __func__, rc); @@ -421,7 +422,8 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) snprintf(devpath, sizeof(devpath), "usb\\%d-%s", udev->bus->busnum, udev->devpath); printk(KERN_INFO "stellar device was found.\n"); - return smsusb1_load_firmware(udev, smscore_registry_getmode(devpath)); + return smsusb1_load_firmware( + udev, smscore_registry_getmode(devpath)); } rc = smsusb_init_device(intf); -- cgit v1.2.3 From 9f2113975a7898c913c668bb709e95c27e51617b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 17:26:42 -0300 Subject: V4L/DVB (8284): sms1xxx: fix WARNING: printk() should include KERN_ facility level Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 26 +++++++++++++++----------- drivers/media/dvb/siano/smsdvb.c | 24 +++++++++++++++--------- drivers/media/dvb/siano/smsusb.c | 4 ++-- 3 files changed, 32 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 084ddc39c989..3c0e64286d4e 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -568,7 +568,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, msleep(500); } - printk("%s rc=%d, postload=%p \n", __func__, rc, + printk(KERN_DEBUG "%s rc=%d, postload=%p \n", __func__, rc, coredev->postload_handler); kfree(msg); @@ -710,8 +710,8 @@ int smscore_detect_mode(smscore_device_t *coredev) rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc == -ETIME) { - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed first try\n", - __func__); + printk(KERN_ERR "%s: MSG_SMS_GET_VERSION_EX_REQ " + "failed first try\n", __func__); if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) { @@ -719,7 +719,8 @@ int smscore_detect_mode(smscore_device_t *coredev) coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc < 0) - printk("%s: MSG_SMS_GET_VERSION_EX_REQ failed " + printk(KERN_ERR "%s: " + "MSG_SMS_GET_VERSION_EX_REQ failed " "second try, rc %d\n", __func__, rc); } else rc = -ETIME; @@ -921,7 +922,7 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) last_sample_time = time_now; if (time_now - last_sample_time > 10000) { - printk("\n%s data rate %d bytes/secs\n", __func__, + printk(KERN_DEBUG "\n%s data rate %d bytes/secs\n", __func__, (int)((data_total * 1000) / (time_now - last_sample_time))); @@ -940,8 +941,8 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) case MSG_SMS_GET_VERSION_EX_RES: { SmsVersionRes_ST *ver = (SmsVersionRes_ST *) phdr; - printk("%s: MSG_SMS_GET_VERSION_EX_RES id %d " - "prots 0x%x ver %d.%d\n", __func__, + printk(KERN_DEBUG "%s: MSG_SMS_GET_VERSION_EX_RES " + "id %d prots 0x%x ver %d.%d\n", __func__, ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); @@ -953,21 +954,24 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) break; } case MSG_SMS_INIT_DEVICE_RES: - printk("%s: MSG_SMS_INIT_DEVICE_RES\n", __func__); + printk(KERN_DEBUG "%s: MSG_SMS_INIT_DEVICE_RES\n", + __func__); complete(&coredev->init_device_done); break; case MSG_SW_RELOAD_START_RES: - printk("%s: MSG_SW_RELOAD_START_RES\n", __func__); + printk(KERN_DEBUG "%s: MSG_SW_RELOAD_START_RES\n", + __func__); complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; case MSG_SW_RELOAD_EXEC_RES: - printk("%s: MSG_SW_RELOAD_EXEC_RES\n", __func__); + printk(KERN_DEBUG "%s: MSG_SW_RELOAD_EXEC_RES\n", + __func__); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", + printk(KERN_DEBUG "%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __func__); complete(&coredev->trigger_done); break; diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index f46e7facdb6b..65b1db61ac15 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -111,7 +111,8 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; - printk("%s add pid %d(%x)\n", __func__, feed->pid, feed->pid); + printk(KERN_DEBUG "%s add pid %d(%x)\n", __func__, + feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -130,7 +131,8 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) container_of(feed->demux, smsdvb_client_t, demux); SmsMsgData_ST PidMsg; - printk("%s remove pid %d(%x)\n", __func__, feed->pid, feed->pid); + printk(KERN_DEBUG "%s remove pid %d(%x)\n", __func__, + feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -212,7 +214,7 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { - printk("%s\n", __func__); + printk(KERN_DEBUG "%s\n", __func__); tune->min_delay_ms = 400; tune->step_size = 250000; @@ -239,7 +241,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; - printk("%s freq %d band %d\n", __func__, + printk(KERN_DEBUG "%s freq %d band %d\n", __func__, fep->frequency, fep->u.ofdm.bandwidth); switch (fep->u.ofdm.bandwidth) { @@ -259,7 +261,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, { smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); - printk("%s\n", __func__); + printk(KERN_DEBUG "%s\n", __func__); /* todo: */ memcpy(fep, &client->fe_params, @@ -328,7 +330,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", THIS_MODULE, device, adapter_nr); if (rc < 0) { - printk("%s dvb_register_adapter() failed %d\n", __func__, rc); + printk(KERN_ERR "%s dvb_register_adapter() failed %d\n", + __func__, rc); goto adapter_error; } @@ -341,7 +344,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, rc = dvb_dmx_init(&client->demux); if (rc < 0) { - printk("%s dvb_dmx_init failed %d\n\n", __func__, rc); + printk(KERN_ERR "%s dvb_dmx_init failed %d\n\n", + __func__, rc); goto dvbdmx_error; } @@ -352,7 +356,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); if (rc < 0) { - printk("%s dvb_dmxdev_init failed %d\n", __func__, rc); + printk(KERN_ERR "%s dvb_dmxdev_init failed %d\n", + __func__, rc); goto dmxdev_error; } @@ -362,7 +367,8 @@ int smsdvb_hotplug(smscore_device_t *coredev, rc = dvb_register_frontend(&client->adapter, &client->frontend); if (rc < 0) { - printk("%s frontend registration failed %d\n", __func__, rc); + printk(KERN_ERR "%s frontend registration failed %d\n", + __func__, rc); goto frontend_error; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 102c5857a23d..82f2e3e4bec6 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -241,7 +241,7 @@ void smsusb1_detectmode(void *context, int *mode) if (!product_string) { product_string = "none"; - printk("%s product string not found\n", __func__); + printk(KERN_ERR "%s product string not found\n", __func__); } else if (strstr(product_string, "DVBH")) *mode = 1; else if (strstr(product_string, "BDA")) @@ -251,7 +251,7 @@ void smsusb1_detectmode(void *context, int *mode) else if (strstr(product_string, "TDMB")) *mode = 2; - printk("%s: %d \"%s\"\n", __func__, *mode, product_string); + printk(KERN_INFO "%s: %d \"%s\"\n", __func__, *mode, product_string); } int smsusb1_setmode(void *context, int mode) -- cgit v1.2.3 From ca78373687bddcd436e1bf2d9b6806cfd9cad8b8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 17:36:00 -0300 Subject: V4L/DVB (8285): sms1xxx: more 80-column cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 6 ++++-- drivers/media/dvb/siano/smscoreapi.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 3c0e64286d4e..d82aafacfb1a 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -971,7 +971,8 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) __func__); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk(KERN_DEBUG "%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", + printk(KERN_DEBUG + "%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", __func__); complete(&coredev->trigger_done); break; @@ -1059,7 +1060,8 @@ int smscore_validate_client(smscore_device_t *coredev, * @param coredev pointer to a coredev object from clients hotplug * @param initial_id all messages with this id would be sent to this client * @param data_type all messages of this type would be sent to this client - * @param onresponse_handler client handler that is called to process incoming messages + * @param onresponse_handler client handler that is called to + * process incoming messages * @param onremove_handler client handler that is called when device is removed * @param context client-specific context * @param client pointer to a value that receives created smsclient object diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 2a823b37ccf7..f0675cf4cef3 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -481,7 +481,8 @@ typedef struct SMSHOSTLIB_STATISTICS_DVB_S u32 NumMPEReceived; /* DVB-H, Num MPE section received */ /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; if set to 0xFFFFFFFF cell_id not yet recovered */ + u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; + * if set to 0xFFFFFFFF cell_id not yet recovered */ u32 DvbhSrvIndHP; /* DVB-H service indication info, * bit 1 - Time Slicing indicator, * bit 0 - MPE-FEC indicator */ -- cgit v1.2.3 From 18245e18eeae15e928b46c1ae0f3a19bdc50419d Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 17:52:24 -0300 Subject: V4L/DVB (8286): sms1xxx: remove typedefs Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 243 ++++++++++++++-------------- drivers/media/dvb/siano/smscoreapi.h | 299 +++++++---------------------------- drivers/media/dvb/siano/smsdvb.c | 70 ++++---- drivers/media/dvb/siano/smsusb.c | 62 ++++---- 4 files changed, 256 insertions(+), 418 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index d82aafacfb1a..e3c6d9cb5621 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -50,33 +50,27 @@ #define PWARNING(fmt, args...) #endif -typedef struct _smscore_device_notifyee -{ +struct smscore_device_notifyee_t { struct list_head entry; hotplug_t hotplug; -} smscore_device_notifyee_t; +}; -typedef struct _smscore_subclient -{ +struct smscore_idlist_t { struct list_head entry; int id; int data_type; -} smscore_idlist_t; +}; -typedef struct _smscore_client -{ +struct smscore_client_t { struct list_head entry; - smscore_device_t *coredev; + struct smscore_device_t *coredev; void *context; struct list_head idlist; onresponse_t onresponse_handler; onremove_t onremove_handler; -} *psmscore_client_t; - - +}; -typedef struct _smscore_device -{ +struct smscore_device_t { struct list_head entry; struct list_head clients; @@ -107,15 +101,14 @@ typedef struct _smscore_device struct completion version_ex_done, data_download_done, trigger_done; struct completion init_device_done, reload_start_done, resume_done; -} *psmscore_device_t; +}; -typedef struct _smscore_registry_entry -{ +struct smscore_registry_entry_t { struct list_head entry; char devpath[32]; int mode; - sms_device_type_st type; -} smscore_registry_entry_t; + enum sms_device_type_st type; +}; struct list_head g_smscore_notifyees; struct list_head g_smscore_devices; @@ -129,23 +122,24 @@ static int default_mode = 1; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -static smscore_registry_entry_t *smscore_find_registry(char *devpath) +static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; struct list_head *next; kmutex_lock(&g_smscore_registrylock); for (next = g_smscore_registry.next; next != &g_smscore_registry; next = next->next) { - entry = (smscore_registry_entry_t *) next; + entry = (struct smscore_registry_entry_t *) next; if (!strcmp(entry->devpath, devpath)) { kmutex_unlock(&g_smscore_registrylock); return entry; } } - entry = (smscore_registry_entry_t *) - kmalloc(sizeof(smscore_registry_entry_t), GFP_KERNEL); + entry = (struct smscore_registry_entry_t *) + kmalloc(sizeof(struct smscore_registry_entry_t), + GFP_KERNEL); if (entry) { entry->mode = default_mode; strcpy(entry->devpath, devpath); @@ -159,7 +153,7 @@ static smscore_registry_entry_t *smscore_find_registry(char *devpath) int smscore_registry_getmode(char *devpath) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; entry = smscore_find_registry(devpath); if (entry) @@ -170,9 +164,9 @@ int smscore_registry_getmode(char *devpath) return default_mode; } -sms_device_type_st smscore_registry_gettype(char *devpath) +enum sms_device_type_st smscore_registry_gettype(char *devpath) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; entry = smscore_find_registry(devpath); if (entry) @@ -185,7 +179,7 @@ sms_device_type_st smscore_registry_gettype(char *devpath) void smscore_registry_setmode(char *devpath, int mode) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; entry = smscore_find_registry(devpath); if (entry) @@ -194,9 +188,9 @@ void smscore_registry_setmode(char *devpath, int mode) printk(KERN_ERR "%s No registry found.\n", __func__); } -void smscore_registry_settype(char *devpath, sms_device_type_st type) +void smscore_registry_settype(char *devpath, enum sms_device_type_st type) { - smscore_registry_entry_t *entry; + struct smscore_registry_entry_t *entry; entry = smscore_find_registry(devpath); if (entry) @@ -229,20 +223,22 @@ void list_add_locked(struct list_head *new, struct list_head *head, */ int smscore_register_hotplug(hotplug_t hotplug) { - smscore_device_notifyee_t *notifyee; + struct smscore_device_notifyee_t *notifyee; struct list_head *next, *first; int rc = 0; kmutex_lock(&g_smscore_deviceslock); - notifyee = kmalloc(sizeof(smscore_device_notifyee_t), GFP_KERNEL); + notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t), + GFP_KERNEL); if (notifyee) { /* now notify callback about existing devices */ first = &g_smscore_devices; for (next = first->next; next != first && !rc; next = next->next) { - smscore_device_t *coredev = (smscore_device_t *) next; + struct smscore_device_t *coredev = + (struct smscore_device_t *) next; rc = hotplug(coredev, coredev->device, 1); } @@ -274,8 +270,8 @@ void smscore_unregister_hotplug(hotplug_t hotplug) first = &g_smscore_notifyees; for (next = first->next; next != first;) { - smscore_device_notifyee_t *notifyee = - (smscore_device_notifyee_t *) next; + struct smscore_device_notifyee_t *notifyee = + (struct smscore_device_notifyee_t *) next; next = next->next; if (notifyee->hotplug == hotplug) { @@ -287,19 +283,19 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } -void smscore_notify_clients(smscore_device_t *coredev) +void smscore_notify_clients(struct smscore_device_t *coredev) { - smscore_client_t *client; + struct smscore_client_t *client; /* the client must call smscore_unregister_client from remove handler */ while (!list_empty(&coredev->clients)) { - client = (smscore_client_t *) coredev->clients.next; + client = (struct smscore_client_t *) coredev->clients.next; client->onremove_handler(client->context); } } -int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, - int arrival) +int smscore_notify_callbacks(struct smscore_device_t *coredev, + struct device *device, int arrival) { struct list_head *next, *first; int rc = 0; @@ -309,7 +305,7 @@ int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, first = &g_smscore_notifyees; for (next = first->next; next != first; next = next->next) { - rc = ((smscore_device_notifyee_t *) next)-> + rc = ((struct smscore_device_notifyee_t *) next)-> hotplug(coredev, device, arrival); if (rc < 0) break; @@ -318,10 +314,11 @@ int smscore_notify_callbacks(smscore_device_t *coredev, struct device *device, return rc; } -smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, +struct smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, dma_addr_t common_buffer_phys) { - smscore_buffer_t *cb = kmalloc(sizeof(smscore_buffer_t), GFP_KERNEL); + struct smscore_buffer_t *cb = + kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); if (!cb) { printk(KERN_INFO "%s kmalloc(...) failed\n", __func__); return NULL; @@ -344,13 +341,13 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, * * @return 0 on success, <0 on error. */ -int smscore_register_device(smsdevice_params_t *params, - smscore_device_t **coredev) +int smscore_register_device(struct smsdevice_params_t *params, + struct smscore_device_t **coredev) { - smscore_device_t *dev; + struct smscore_device_t *dev; u8 *buffer; - dev = kzalloc(sizeof(smscore_device_t), GFP_KERNEL); + dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); if (!dev) { printk(KERN_INFO "%s kzalloc(...) failed\n", __func__); return -ENOMEM; @@ -389,7 +386,7 @@ int smscore_register_device(smsdevice_params_t *params, for (buffer = dev->common_buffer; dev->num_buffers < params->num_buffers; dev->num_buffers++, buffer += params->buffer_size) { - smscore_buffer_t *cb = + struct smscore_buffer_t *cb = smscore_createbuffer(buffer, dev->common_buffer, dev->common_buffer_phys); if (!cb) { @@ -437,7 +434,7 @@ int smscore_register_device(smsdevice_params_t *params, * * @return 0 on success, <0 on error. */ -int smscore_start_device(smscore_device_t *coredev) +int smscore_start_device(struct smscore_device_t *coredev) { int rc = smscore_set_device_mode( coredev, smscore_registry_getmode(coredev->devpath)); @@ -459,7 +456,7 @@ int smscore_start_device(smscore_device_t *coredev) return rc; } -int smscore_sendrequest_and_wait(smscore_device_t *coredev, void *buffer, +int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); @@ -474,11 +471,11 @@ int smscore_sendrequest_and_wait(smscore_device_t *coredev, void *buffer, 0 : -ETIME; } -int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, - size_t size) +int smscore_load_firmware_family2(struct smscore_device_t *coredev, + void *buffer, size_t size) { - SmsFirmware_ST *firmware = (SmsFirmware_ST *) buffer; - SmsMsgHdr_ST *msg; + struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; + struct SmsMsgHdr_ST *msg; u32 mem_address = firmware->StartAddress; u8 *payload = firmware->Payload; int rc = 0; @@ -492,14 +489,14 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, } /* PAGE_SIZE buffer shall be enough and dma aligned */ - msg = (SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); + msg = (struct SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); if (!msg) return -ENOMEM; if (coredev->mode != DEVICE_MODE_NONE) { PDEBUG("Sending reload command\n"); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, - sizeof(SmsMsgHdr_ST)); + sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->reload_start_done); @@ -507,11 +504,12 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, } while (size && rc >= 0) { - SmsDataDownload_ST *DataMsg = (SmsDataDownload_ST *) msg; + struct SmsDataDownload_ST *DataMsg = + (struct SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, - (u16)(sizeof(SmsMsgHdr_ST) + + (u16)(sizeof(struct SmsMsgHdr_ST) + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; @@ -535,10 +533,11 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, if (rc >= 0) { if (coredev->mode == DEVICE_MODE_NONE) { - SmsMsgData_ST *TriggerMsg = (SmsMsgData_ST *) msg; + struct SmsMsgData_ST *TriggerMsg = + (struct SmsMsgData_ST *) msg; SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(SmsMsgHdr_ST) + + sizeof(struct SmsMsgHdr_ST) + sizeof(u32) * 5); TriggerMsg->msgData[0] = firmware->StartAddress; @@ -560,7 +559,7 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, &coredev->trigger_done); } else { SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, - sizeof(SmsMsgHdr_ST)); + sizeof(struct SmsMsgHdr_ST)); rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); @@ -588,7 +587,8 @@ int smscore_load_firmware_family2(smscore_device_t *coredev, void *buffer, * * @return 0 on success, <0 on error. */ -int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, +int smscore_load_firmware_from_file(struct smscore_device_t *coredev, + char *filename, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; @@ -632,8 +632,8 @@ int smscore_load_firmware_from_file(smscore_device_t *coredev, char *filename, return rc; } -int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, - int size, int new_mode) +int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, + u8 *buffer, int size, int new_mode) { PERROR("Feature not implemented yet\n"); return -EFAULT; @@ -648,9 +648,9 @@ int smscore_load_firmware_from_buffer(smscore_device_t *coredev, u8 *buffer, * * @return 0 on success, <0 on error. */ -void smscore_unregister_device(smscore_device_t *coredev) +void smscore_unregister_device(struct smscore_device_t *coredev) { - smscore_buffer_t *cb; + struct smscore_buffer_t *cb; int num_buffers = 0; int retry = 0; @@ -695,17 +695,19 @@ void smscore_unregister_device(smscore_device_t *coredev) printk(KERN_INFO "%s device %p destroyed\n", __func__, coredev); } -int smscore_detect_mode(smscore_device_t *coredev) +int smscore_detect_mode(struct smscore_device_t *coredev) { - void *buffer = kmalloc(sizeof(SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, + void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - SmsMsgHdr_ST *msg = (SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); + struct SmsMsgHdr_ST *msg = + (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); int rc; if (!buffer) return -ENOMEM; - SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, sizeof(SmsMsgHdr_ST)); + SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, + sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); @@ -754,11 +756,11 @@ char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { * * @return 0 on success, <0 on error. */ -int smscore_set_device_mode(smscore_device_t *coredev, int mode) +int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) { void *buffer; int rc = 0; - sms_device_type_st type; + enum sms_device_type_st type; PDEBUG("set device mode to %d\n", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { @@ -798,14 +800,15 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) printk(KERN_INFO "%s mode %d supported by running " "firmware\n", __func__, mode); - buffer = kmalloc(sizeof(SmsMsgData_ST) + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); + buffer = kmalloc(sizeof(struct SmsMsgData_ST) + + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { - SmsMsgData_ST *msg = - (SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); + struct SmsMsgData_ST *msg = + (struct SmsMsgData_ST *) + SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, - sizeof(SmsMsgData_ST)); + sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; rc = smscore_sendrequest_and_wait( @@ -853,7 +856,7 @@ int smscore_set_device_mode(smscore_device_t *coredev, int mode) * * @return current mode */ -int smscore_get_device_mode(smscore_device_t *coredev) +int smscore_get_device_mode(struct smscore_device_t *coredev) { return coredev->mode; } @@ -868,10 +871,10 @@ int smscore_get_device_mode(smscore_device_t *coredev) * @param id client id (SMS_DONT_CARE for all id) * */ -smscore_client_t *smscore_find_client(smscore_device_t *coredev, +struct smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, int data_type, int id) { - smscore_client_t *client = NULL; + struct smscore_client_t *client = NULL; struct list_head *next, *first; unsigned long flags; struct list_head *firstid, *nextid; @@ -882,14 +885,14 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, for (next = first->next; (next != first) && !client; next = next->next) { - firstid = &((smscore_client_t *)next)->idlist; + firstid = &((struct smscore_client_t *)next)->idlist; for (nextid = firstid->next; nextid != firstid; nextid = nextid->next) { - if ((((smscore_idlist_t *)nextid)->id == id) && - (((smscore_idlist_t *)nextid)->data_type == data_type || - (((smscore_idlist_t *)nextid)->data_type == 0))) { - client = (smscore_client_t *) next; + if ((((struct smscore_idlist_t *)nextid)->id == id) && + (((struct smscore_idlist_t *)nextid)->data_type == data_type || + (((struct smscore_idlist_t *)nextid)->data_type == 0))) { + client = (struct smscore_client_t *) next; break; } } @@ -907,10 +910,12 @@ smscore_client_t *smscore_find_client(smscore_device_t *coredev, * @param cb pointer to response buffer descriptor * */ -void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) +void smscore_onresponse(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb) { - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); - smscore_client_t *client = + struct SmsMsgHdr_ST *phdr = + (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); + struct smscore_client_t *client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; @@ -940,7 +945,8 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) switch (phdr->msgType) { case MSG_SMS_GET_VERSION_EX_RES: { - SmsVersionRes_ST *ver = (SmsVersionRes_ST *) phdr; + struct SmsVersionRes_ST *ver = + (struct SmsVersionRes_ST *) phdr; printk(KERN_DEBUG "%s: MSG_SMS_GET_VERSION_EX_RES " "id %d prots 0x%x ver %d.%d\n", __func__, ver->FirmwareId, ver->SupportedProtocols, @@ -994,15 +1000,15 @@ void smscore_onresponse(smscore_device_t *coredev, smscore_buffer_t *cb) * * @return pointer to descriptor on success, NULL on error. */ -smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) { - smscore_buffer_t *cb = NULL; + struct smscore_buffer_t *cb = NULL; unsigned long flags; spin_lock_irqsave(&coredev->bufferslock, flags); if (!list_empty(&coredev->buffers)) { - cb = (smscore_buffer_t *) coredev->buffers.next; + cb = (struct smscore_buffer_t *) coredev->buffers.next; list_del(&cb->entry); } @@ -1019,16 +1025,18 @@ smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev) * @param cb pointer buffer descriptor * */ -void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb) +void smscore_putbuffer(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb) { list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -int smscore_validate_client(smscore_device_t *coredev, - smscore_client_t *client, int data_type, int id) +int smscore_validate_client(struct smscore_device_t *coredev, + struct smscore_client_t *client, + int data_type, int id) { - smscore_idlist_t *listentry; - smscore_client_t *registered_client; + struct smscore_idlist_t *listentry; + struct smscore_client_t *registered_client; if (!client) { PERROR("bad parameter.\n"); @@ -1042,7 +1050,7 @@ int smscore_validate_client(smscore_device_t *coredev, PERROR("The msg ID already registered to another client.\n"); return -EEXIST; } - listentry = kzalloc(sizeof(smscore_idlist_t), GFP_KERNEL); + listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); if (!listentry) { PERROR("Can't allocate memory for client id.\n"); return -ENOMEM; @@ -1068,11 +1076,11 @@ int smscore_validate_client(smscore_device_t *coredev, * * @return 0 on success, <0 on error. */ -int smscore_register_client(smscore_device_t *coredev, - smsclient_params_t *params, - smscore_client_t **client) +int smscore_register_client(struct smscore_device_t *coredev, + struct smsclient_params_t *params, + struct smscore_client_t **client) { - smscore_client_t *newclient; + struct smscore_client_t *newclient; /* check that no other channel with same parameters exists */ if (smscore_find_client(coredev, params->data_type, params->initial_id)) { @@ -1080,7 +1088,7 @@ int smscore_register_client(smscore_device_t *coredev, return -EEXIST; } - newclient = kzalloc(sizeof(smscore_client_t), GFP_KERNEL); + newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); if (!newclient) { PERROR("Failed to allocate memory for client.\n"); return -ENOMEM; @@ -1109,17 +1117,17 @@ int smscore_register_client(smscore_device_t *coredev, * smscore_register_client * */ -void smscore_unregister_client(smscore_client_t *client) +void smscore_unregister_client(struct smscore_client_t *client) { - smscore_device_t *coredev = client->coredev; + struct smscore_device_t *coredev = client->coredev; unsigned long flags; spin_lock_irqsave(&coredev->clientslock, flags); while (!list_empty(&client->idlist)) { - smscore_idlist_t *identry = - (smscore_idlist_t *) client->idlist.next; + struct smscore_idlist_t *identry = + (struct smscore_idlist_t *) client->idlist.next; list_del(&identry->entry); kfree(identry); } @@ -1143,10 +1151,11 @@ void smscore_unregister_client(smscore_client_t *client) * * @return 0 on success, <0 on error. */ -int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) +int smsclient_sendrequest(struct smscore_client_t *client, + void *buffer, size_t size) { - smscore_device_t *coredev; - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) buffer; + struct smscore_device_t *coredev; + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; int rc; if (client == NULL) { @@ -1177,7 +1186,7 @@ int smsclient_sendrequest(smscore_client_t *client, void *buffer, size_t size) * * @return size (in bytes) of the buffer */ -int smscore_get_common_buffer_size(smscore_device_t *coredev) +int smscore_get_common_buffer_size(struct smscore_device_t *coredev) { return coredev->common_buffer_size; } @@ -1190,7 +1199,7 @@ int smscore_get_common_buffer_size(smscore_device_t *coredev) * * @return 0 on success, <0 on error. */ -int smscore_map_common_buffer(smscore_device_t *coredev, +int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma) { unsigned long end = vma->vm_end, @@ -1247,8 +1256,9 @@ void smscore_module_exit(void) kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { - smscore_device_notifyee_t *notifyee = - (smscore_device_notifyee_t *) g_smscore_notifyees.next; + struct smscore_device_notifyee_t *notifyee = + (struct smscore_device_notifyee_t *) + g_smscore_notifyees.next; list_del(¬ifyee->entry); kfree(notifyee); @@ -1257,8 +1267,9 @@ void smscore_module_exit(void) kmutex_lock(&g_smscore_registrylock); while (!list_empty(&g_smscore_registry)) { - smscore_registry_entry_t *entry = - (smscore_registry_entry_t *) g_smscore_registry.next; + struct smscore_registry_entry_t *entry = + (struct smscore_registry_entry_t *) + g_smscore_registry.next; list_del(&entry->entry); kfree(entry); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index f0675cf4cef3..be98baf3085e 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -57,19 +57,19 @@ typedef struct mutex kmutex_t; #define SMS_ROM_NO_RESPONSE 2 #define SMS_DEVICE_NOT_READY 0x8000000 -typedef enum { +enum sms_device_type_st { SMS_STELLAR = 0, SMS_NOVA_A0, SMS_NOVA_B0, SMS_VEGA, SMS_NUM_OF_DEVICE_TYPES -} sms_device_type_st; +}; -typedef struct _smscore_device smscore_device_t; -typedef struct _smscore_client smscore_client_t; -typedef struct _smscore_buffer smscore_buffer_t; +struct smscore_device_t; +struct smscore_client_t; +struct smscore_buffer_t; -typedef int (*hotplug_t)(smscore_device_t *coredev, +typedef int (*hotplug_t)(struct smscore_device_t *coredev, struct device *device, int arrival); typedef int (*setmode_t)(void *context, int mode); @@ -79,11 +79,10 @@ typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); typedef int (*preload_t)(void *context); typedef int (*postload_t)(void *context); -typedef int (*onresponse_t)(void *context, smscore_buffer_t *cb); +typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb); typedef void (*onremove_t)(void *context); -typedef struct _smscore_buffer -{ +struct smscore_buffer_t { /* public members, once passed to clients can be changed freely */ struct list_head entry; int size; @@ -93,10 +92,9 @@ typedef struct _smscore_buffer void *p; dma_addr_t phys; unsigned long offset_in_common; -} *psmscore_buffer_t; +}; -typedef struct _smsdevice_params -{ +struct smsdevice_params_t { struct device *device; int buffer_size; @@ -112,18 +110,17 @@ typedef struct _smsdevice_params postload_t postload_handler; void *context; - sms_device_type_st device_type; -} smsdevice_params_t; + enum sms_device_type_st device_type; +}; -typedef struct _smsclient_params -{ +struct smsclient_params_t { int initial_id; int data_type; onresponse_t onresponse_handler; onremove_t onremove_handler; void *context; -} smsclient_params_t; +}; /* GPIO definitions for antenna frequency domain control (SMS8021) */ #define SMS_ANTENNA_GPIO_0 1 @@ -201,8 +198,7 @@ typedef struct _smsclient_params #define SMS_INIT_MSG(ptr, type, len) \ SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) -typedef enum -{ +enum SMS_DEVICE_MODE { DEVICE_MODE_NONE = -1, DEVICE_MODE_DVBT = 0, DEVICE_MODE_DVBH, @@ -214,33 +210,29 @@ typedef enum DEVICE_MODE_CMMB, DEVICE_MODE_RAW_TUNER, DEVICE_MODE_MAX, -} SMS_DEVICE_MODE; +}; -typedef struct SmsMsgHdr_S -{ +struct SmsMsgHdr_ST { u16 msgType; u8 msgSrcId; u8 msgDstId; u16 msgLength; /* Length of entire message, including header */ u16 msgFlags; -} SmsMsgHdr_ST; +}; -typedef struct SmsMsgData_S -{ - SmsMsgHdr_ST xMsgHeader; +struct SmsMsgData_ST { + struct SmsMsgHdr_ST xMsgHeader; u32 msgData[1]; -} SmsMsgData_ST; +}; -typedef struct SmsDataDownload_S -{ - SmsMsgHdr_ST xMsgHeader; +struct SmsDataDownload_ST { + struct SmsMsgHdr_ST xMsgHeader; u32 MemAddr; u8 Payload[SMS_MAX_PAYLOAD_SIZE]; -} SmsDataDownload_ST; +}; -typedef struct SmsVersionRes_S -{ - SmsMsgHdr_ST xMsgHeader; +struct SmsVersionRes_ST { + struct SmsMsgHdr_ST xMsgHeader; u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ u8 Step; /* 0 - Step A */ @@ -263,18 +255,16 @@ typedef struct SmsVersionRes_S u8 RomVersionFieldPatch; u8 TextLabel[34]; -} SmsVersionRes_ST; +}; -typedef struct SmsFirmware_S -{ +struct SmsFirmware_ST { u32 CheckSum; u32 Length; u32 StartAddress; u8 Payload[1]; -} SmsFirmware_ST; +}; -typedef struct SMSHOSTLIB_STATISTICS_S -{ +struct SMSHOSTLIB_STATISTICS_ST { u32 Reserved; /* Reserved */ /* Common parameters */ @@ -339,196 +329,25 @@ typedef struct SMSHOSTLIB_STATISTICS_S u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; * if set to 0xFFFFFFFF cell_id not yet recovered */ -} SMSHOSTLIB_STATISTICS_ST; +}; -typedef struct -{ +struct SmsMsgStatisticsInfo_ST { u32 RequestResult; - SMSHOSTLIB_STATISTICS_ST Stat; + struct SMSHOSTLIB_STATISTICS_ST Stat; /* Split the calc of the SNR in DAB */ u32 Signal; /* dB */ u32 Noise; /* dB */ -} SmsMsgStatisticsInfo_ST; - -typedef struct SMSHOSTLIB_ISDBT_LAYER_STAT_S -{ - /* Per-layer information */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, - * 255 means layer does not exist */ - u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET, - * 255 means layer does not exist */ - u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 BERErrorCount; /* Post Viterbi Error Bits Count */ - u32 BERBitCount; /* Post Viterbi Total Bits Count */ - u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */ - u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */ - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 TILdepthI; /* Time interleaver depth I parameter, - * 255 means layer does not exist */ - u32 NumberOfSegments; /* Number of segments in layer A, - * 255 means layer does not exist */ - u32 TMCCErrors; /* TMCC errors */ -} SMSHOSTLIB_ISDBT_LAYER_STAT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_ISDBT_S -{ - u32 StatisticsType; /* Enumerator identifying the type of the - * structure. Values are the same as - * SMSHOSTLIB_DEVICE_MODES_E - * - * This field MUST always be first in any - * statistics structure */ - - u32 FullSize; /* Total size of the structure returned by the modem. - * If the size requested by the host is smaller than - * FullSize, the struct will be truncated */ - - /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - /* Reception quality */ - s32 SNR; /* dB */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in Hz */ - - /* Transmission parameters */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* ISDB-T transmission mode */ - u32 ModemState; /* 0 - Acquisition, 1 - Locked */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */ - u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */ - u32 NumOfLayers; /* Number of ISDB-T layers in the network */ - - /* Per-layer information */ - /* Layers A, B and C */ - SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3]; /* Per-layer statistics, - see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */ +}; - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ - -} SMSHOSTLIB_STATISTICS_ISDBT_ST; - -typedef struct SMSHOSTLIB_STATISTICS_DVB_S -{ - u32 StatisticsType; /* Enumerator identifying the type of the - * structure. Values are the same as - * SMSHOSTLIB_DEVICE_MODES_E - * This field MUST always first in any - * statistics structure */ - - u32 FullSize; /* Total size of the structure returned by the modem. - * If the size requested by the host is smaller than - * FullSize, the struct will be truncated */ - /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - /* Reception quality */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 BERErrorCount; /* Number of errornous SYNC bits. */ - u32 BERBitCount; /* Total number of SYNC bits. */ - u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A */ - u32 MFER; /* DVB-H frame error rate in percentage, - * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - - /* Transmission parameters */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ - u32 TransmissionMode; /* FFT mode carriers in Kilos */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ - u32 LPCodeRate; /* Low Priority Code Rate from - * SMSHOSTLIB_CODE_RATE_ET */ - u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ - u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET */ - - /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes */ - u32 BurstDuration; /* Current burst duration in mSec */ - u32 BurstCycleTime; /* Current burst cycle time in mSec */ - u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, - * as calculated by demodulator */ - u32 NumOfRows; /* Number of rows in MPE table */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ - - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include - * errors after MPE RS decoding */ - u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include - * errors after MPE RS decoding */ - u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were - * corrected by MPE RS decoding */ - - u32 NumMPEReceived; /* DVB-H, Num MPE section received */ - - /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; - * if set to 0xFFFFFFFF cell_id not yet recovered */ - u32 DvbhSrvIndHP; /* DVB-H service indication info, - * bit 1 - Time Slicing indicator, - * bit 0 - MPE-FEC indicator */ - u32 DvbhSrvIndLP; /* DVB-H service indication info, - * bit 1 - Time Slicing indicator, - * bit 0 - MPE-FEC indicator */ - - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ -} SMSHOSTLIB_STATISTICS_DVB_ST; - -typedef struct SMSHOSTLIB_GPIO_CONFIG_S -{ - u8 Direction; /* GPIO direction: Input - 0, Output - 1 */ - u8 PullUpDown; /* PullUp/PullDown: None - 0, - * PullDown - 1, PullUp - 2, Keeper - 3 */ - u8 InputCharacteristics; /* Input Characteristics: Normal - 0, - * Schmitt trigger - 1 */ - u8 OutputSlewRate; /* Output Slew Rate: - * Fast slew rate - 0, Slow slew rate - 1 */ - u8 OutputDriving; /* Output driving capability: - * 4mA - 0, 8mA - 1, 12mA - 2, 16mA - 3 */ -} SMSHOSTLIB_GPIO_CONFIG_ST; - -typedef struct SMSHOSTLIB_I2C_REQ_S -{ - u32 DeviceAddress; /* I2c device address */ - u32 WriteCount; /* number of bytes to write */ - u32 ReadCount; /* number of bytes to read */ - u8 Data[1]; -} SMSHOSTLIB_I2C_REQ_ST; - -typedef struct SMSHOSTLIB_I2C_RES_S -{ - u32 Status; /* non-zero value in case of failure */ - u32 ReadCount; /* number of bytes read */ - u8 Data[1]; -} SMSHOSTLIB_I2C_RES_ST; - -typedef struct _smsdvb_client -{ +struct smsdvb_client_t { struct list_head entry; - smscore_device_t *coredev; - smscore_client_t *smsclient; + struct smscore_device_t *coredev; + struct smscore_client_t *smsclient; struct dvb_adapter adapter; struct dvb_demux demux; @@ -543,7 +362,7 @@ typedef struct _smsdvb_client /* todo: save freq/band instead whole struct */ struct dvb_frontend_parameters fe_params; -} smsdvb_client_t; +}; extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -551,37 +370,39 @@ extern int smscore_registry_getmode(char *devpath); extern int smscore_register_hotplug(hotplug_t hotplug); extern void smscore_unregister_hotplug(hotplug_t hotplug); -extern int smscore_register_device(smsdevice_params_t *params, - smscore_device_t **coredev); -extern void smscore_unregister_device(smscore_device_t *coredev); +extern int smscore_register_device(struct smsdevice_params_t *params, + struct smscore_device_t **coredev); +extern void smscore_unregister_device(struct smscore_device_t *coredev); -extern int smscore_start_device(smscore_device_t *coredev); -extern int smscore_load_firmware(smscore_device_t *coredev, char *filename, - loadfirmware_t loadfirmware_handler); +extern int smscore_start_device(struct smscore_device_t *coredev); +extern int smscore_load_firmware(struct smscore_device_t *coredev, + char *filename, + loadfirmware_t loadfirmware_handler); -extern int smscore_load_firmware_from_buffer(smscore_device_t *coredev, +extern int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, u8 *buffer, int size, int new_mode); -extern int smscore_set_device_mode(smscore_device_t *coredev, int mode); -extern int smscore_get_device_mode(smscore_device_t *coredev); +extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); +extern int smscore_get_device_mode(struct smscore_device_t *coredev); -extern int smscore_register_client(smscore_device_t *coredev, - smsclient_params_t *params, - smscore_client_t **client); -extern void smscore_unregister_client(smscore_client_t *client); +extern int smscore_register_client(struct smscore_device_t *coredev, + struct smsclient_params_t *params, + struct smscore_client_t **client); +extern void smscore_unregister_client(struct smscore_client_t *client); -extern int smsclient_sendrequest(smscore_client_t *client, +extern int smsclient_sendrequest(struct smscore_client_t *client, void *buffer, size_t size); -extern void smscore_onresponse(smscore_device_t *coredev, - smscore_buffer_t *cb); +extern void smscore_onresponse(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb); -extern int smscore_get_common_buffer_size(smscore_device_t *coredev); -extern int smscore_map_common_buffer(smscore_device_t *coredev, +extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); +extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); -extern smscore_buffer_t *smscore_getbuffer(smscore_device_t *coredev); -extern void smscore_putbuffer(smscore_device_t *coredev, smscore_buffer_t *cb); +extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); +extern void smscore_putbuffer(struct smscore_device_t *coredev, + struct smscore_buffer_t *cb); /* smsdvb.c */ int smsdvb_register(void); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 65b1db61ac15..b17696fcbbc6 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -29,15 +29,16 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct list_head g_smsdvb_clients; kmutex_t g_smsdvb_clientslock; -int smsdvb_onresponse(void *context, smscore_buffer_t *cb) +int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { - smsdvb_client_t *client = (smsdvb_client_t *) context; - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); + struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; + struct SmsMsgHdr_ST *phdr = + (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), - cb->size - sizeof(SmsMsgHdr_ST)); + cb->size - sizeof(struct SmsMsgHdr_ST)); break; case MSG_SMS_RF_TUNE_RES: @@ -46,8 +47,8 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) case MSG_SMS_GET_STATISTICS_RES: { - SmsMsgStatisticsInfo_ST *p = - (SmsMsgStatisticsInfo_ST *)(phdr + 1); + struct SmsMsgStatisticsInfo_ST *p = + (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); if (p->Stat.IsDemodLocked) { client->fe_status = FE_HAS_SIGNAL | @@ -82,7 +83,7 @@ int smsdvb_onresponse(void *context, smscore_buffer_t *cb) return 0; } -void smsdvb_unregister_client(smsdvb_client_t *client) +void smsdvb_unregister_client(struct smsdvb_client_t *client) { /* must be called under clientslock */ @@ -100,16 +101,16 @@ void smsdvb_onremove(void *context) { kmutex_lock(&g_smsdvb_clientslock); - smsdvb_unregister_client((smsdvb_client_t *) context); + smsdvb_unregister_client((struct smsdvb_client_t *) context); kmutex_unlock(&g_smsdvb_clientslock); } static int smsdvb_start_feed(struct dvb_demux_feed *feed) { - smsdvb_client_t *client = - container_of(feed->demux, smsdvb_client_t, demux); - SmsMsgData_ST PidMsg; + struct smsdvb_client_t *client = + container_of(feed->demux, struct smsdvb_client_t, demux); + struct SmsMsgData_ST PidMsg; printk(KERN_DEBUG "%s add pid %d(%x)\n", __func__, feed->pid, feed->pid); @@ -127,9 +128,9 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) static int smsdvb_stop_feed(struct dvb_demux_feed *feed) { - smsdvb_client_t *client = - container_of(feed->demux, smsdvb_client_t, demux); - SmsMsgData_ST PidMsg; + struct smsdvb_client_t *client = + container_of(feed->demux, struct smsdvb_client_t, demux); + struct SmsMsgData_ST PidMsg; printk(KERN_DEBUG "%s remove pid %d(%x)\n", __func__, feed->pid, feed->pid); @@ -145,7 +146,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) &PidMsg, sizeof(PidMsg)); } -static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, +static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, void *buffer, size_t size, struct completion *completion) { @@ -158,18 +159,19 @@ static int smsdvb_sendrequest_and_wait(smsdvb_client_t *client, 0 : -ETIME; } -static int smsdvb_send_statistics_request(smsdvb_client_t *client) +static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) { - SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, + struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, DVBT_BDA_CONTROL_MSG_ID, - HIF_TASK, sizeof(SmsMsgHdr_ST), 0 }; + HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), &client->stat_done); } static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -180,7 +182,8 @@ static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -191,7 +194,8 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -202,7 +206,8 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); int rc = smsdvb_send_statistics_request(client); if (!rc) @@ -225,11 +230,11 @@ static int smsdvb_get_tune_settings(struct dvb_frontend *fe, static int smsdvb_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); - struct - { - SmsMsgHdr_ST Msg; + struct { + struct SmsMsgHdr_ST Msg; u32 Data[3]; } Msg; @@ -259,7 +264,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, static int smsdvb_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { - smsdvb_client_t *client = container_of(fe, smsdvb_client_t, frontend); + struct smsdvb_client_t *client = + container_of(fe, struct smsdvb_client_t, frontend); printk(KERN_DEBUG "%s\n", __func__); @@ -303,11 +309,11 @@ static struct dvb_frontend_ops smsdvb_fe_ops = { .read_snr = smsdvb_read_snr, }; -int smsdvb_hotplug(smscore_device_t *coredev, +int smsdvb_hotplug(struct smscore_device_t *coredev, struct device *device, int arrival) { - smsclient_params_t params; - smsdvb_client_t *client; + struct smsclient_params_t params; + struct smsdvb_client_t *client; int rc; /* device removal handled by onremove callback */ @@ -320,7 +326,7 @@ int smsdvb_hotplug(smscore_device_t *coredev, return 0; } - client = kzalloc(sizeof(smsdvb_client_t), GFP_KERNEL); + client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); if (!client) { printk(KERN_INFO "%s kmalloc() failed\n", __func__); return -ENOMEM; @@ -439,7 +445,7 @@ void smsdvb_unregister(void) while (!list_empty(&g_smsdvb_clients)) smsdvb_unregister_client( - (smsdvb_client_t *) g_smsdvb_clients.next); + (struct smsdvb_client_t *) g_smsdvb_clients.next); kmutex_unlock(&g_smsdvb_clientslock); } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 82f2e3e4bec6..85172f47c737 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -40,33 +40,31 @@ #define USB_PID_NOVA_B 0x0201 #define USB_PID_VEGA 0x0300 -typedef struct _smsusb_device smsusb_device_t; +struct smsusb_device_t; -typedef struct _smsusb_urb -{ - smscore_buffer_t *cb; - smsusb_device_t *dev; +struct smsusb_urb_t { + struct smscore_buffer_t *cb; + struct smsusb_device_t *dev; - struct urb urb; -} smsusb_urb_t; + struct urb urb; +}; -typedef struct _smsusb_device -{ +struct smsusb_device_t { struct usb_device *udev; - smscore_device_t *coredev; + struct smscore_device_t *coredev; - smsusb_urb_t surbs[MAX_URBS]; + struct smsusb_urb_t surbs[MAX_URBS]; int response_alignment; int buffer_size; -} *psmsusb_device_t; +}; -int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb); +int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb); void smsusb_onresponse(struct urb *urb) { - smsusb_urb_t *surb = (smsusb_urb_t *) urb->context; - smsusb_device_t *dev = surb->dev; + struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; + struct smsusb_device_t *dev = surb->dev; if (urb->status < 0) { printk(KERN_INFO "%s error, urb status %d, %d bytes\n", @@ -75,7 +73,7 @@ void smsusb_onresponse(struct urb *urb) } if (urb->actual_length > 0) { - SmsMsgHdr_ST *phdr = (SmsMsgHdr_ST *) surb->cb->p; + struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; if (urb->actual_length >= phdr->msgLength) { surb->cb->size = phdr->msgLength; @@ -102,7 +100,7 @@ void smsusb_onresponse(struct urb *urb) /* move buffer pointer and * copy header to its new location */ memcpy((char *) phdr + surb->cb->offset, - phdr, sizeof(SmsMsgHdr_ST)); + phdr, sizeof(struct SmsMsgHdr_ST)); } else surb->cb->offset = 0; @@ -119,7 +117,7 @@ exit_and_resubmit: smsusb_submit_urb(dev, surb); } -int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb) +int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) { if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); @@ -145,7 +143,7 @@ int smsusb_submit_urb(smsusb_device_t *dev, smsusb_urb_t *surb) return usb_submit_urb(&surb->urb, GFP_ATOMIC); } -void smsusb_stop_streaming(smsusb_device_t *dev) +void smsusb_stop_streaming(struct smsusb_device_t *dev) { int i; @@ -159,7 +157,7 @@ void smsusb_stop_streaming(smsusb_device_t *dev) } } -int smsusb_start_streaming(smsusb_device_t *dev) +int smsusb_start_streaming(struct smsusb_device_t *dev) { int i, rc; @@ -178,7 +176,7 @@ int smsusb_start_streaming(smsusb_device_t *dev) int smsusb_sendrequest(void *context, void *buffer, size_t size) { - smsusb_device_t *dev = (smsusb_device_t *) context; + struct smsusb_device_t *dev = (struct smsusb_device_t *) context; int dummy; return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), @@ -235,7 +233,8 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) void smsusb1_detectmode(void *context, int *mode) { - char *product_string = ((smsusb_device_t *) context)->udev->product; + char *product_string = + ((struct smsusb_device_t *) context)->udev->product; *mode = DEVICE_MODE_NONE; @@ -256,8 +255,8 @@ void smsusb1_detectmode(void *context, int *mode) int smsusb1_setmode(void *context, int mode) { - SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, - sizeof(SmsMsgHdr_ST), 0 }; + struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, + sizeof(struct SmsMsgHdr_ST), 0 }; if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { printk(KERN_INFO "%s invalid firmware id specified %d\n", @@ -270,7 +269,8 @@ int smsusb1_setmode(void *context, int mode) void smsusb_term_device(struct usb_interface *intf) { - smsusb_device_t *dev = (smsusb_device_t *) usb_get_intfdata(intf); + struct smsusb_device_t *dev = + (struct smsusb_device_t *) usb_get_intfdata(intf); if (dev) { smsusb_stop_streaming(dev); @@ -289,15 +289,15 @@ void smsusb_term_device(struct usb_interface *intf) int smsusb_init_device(struct usb_interface *intf) { - smsdevice_params_t params; - smsusb_device_t *dev; + struct smsdevice_params_t params; + struct smsusb_device_t *dev; int i, rc; /* create device object */ - dev = kzalloc(sizeof(smsusb_device_t), GFP_KERNEL); + dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); if (!dev) { - printk(KERN_INFO "%s kzalloc(sizeof(smsusb_device_t) failed\n", - __func__); + printk(KERN_INFO "%s kzalloc(sizeof(struct smsusb_device_t) " + "failed\n", __func__); return -ENOMEM; } @@ -334,7 +334,7 @@ int smsusb_init_device(struct usb_interface *intf) dev->buffer_size = USB2_BUFFER_SIZE; dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - - sizeof(SmsMsgHdr_ST); + sizeof(struct SmsMsgHdr_ST); params.flags |= SMS_DEVICE_FAMILY2; break; -- cgit v1.2.3 From e080842c6c31249010adb184f9efbbc5cb40bd2b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 19:11:37 -0300 Subject: V4L/DVB (8287): sms1xxx: fix WARNING: unnecessary cast may hide bugs fix the following checkpatch.pl warning: WARNING: unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html 596: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:540: + msg = (struct SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index e3c6d9cb5621..423ca5744952 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -489,7 +489,7 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, } /* PAGE_SIZE buffer shall be enough and dma aligned */ - msg = (struct SmsMsgHdr_ST *) kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); + msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); if (!msg) return -ENOMEM; -- cgit v1.2.3 From fbd05c8213e7cddca3041c280e5fca5eff0956f9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 19:27:35 -0300 Subject: V4L/DVB (8288): sms1xxx: more cleanups Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 423ca5744952..89fb5a73fc6f 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -734,15 +734,23 @@ int smscore_detect_mode(struct smscore_device_t *coredev) } char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - /*Stellar NOVA A0 Nova B0 VEGA*/ - /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "none", "none"}, - /*DABIP*/ {"none", "none", "none", "none"}, - /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, - /*ISDBTBDA*/{"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} + /*Stellar NOVA A0 Nova B0 VEGA*/ + /*DVBT*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*DVBH*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*TDMB*/ + {"none", "tdmb_nova_12mhz.inp", "none", "none"}, + /*DABIP*/ + {"none", "none", "none", "none"}, + /*BDA*/ + {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, + /*ISDBT*/ + {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, + /*ISDBTBDA*/ + {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, + /*CMMB*/ + {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; @@ -919,8 +927,8 @@ void smscore_onresponse(struct smscore_device_t *coredev, smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); int rc = -EBUSY; - static unsigned long last_sample_time = 0; - static int data_total = 0; + static unsigned long last_sample_time; /* = 0; */ + static int data_total; /* = 0; */ unsigned long time_now = jiffies_to_msecs(jiffies); if (!last_sample_time) -- cgit v1.2.3 From df0462e77e9aa19d50dbfd540e78f1803e992c25 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 15 Jun 2008 19:39:55 -0300 Subject: V4L/DVB (8289): sms1xxx: remove #if LINUX_VERSION_CODE checks Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 5 +---- drivers/media/dvb/siano/smscoreapi.h | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 89fb5a73fc6f..6b9f512a357d 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -200,7 +200,6 @@ void smscore_registry_settype(char *devpath, enum sms_device_type_st type) } - void list_add_locked(struct list_head *new, struct list_head *head, spinlock_t *lock) { @@ -592,7 +591,6 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; - const struct firmware *fw; u8 *fw_buffer; @@ -1228,8 +1226,7 @@ int smscore_map_common_buffer(struct smscore_device_t *coredev, if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, - size, pgprot_noncached(vma->vm_page_prot))) - { + size, pgprot_noncached(vma->vm_page_prot))) { printk(KERN_INFO "%s remap_page_range failed\n", __func__); return -EAGAIN; } diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index be98baf3085e..355c22b1d158 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -43,7 +43,6 @@ typedef struct mutex kmutex_t; #define kmutex_trylock(_p_) mutex_trylock(_p_) #define kmutex_unlock(_p_) mutex_unlock(_p_) - #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif -- cgit v1.2.3 From d3e72fe75ef7651e49e50f6a5f2c1c6453749e33 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 16 Jun 2008 12:37:05 -0300 Subject: V4L/DVB (8290): sms1xxx: small cleanup Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 85172f47c737..29183884d7ec 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -427,7 +427,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) } rc = smsusb_init_device(intf); - printk(KERN_INFO "%s rc %d\n", __func__, rc); + printk(KERN_INFO "%s rc %d\n", __func__, rc); return rc; } @@ -437,9 +437,10 @@ void smsusb_disconnect(struct usb_interface *intf) } static struct usb_device_id smsusb_id_table [] = { - { USB_DEVICE(USB_VID_SIANO, 0x0010) }, { USB_DEVICE(USB_VID_SIANO, USB_PID_STELLAR) }, { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_A) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_B) }, + { USB_DEVICE(USB_VID_SIANO, USB_PID_VEGA) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, smsusb_id_table); @@ -464,8 +465,8 @@ int smsusb_register(void) void smsusb_unregister(void) { + printk(KERN_DEBUG "%s\n", __func__); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); - printk(KERN_INFO "%s\n", __func__); } -- cgit v1.2.3 From dd5b2a5c2a6c793d855910864593ad26dd844154 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 18 Jun 2008 20:25:25 -0300 Subject: V4L/DVB (8291): sms1xxx: change default_mode to 4 Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 6b9f512a357d..32dbe2469639 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -117,7 +117,7 @@ kmutex_t g_smscore_deviceslock; struct list_head g_smscore_registry; kmutex_t g_smscore_registrylock; -static int default_mode = 1; +static int default_mode = 4; module_param(default_mode, int, 0644); MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); -- cgit v1.2.3 From 1c11d546b6c31399ac60f42d3103227cc1164d80 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 18 Jun 2008 22:09:55 -0300 Subject: V4L/DVB (8292): sms1xxx: add code to allow device-specific functionality Set board ID in the usb_device_id table's driver_info field. Use board name when registering the dvb adapter. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Makefile | 2 +- drivers/media/dvb/siano/sms-cards.c | 69 ++++++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/sms-cards.h | 42 ++++++++++++++++++++++ drivers/media/dvb/siano/smscoreapi.c | 12 +++++++ drivers/media/dvb/siano/smscoreapi.h | 3 ++ drivers/media/dvb/siano/smsdvb.c | 7 ++-- drivers/media/dvb/siano/smsusb.c | 44 ++++++++++------------- 7 files changed, 150 insertions(+), 29 deletions(-) create mode 100644 drivers/media/dvb/siano/sms-cards.c create mode 100644 drivers/media/dvb/siano/sms-cards.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index e549c4e2bbe2..ee0737af98c0 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile @@ -1,4 +1,4 @@ -sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o +sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c new file mode 100644 index 000000000000..88fc2a4edc1e --- /dev/null +++ b/drivers/media/dvb/siano/sms-cards.c @@ -0,0 +1,69 @@ +/* + * Card-specific functions for the Siano SMS1xxx USB dongle + * + * Copyright (c) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "sms-cards.h" + +struct usb_device_id smsusb_id_table[] = { + { USB_DEVICE(0x187f, 0x0010), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0100), + .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, + { USB_DEVICE(0x187f, 0x0200), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, + { USB_DEVICE(0x187f, 0x0201), + .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, + { USB_DEVICE(0x187f, 0x0300), + .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, smsusb_id_table); + +static struct sms_board sms_boards[] = { + [SMS_BOARD_UNKNOWN] = { + .name = "Unknown board", + }, + [SMS1XXX_BOARD_SIANO_SMS1000] = { + .name = "Siano Digital Receiver", + .type = SMS_STELLAR, + }, + [SMS1XXX_BOARD_SIANO_STELLAR] = { + .name = "Siano Stellar reference board", + .type = SMS_STELLAR, + }, + [SMS1XXX_BOARD_SIANO_NOVA_A] = { + .name = "Siano Nova A reference board", + .type = SMS_NOVA_A0, + }, + [SMS1XXX_BOARD_SIANO_NOVA_B] = { + .name = "Siano Nova B reference board", + .type = SMS_NOVA_B0, + }, + [SMS1XXX_BOARD_SIANO_VEGA] = { + .name = "Siano Vega reference board", + .type = SMS_VEGA, + }, +}; + +struct sms_board *sms_get_board(int id) +{ + BUG_ON(id >= ARRAY_SIZE(sms_boards)); + + return &sms_boards[id]; +} + diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h new file mode 100644 index 000000000000..7ba3df63dffe --- /dev/null +++ b/drivers/media/dvb/siano/sms-cards.h @@ -0,0 +1,42 @@ +/* + * Card-specific functions for the Siano SMS1xxx USB dongle + * + * Copyright (c) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation; + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SMS_CARDS_H__ +#define __SMS_CARDS_H__ + +#include +#include "smscoreapi.h" + +#define SMS_BOARD_UNKNOWN 0 +#define SMS1XXX_BOARD_SIANO_SMS1000 1 +#define SMS1XXX_BOARD_SIANO_STELLAR 2 +#define SMS1XXX_BOARD_SIANO_NOVA_A 3 +#define SMS1XXX_BOARD_SIANO_NOVA_B 4 +#define SMS1XXX_BOARD_SIANO_VEGA 5 + +struct sms_board { + char *name; + enum sms_device_type_st type; +}; + +struct sms_board *sms_get_board(int id); + +extern struct usb_device_id smsusb_id_table[]; + +#endif /* __SMS_CARDS_H__ */ diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 32dbe2469639..a5a3cbf2ffd6 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -101,8 +101,20 @@ struct smscore_device_t { struct completion version_ex_done, data_download_done, trigger_done; struct completion init_device_done, reload_start_done, resume_done; + + int board_id; }; +void smscore_set_board_id(struct smscore_device_t *core, int id) +{ + core->board_id = id; +} + +int smscore_get_board_id(struct smscore_device_t *core) +{ + return core->board_id; +} + struct smscore_registry_entry_t { struct list_head entry; char devpath[32]; diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 355c22b1d158..1962f016612b 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -403,6 +403,9 @@ extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *cored extern void smscore_putbuffer(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); +void smscore_set_board_id(struct smscore_device_t *core, int id); +int smscore_get_board_id(struct smscore_device_t *core); + /* smsdvb.c */ int smsdvb_register(void); void smsdvb_unregister(void); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index b17696fcbbc6..88b2bd2821dc 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -23,6 +23,7 @@ #include #include "smscoreapi.h" +#include "sms-cards.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -282,7 +283,7 @@ static void smsdvb_release(struct dvb_frontend *fe) static struct dvb_frontend_ops smsdvb_fe_ops = { .info = { - .name = "Siano Mobile Digital SMS10xx", + .name = "Siano Mobile Digital SMS1xxx", .type = FE_OFDM, .frequency_min = 44250000, .frequency_max = 867250000, @@ -333,7 +334,9 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, } /* register dvb adapter */ - rc = dvb_register_adapter(&client->adapter, "Siano Digital Receiver", + rc = dvb_register_adapter(&client->adapter, + sms_get_board( + smscore_get_board_id(coredev))->name, THIS_MODULE, device, adapter_nr); if (rc < 0) { printk(KERN_ERR "%s dvb_register_adapter() failed %d\n", diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 29183884d7ec..bb8a364477fb 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -25,6 +25,7 @@ #include #include "smscoreapi.h" +#include "sms-cards.h" #define USB1_BUFFER_SIZE 0x1000 #define USB2_BUFFER_SIZE 0x4000 @@ -32,14 +33,6 @@ #define MAX_BUFFERS 50 #define MAX_URBS 10 -/* TO DO: move these to a header file */ -#define USB_VID_SIANO 0x187f - -#define USB_PID_STELLAR 0x0100 -#define USB_PID_NOVA_A 0x0200 -#define USB_PID_NOVA_B 0x0201 -#define USB_PID_VEGA 0x0300 - struct smsusb_device_t; struct smsusb_urb_t { @@ -287,10 +280,11 @@ void smsusb_term_device(struct usb_interface *intf) usb_set_intfdata(intf, NULL); } -int smsusb_init_device(struct usb_interface *intf) +int smsusb_init_device(struct usb_interface *intf, int board_id) { struct smsdevice_params_t params; struct smsusb_device_t *dev; + struct sms_board *board; int i, rc; /* create device object */ @@ -305,9 +299,11 @@ int smsusb_init_device(struct usb_interface *intf) usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); - switch (dev->udev->descriptor.idProduct) { + board = sms_get_board(board_id); + + switch (board->type) { - case USB_PID_STELLAR: + case SMS_STELLAR: dev->buffer_size = USB1_BUFFER_SIZE; params.setmode_handler = smsusb1_setmode; @@ -316,19 +312,22 @@ int smsusb_init_device(struct usb_interface *intf) printk(KERN_INFO "%s stellar device found\n", __func__); break; default: - switch (dev->udev->descriptor.idProduct) { - case USB_PID_NOVA_A: + switch (board->type) { + case SMS_NOVA_A0: params.device_type = SMS_NOVA_A0; printk(KERN_INFO "%s nova A0 found\n", __func__); break; - default: - case USB_PID_NOVA_B: + case SMS_NOVA_B0: params.device_type = SMS_NOVA_B0; printk(KERN_INFO "%s nova B0 found\n", __func__); break; - case USB_PID_VEGA: + case SMS_VEGA: params.device_type = SMS_VEGA; printk(KERN_INFO "%s Vega found\n", __func__); + break; + default: + printk(KERN_ERR "%s Unspecified sms device type!\n", + __func__); } dev->buffer_size = USB2_BUFFER_SIZE; @@ -357,6 +356,8 @@ int smsusb_init_device(struct usb_interface *intf) return rc; } + smscore_set_board_id(dev->coredev, board_id); + /* initialize urbs */ for (i = 0; i < MAX_URBS; i++) { dev->surbs[i].dev = dev; @@ -426,7 +427,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) udev, smscore_registry_getmode(devpath)); } - rc = smsusb_init_device(intf); + rc = smsusb_init_device(intf, id->driver_info); printk(KERN_INFO "%s rc %d\n", __func__, rc); return rc; } @@ -436,15 +437,6 @@ void smsusb_disconnect(struct usb_interface *intf) smsusb_term_device(intf); } -static struct usb_device_id smsusb_id_table [] = { - { USB_DEVICE(USB_VID_SIANO, USB_PID_STELLAR) }, - { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_A) }, - { USB_DEVICE(USB_VID_SIANO, USB_PID_NOVA_B) }, - { USB_DEVICE(USB_VID_SIANO, USB_PID_VEGA) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - static struct usb_driver smsusb_driver = { .name = "smsusb", .probe = smsusb_probe, -- cgit v1.2.3 From 068d6c0f5d6c67d0e93f8e214897ddd64746be4e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 01:15:46 -0300 Subject: V4L/DVB (8293): sms1xxx: create printk macros Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 161 +++++++++++++++++------------------ drivers/media/dvb/siano/smscoreapi.h | 5 ++ drivers/media/dvb/siano/smsdvb.c | 46 +++++----- drivers/media/dvb/siano/smsusb.c | 106 +++++++++++------------ 4 files changed, 161 insertions(+), 157 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index a5a3cbf2ffd6..a35513ef74a9 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -34,16 +34,16 @@ #include "smscoreapi.h" #define PERROR(fmt, args...)\ - printk(KERN_ERR "smscore error: line %d- %s(): " fmt, \ + sms_err("smscore error: line %d- %s(): " fmt, \ __LINE__, __func__, ## args) #ifdef SMSCORE_DEBUG #undef PWARNING -# define PWARNING(fmt, args...) printk(KERN_INFO "smscore warning: " \ +# define PWARNING(fmt, args...) sms_info("smscore warning: " \ "line %d- %s(): " fmt, \ __LINE__, __func__, ## args) #undef PDEBUG /* undef it, just in case */ -# define PDEBUG(fmt, args...) printk(KERN_INFO "smscore - %s(): " fmt, \ +# define PDEBUG(fmt, args...) sms_info("smscore - %s(): " fmt, \ __func__, ## args) #else /*SMSCORE_DEBUG*/ #define PDEBUG(fmt, args...) @@ -157,8 +157,8 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) strcpy(entry->devpath, devpath); list_add(&entry->entry, &g_smscore_registry); } else - printk(KERN_ERR "%s failed to create smscore_registry.\n", - __func__); + sms_err("%s failed to create smscore_registry.\n", + __func__); kmutex_unlock(&g_smscore_registrylock); return entry; } @@ -171,7 +171,7 @@ int smscore_registry_getmode(char *devpath) if (entry) return entry->mode; else - printk(KERN_ERR "%s No registry found.\n", __func__); + sms_err("%s No registry found.\n", __func__); return default_mode; } @@ -184,7 +184,7 @@ enum sms_device_type_st smscore_registry_gettype(char *devpath) if (entry) return entry->type; else - printk(KERN_ERR "%s No registry found.\n", __func__); + sms_err("%s No registry found.\n", __func__); return -1; } @@ -197,7 +197,7 @@ void smscore_registry_setmode(char *devpath, int mode) if (entry) entry->mode = mode; else - printk(KERN_ERR "%s No registry found.\n", __func__); + sms_err("%s No registry found.\n", __func__); } void smscore_registry_settype(char *devpath, enum sms_device_type_st type) @@ -208,7 +208,7 @@ void smscore_registry_settype(char *devpath, enum sms_device_type_st type) if (entry) entry->type = type; else - printk(KERN_ERR "%s No registry found.\n", __func__); + sms_err("%s No registry found.\n", __func__); } @@ -331,7 +331,7 @@ struct smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, struct smscore_buffer_t *cb = kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); if (!cb) { - printk(KERN_INFO "%s kmalloc(...) failed\n", __func__); + sms_info("%s kmalloc(...) failed\n", __func__); return NULL; } @@ -360,7 +360,7 @@ int smscore_register_device(struct smsdevice_params_t *params, dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); if (!dev) { - printk(KERN_INFO "%s kzalloc(...) failed\n", __func__); + sms_info("%s kzalloc(...) failed\n", __func__); return -ENOMEM; } @@ -408,8 +408,8 @@ int smscore_register_device(struct smsdevice_params_t *params, smscore_putbuffer(dev, cb); } - printk(KERN_INFO "%s allocated %d buffers\n", - __func__, dev->num_buffers); + sms_info("%s allocated %d buffers\n", + __func__, dev->num_buffers); dev->mode = DEVICE_MODE_NONE; dev->context = params->context; @@ -432,7 +432,7 @@ int smscore_register_device(struct smsdevice_params_t *params, *coredev = dev; - printk(KERN_INFO "%s device %p created\n", __func__, dev); + sms_info("%s device %p created\n", __func__, dev); return 0; } @@ -450,8 +450,8 @@ int smscore_start_device(struct smscore_device_t *coredev) int rc = smscore_set_device_mode( coredev, smscore_registry_getmode(coredev->devpath)); if (rc < 0) { - printk(KERN_INFO "%s set device mode faile , rc %d\n", - __func__, rc); + sms_info("%s set device mode faile , rc %d\n", + __func__, rc); return rc; } @@ -459,8 +459,8 @@ int smscore_start_device(struct smscore_device_t *coredev) rc = smscore_notify_callbacks(coredev, coredev->device, 1); - printk(KERN_INFO "%s device %p started, rc %d\n", - __func__, coredev, rc); + sms_info("%s device %p started, rc %d\n", + __func__, coredev, rc); kmutex_unlock(&g_smscore_deviceslock); @@ -472,8 +472,8 @@ int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { - printk(KERN_INFO "%s sendrequest returned error %d\n", - __func__, rc); + sms_info("%s sendrequest returned error %d\n", + __func__, rc); return rc; } @@ -491,8 +491,8 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, u8 *payload = firmware->Payload; int rc = 0; - printk(KERN_INFO "%s loading FW to addr 0x%x size %d\n", - __func__, mem_address, firmware->Length); + sms_info("%s loading FW to addr 0x%x size %d\n", + __func__, mem_address, firmware->Length); if (coredev->preload_handler) { rc = coredev->preload_handler(coredev->context); if (rc < 0) @@ -578,8 +578,8 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, msleep(500); } - printk(KERN_DEBUG "%s rc=%d, postload=%p \n", __func__, rc, - coredev->postload_handler); + sms_debug("%s rc=%d, postload=%p \n", __func__, rc, + coredev->postload_handler); kfree(msg); @@ -612,12 +612,12 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, rc = request_firmware(&fw, filename, coredev->device); if (rc < 0) { - printk(KERN_INFO "%s failed to open \"%s\"\n", - __func__, filename); + sms_info("%s failed to open \"%s\"\n", + __func__, filename); return rc; } - printk(KERN_INFO "%s read FW %s, size=%d\"\n", __func__, - filename, fw->size); + sms_info("%s read FW %s, size=%d\"\n", __func__, + filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { @@ -632,8 +632,8 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, kfree(fw_buffer); } else { - printk(KERN_INFO "%s failed to allocate firmware buffer\n", - __func__); + sms_info("%s failed to allocate firmware buffer\n", + __func__); rc = -ENOMEM; } @@ -680,17 +680,17 @@ void smscore_unregister_device(struct smscore_device_t *coredev) if (num_buffers == coredev->num_buffers) break; if (++retry > 10) { - printk(KERN_INFO "%s exiting although " - "not all buffers released.\n", __func__); + sms_info("%s exiting although " + "not all buffers released.\n", __func__); break; } - printk(KERN_INFO "%s waiting for %d buffer(s)\n", __func__, - coredev->num_buffers - num_buffers); + sms_info("%s waiting for %d buffer(s)\n", __func__, + coredev->num_buffers - num_buffers); msleep(100); } - printk(KERN_INFO "%s freed %d buffers\n", __func__, num_buffers); + sms_info("%s freed %d buffers\n", __func__, num_buffers); if (coredev->common_buffer) dma_free_coherent(NULL, coredev->common_buffer_size, @@ -702,7 +702,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) kmutex_unlock(&g_smscore_deviceslock); - printk(KERN_INFO "%s device %p destroyed\n", __func__, coredev); + sms_info("%s device %p destroyed\n", __func__, coredev); } int smscore_detect_mode(struct smscore_device_t *coredev) @@ -722,8 +722,8 @@ int smscore_detect_mode(struct smscore_device_t *coredev) rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc == -ETIME) { - printk(KERN_ERR "%s: MSG_SMS_GET_VERSION_EX_REQ " - "failed first try\n", __func__); + sms_err("%s: MSG_SMS_GET_VERSION_EX_REQ " + "failed first try\n", __func__); if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) { @@ -731,9 +731,9 @@ int smscore_detect_mode(struct smscore_device_t *coredev) coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc < 0) - printk(KERN_ERR "%s: " - "MSG_SMS_GET_VERSION_EX_REQ failed " - "second try, rc %d\n", __func__, rc); + sms_err("%s: " + "MSG_SMS_GET_VERSION_EX_REQ failed " + "second try, rc %d\n", __func__, rc); } else rc = -ETIME; } @@ -783,8 +783,8 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) PDEBUG("set device mode to %d\n", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { - printk(KERN_INFO "%s invalid mode specified %d\n", - __func__, mode); + sms_info("%s invalid mode specified %d\n", + __func__, mode); return -EINVAL; } @@ -793,15 +793,15 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); if (rc < 0) { - printk(KERN_INFO "%s mode detect failed %d\n", - __func__, rc); + sms_info("%s mode detect failed %d\n", + __func__, rc); return rc; } } if (coredev->mode == mode) { - printk(KERN_INFO "%s device mode %d already set\n", - __func__, mode); + sms_info("%s device mode %d already set\n", + __func__, mode); return 0; } @@ -810,13 +810,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) rc = smscore_load_firmware_from_file( coredev, smscore_fw_lkup[mode][type], NULL); if (rc < 0) { - printk(KERN_INFO "%s load firmware " - "failed %d\n", __func__, rc); + sms_info("%s load firmware " + "failed %d\n", __func__, rc); return rc; } } else - printk(KERN_INFO "%s mode %d supported by running " - "firmware\n", __func__, mode); + sms_info("%s mode %d supported by running " + "firmware\n", __func__, mode); buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); @@ -835,14 +835,14 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) kfree(buffer); } else { - printk(KERN_INFO "%s Could not allocate buffer for " - "init device message.\n", __func__); + sms_info("%s Could not allocate buffer for " + "init device message.\n", __func__); rc = -ENOMEM; } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - printk(KERN_INFO "%s invalid mode specified %d\n", - __func__, mode); + sms_info("%s invalid mode specified %d\n", + __func__, mode); return -EINVAL; } @@ -862,7 +862,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc != 0) - printk(KERN_INFO "%s return error code %d.\n", __func__, rc); + sms_info("%s return error code %d.\n", __func__, rc); return rc; } @@ -945,9 +945,9 @@ void smscore_onresponse(struct smscore_device_t *coredev, last_sample_time = time_now; if (time_now - last_sample_time > 10000) { - printk(KERN_DEBUG "\n%s data rate %d bytes/secs\n", __func__, - (int)((data_total * 1000) / - (time_now - last_sample_time))); + sms_debug("\n%s data rate %d bytes/secs\n", __func__, + (int)((data_total * 1000) / + (time_now - last_sample_time))); last_sample_time = time_now; data_total = 0; @@ -965,10 +965,10 @@ void smscore_onresponse(struct smscore_device_t *coredev, { struct SmsVersionRes_ST *ver = (struct SmsVersionRes_ST *) phdr; - printk(KERN_DEBUG "%s: MSG_SMS_GET_VERSION_EX_RES " - "id %d prots 0x%x ver %d.%d\n", __func__, - ver->FirmwareId, ver->SupportedProtocols, - ver->RomVersionMajor, ver->RomVersionMinor); + sms_debug("%s: MSG_SMS_GET_VERSION_EX_RES " + "id %d prots 0x%x ver %d.%d\n", __func__, + ver->FirmwareId, ver->SupportedProtocols, + ver->RomVersionMajor, ver->RomVersionMinor); coredev->mode = ver->FirmwareId == 255 ? DEVICE_MODE_NONE : ver->FirmwareId; @@ -978,26 +978,25 @@ void smscore_onresponse(struct smscore_device_t *coredev, break; } case MSG_SMS_INIT_DEVICE_RES: - printk(KERN_DEBUG "%s: MSG_SMS_INIT_DEVICE_RES\n", - __func__); + sms_debug("%s: MSG_SMS_INIT_DEVICE_RES\n", + __func__); complete(&coredev->init_device_done); break; case MSG_SW_RELOAD_START_RES: - printk(KERN_DEBUG "%s: MSG_SW_RELOAD_START_RES\n", - __func__); + sms_debug("%s: MSG_SW_RELOAD_START_RES\n", + __func__); complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; case MSG_SW_RELOAD_EXEC_RES: - printk(KERN_DEBUG "%s: MSG_SW_RELOAD_EXEC_RES\n", - __func__); + sms_debug("%s: MSG_SW_RELOAD_EXEC_RES\n", + __func__); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - printk(KERN_DEBUG - "%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", - __func__); + sms_debug("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", + __func__); complete(&coredev->trigger_done); break; case MSG_SMS_SLEEP_RESUME_COMP_IND: @@ -1150,7 +1149,7 @@ void smscore_unregister_client(struct smscore_client_t *client) kfree(identry); } - printk(KERN_INFO "%s %p\n", __func__, client->context); + sms_info("%s %p\n", __func__, client->context); list_del(&client->entry); kfree(client); @@ -1177,7 +1176,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, int rc; if (client == NULL) { - printk(KERN_ERR "%s Got NULL client\n", __func__); + sms_err("%s Got NULL client\n", __func__); return -EINVAL; } @@ -1185,7 +1184,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, /* check that no other channel with same id exists */ if (coredev == NULL) { - printk(KERN_ERR "%s Got NULL coredev\n", __func__); + sms_err("%s Got NULL coredev\n", __func__); return -EINVAL; } @@ -1226,20 +1225,20 @@ int smscore_map_common_buffer(struct smscore_device_t *coredev, if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) { - printk(KERN_INFO "%s invalid vm flags\n", __func__); + sms_info("%s invalid vm flags\n", __func__); return -EINVAL; } if ((end - start) != size) { - printk(KERN_INFO "%s invalid size %d expected %d\n", - __func__, (int)(end - start), (int) size); + sms_info("%s invalid size %d expected %d\n", + __func__, (int)(end - start), (int) size); return -EINVAL; } if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) { - printk(KERN_INFO "%s remap_page_range failed\n", __func__); + sms_info("%s remap_page_range failed\n", __func__); return -EAGAIN; } @@ -1263,7 +1262,7 @@ int smscore_module_init(void) /* DVB Register */ rc = smsdvb_register(); - printk(KERN_INFO "%s, rc %d\n", __func__, rc); + sms_info("%s, rc %d\n", __func__, rc); return rc; } @@ -1299,7 +1298,7 @@ void smscore_module_exit(void) /* Unregister USB */ smsusb_unregister(); - printk(KERN_INFO "%s\n", __func__); + sms_info("%s\n", __func__); } module_init(smscore_module_init); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 1962f016612b..2799ea7bb41a 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -414,4 +414,9 @@ void smsdvb_unregister(void); int smsusb_register(void); void smsusb_unregister(void); +#define sms_err(fmt, arg...) printk(KERN_ERR fmt, ##arg) +#define sms_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) +#define sms_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg) + + #endif /* __smscoreapi_h__ */ diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 88b2bd2821dc..57ab7db56a65 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -113,8 +113,8 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - printk(KERN_DEBUG "%s add pid %d(%x)\n", __func__, - feed->pid, feed->pid); + sms_debug("%s add pid %d(%x)\n", __func__, + feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -133,8 +133,8 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - printk(KERN_DEBUG "%s remove pid %d(%x)\n", __func__, - feed->pid, feed->pid); + sms_debug("%s remove pid %d(%x)\n", __func__, + feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; PidMsg.xMsgHeader.msgDstId = HIF_TASK; @@ -220,7 +220,7 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { - printk(KERN_DEBUG "%s\n", __func__); + sms_debug("%s\n", __func__); tune->min_delay_ms = 400; tune->step_size = 250000; @@ -247,8 +247,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; - printk(KERN_DEBUG "%s freq %d band %d\n", __func__, - fep->frequency, fep->u.ofdm.bandwidth); + sms_debug("%s freq %d band %d\n", __func__, + fep->frequency, fep->u.ofdm.bandwidth); switch (fep->u.ofdm.bandwidth) { case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; @@ -268,7 +268,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - printk(KERN_DEBUG "%s\n", __func__); + sms_debug("%s\n", __func__); /* todo: */ memcpy(fep, &client->fe_params, @@ -322,14 +322,14 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, return 0; if (smscore_get_device_mode(coredev) != 4) { - printk(KERN_ERR "%sSMS Device mode is not set for " - "DVB operation.\n", __func__); + sms_err("%sSMS Device mode is not set for " + "DVB operation.\n", __func__); return 0; } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); if (!client) { - printk(KERN_INFO "%s kmalloc() failed\n", __func__); + sms_info("%s kmalloc() failed\n", __func__); return -ENOMEM; } @@ -339,8 +339,8 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, smscore_get_board_id(coredev))->name, THIS_MODULE, device, adapter_nr); if (rc < 0) { - printk(KERN_ERR "%s dvb_register_adapter() failed %d\n", - __func__, rc); + sms_err("%s dvb_register_adapter() failed %d\n", + __func__, rc); goto adapter_error; } @@ -353,8 +353,8 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_dmx_init(&client->demux); if (rc < 0) { - printk(KERN_ERR "%s dvb_dmx_init failed %d\n\n", - __func__, rc); + sms_err("%s dvb_dmx_init failed %d\n\n", + __func__, rc); goto dvbdmx_error; } @@ -365,8 +365,8 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); if (rc < 0) { - printk(KERN_ERR "%s dvb_dmxdev_init failed %d\n", - __func__, rc); + sms_err("%s dvb_dmxdev_init failed %d\n", + __func__, rc); goto dmxdev_error; } @@ -376,8 +376,8 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_register_frontend(&client->adapter, &client->frontend); if (rc < 0) { - printk(KERN_ERR "%s frontend registration failed %d\n", - __func__, rc); + sms_err("%s frontend registration failed %d\n", + __func__, rc); goto frontend_error; } @@ -389,8 +389,8 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = smscore_register_client(coredev, ¶ms, &client->smsclient); if (rc < 0) { - printk(KERN_INFO "%s smscore_register_client() failed %d\n", - __func__, rc); + sms_info("%s smscore_register_client() failed %d\n", + __func__, rc); goto client_error; } @@ -405,7 +405,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, kmutex_unlock(&g_smsdvb_clientslock); - printk(KERN_INFO "%s success\n", __func__); + sms_info("%s success\n", __func__); return 0; @@ -435,7 +435,7 @@ int smsdvb_register(void) rc = smscore_register_hotplug(smsdvb_hotplug); - printk(KERN_INFO "%s\n", __func__); + sms_info("%s\n", __func__); return rc; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index bb8a364477fb..34e60482facb 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -60,8 +60,8 @@ void smsusb_onresponse(struct urb *urb) struct smsusb_device_t *dev = surb->dev; if (urb->status < 0) { - printk(KERN_INFO "%s error, urb status %d, %d bytes\n", - __func__, urb->status, urb->actual_length); + sms_info("%s error, urb status %d, %d bytes\n", + __func__, urb->status, urb->actual_length); return; } @@ -81,12 +81,12 @@ void smsusb_onresponse(struct urb *urb) /* sanity check */ if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) { - printk(KERN_INFO "%s: invalid " - "response msglen %d offset %d " - "size %d\n", __func__, - phdr->msgLength, - surb->cb->offset, - urb->actual_length); + sms_info("%s: invalid response " + "msglen %d offset %d " + "size %d\n", __func__, + phdr->msgLength, + surb->cb->offset, + urb->actual_length); goto exit_and_resubmit; } @@ -100,9 +100,9 @@ void smsusb_onresponse(struct urb *urb) smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; } else { - printk(KERN_INFO "%s invalid response " - "msglen %d actual %d\n", __func__, - phdr->msgLength, urb->actual_length); + sms_info("%s invalid response " + "msglen %d actual %d\n", __func__, + phdr->msgLength, urb->actual_length); } } @@ -115,8 +115,8 @@ int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); if (!surb->cb) { - printk(KERN_INFO "%s smscore_getbuffer(...) " - "returned NULL\n", __func__); + sms_info("%s smscore_getbuffer(...) " + "returned NULL\n", __func__); return -ENOMEM; } } @@ -157,8 +157,8 @@ int smsusb_start_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { rc = smsusb_submit_urb(dev, &dev->surbs[i]); if (rc < 0) { - printk(KERN_INFO "%s smsusb_submit_urb(...) " - "failed\n", __func__); + sms_info("%s smsusb_submit_urb(...) " + "failed\n", __func__); smsusb_stop_streaming(dev); break; } @@ -191,15 +191,15 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) int rc, dummy; if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - printk(KERN_INFO "%s invalid firmware id specified %d\n", - __func__, id); + sms_info("%s invalid firmware id specified %d\n", + __func__, id); return -EINVAL; } rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); if (rc < 0) { - printk(KERN_INFO "%s failed to open \"%s\" mode %d\n", - __func__, smsusb1_fw_lkup[id], id); + sms_info("%s failed to open \"%s\" mode %d\n", + __func__, smsusb1_fw_lkup[id], id); return rc; } @@ -210,12 +210,12 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); - printk(KERN_INFO "%s: sent %d(%d) bytes, rc %d\n", - __func__, fw->size, dummy, rc); + sms_info("%s: sent %d(%d) bytes, rc %d\n", + __func__, fw->size, dummy, rc); kfree(fw_buffer); } else { - printk(KERN_INFO "failed to allocate firmware buffer\n"); + sms_info("failed to allocate firmware buffer\n"); rc = -ENOMEM; } @@ -233,7 +233,7 @@ void smsusb1_detectmode(void *context, int *mode) if (!product_string) { product_string = "none"; - printk(KERN_ERR "%s product string not found\n", __func__); + sms_err("%s product string not found\n", __func__); } else if (strstr(product_string, "DVBH")) *mode = 1; else if (strstr(product_string, "BDA")) @@ -243,7 +243,7 @@ void smsusb1_detectmode(void *context, int *mode) else if (strstr(product_string, "TDMB")) *mode = 2; - printk(KERN_INFO "%s: %d \"%s\"\n", __func__, *mode, product_string); + sms_info("%s: %d \"%s\"\n", __func__, *mode, product_string); } int smsusb1_setmode(void *context, int mode) @@ -252,8 +252,8 @@ int smsusb1_setmode(void *context, int mode) sizeof(struct SmsMsgHdr_ST), 0 }; if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - printk(KERN_INFO "%s invalid firmware id specified %d\n", - __func__, mode); + sms_info("%s invalid firmware id specified %d\n", + __func__, mode); return -EINVAL; } @@ -274,7 +274,7 @@ void smsusb_term_device(struct usb_interface *intf) kfree(dev); - printk(KERN_INFO "%s device %p destroyed\n", __func__, dev); + sms_info("%s device %p destroyed\n", __func__, dev); } usb_set_intfdata(intf, NULL); @@ -290,8 +290,8 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* create device object */ dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); if (!dev) { - printk(KERN_INFO "%s kzalloc(sizeof(struct smsusb_device_t) " - "failed\n", __func__); + sms_info("%s kzalloc(sizeof(struct smsusb_device_t) " + "failed\n", __func__); return -ENOMEM; } @@ -309,25 +309,25 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) params.setmode_handler = smsusb1_setmode; params.detectmode_handler = smsusb1_detectmode; params.device_type = SMS_STELLAR; - printk(KERN_INFO "%s stellar device found\n", __func__); + sms_info("%s stellar device found\n", __func__); break; default: switch (board->type) { case SMS_NOVA_A0: params.device_type = SMS_NOVA_A0; - printk(KERN_INFO "%s nova A0 found\n", __func__); + sms_info("%s nova A0 found\n", __func__); break; case SMS_NOVA_B0: params.device_type = SMS_NOVA_B0; - printk(KERN_INFO "%s nova B0 found\n", __func__); + sms_info("%s nova B0 found\n", __func__); break; case SMS_VEGA: params.device_type = SMS_VEGA; - printk(KERN_INFO "%s Vega found\n", __func__); + sms_info("%s Vega found\n", __func__); break; default: - printk(KERN_ERR "%s Unspecified sms device type!\n", - __func__); + sms_err("%s Unspecified sms device type!\n", + __func__); } dev->buffer_size = USB2_BUFFER_SIZE; @@ -350,8 +350,8 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* register in smscore */ rc = smscore_register_device(¶ms, &dev->coredev); if (rc < 0) { - printk(KERN_INFO "%s smscore_register_device(...) failed, " - "rc %d\n", __func__, rc); + sms_info("%s smscore_register_device(...) failed, " + "rc %d\n", __func__, rc); smsusb_term_device(intf); return rc; } @@ -364,24 +364,24 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) usb_init_urb(&dev->surbs[i].urb); } - printk(KERN_INFO "%s smsusb_start_streaming(...).\n", __func__); + sms_info("%s smsusb_start_streaming(...).\n", __func__); rc = smsusb_start_streaming(dev); if (rc < 0) { - printk(KERN_INFO "%s smsusb_start_streaming(...) failed\n", - __func__); + sms_info("%s smsusb_start_streaming(...) failed\n", + __func__); smsusb_term_device(intf); return rc; } rc = smscore_start_device(dev->coredev); if (rc < 0) { - printk(KERN_INFO "%s smscore_start_device(...) failed\n", - __func__); + sms_info("%s smscore_start_device(...) failed\n", + __func__); smsusb_term_device(intf); return rc; } - printk(KERN_INFO "%s device %p created\n", __func__, dev); + sms_info("%s device %p created\n", __func__, dev); return rc; } @@ -399,36 +399,36 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_set_interface( udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); if (rc < 0) { - printk(KERN_INFO "%s usb_set_interface failed, " - "rc %d\n", __func__, rc); + sms_info("%s usb_set_interface failed, " + "rc %d\n", __func__, rc); return rc; } } - printk(KERN_INFO "smsusb_probe %d\n", + sms_info("smsusb_probe %d\n", intf->cur_altsetting->desc.bInterfaceNumber); for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, + sms_info("endpoint %d %02x %02x %d\n", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); if ((udev->actconfig->desc.bNumInterfaces == 2) && (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { - printk(KERN_INFO "rom interface 0 is not used\n"); + sms_info("rom interface 0 is not used\n"); return -ENODEV; } if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { snprintf(devpath, sizeof(devpath), "usb\\%d-%s", udev->bus->busnum, udev->devpath); - printk(KERN_INFO "stellar device was found.\n"); + sms_info("stellar device was found.\n"); return smsusb1_load_firmware( udev, smscore_registry_getmode(devpath)); } rc = smsusb_init_device(intf, id->driver_info); - printk(KERN_INFO "%s rc %d\n", __func__, rc); + sms_info("%s rc %d\n", __func__, rc); return rc; } @@ -448,16 +448,16 @@ int smsusb_register(void) { int rc = usb_register(&smsusb_driver); if (rc) - printk(KERN_INFO "usb_register failed. Error number %d\n", rc); + sms_info("usb_register failed. Error number %d\n", rc); - printk(KERN_INFO "%s\n", __func__); + sms_info("%s\n", __func__); return rc; } void smsusb_unregister(void) { - printk(KERN_DEBUG "%s\n", __func__); + sms_debug("%s\n", __func__); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); } -- cgit v1.2.3 From a0c0abcb1fdb316dee3a38cff9843d7d094c327c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 20:35:21 -0300 Subject: V4L/DVB (8294): sms1xxx: move message formatting into printk macros Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 142 +++++++++++++++-------------------- drivers/media/dvb/siano/smscoreapi.h | 9 ++- drivers/media/dvb/siano/smsdvb.c | 35 ++++----- drivers/media/dvb/siano/smsusb.c | 90 +++++++++++----------- 4 files changed, 125 insertions(+), 151 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index a35513ef74a9..6e2cc3d57161 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -157,8 +157,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) strcpy(entry->devpath, devpath); list_add(&entry->entry, &g_smscore_registry); } else - sms_err("%s failed to create smscore_registry.\n", - __func__); + sms_err("failed to create smscore_registry."); kmutex_unlock(&g_smscore_registrylock); return entry; } @@ -171,7 +170,7 @@ int smscore_registry_getmode(char *devpath) if (entry) return entry->mode; else - sms_err("%s No registry found.\n", __func__); + sms_err("No registry found."); return default_mode; } @@ -184,7 +183,7 @@ enum sms_device_type_st smscore_registry_gettype(char *devpath) if (entry) return entry->type; else - sms_err("%s No registry found.\n", __func__); + sms_err("No registry found."); return -1; } @@ -197,7 +196,7 @@ void smscore_registry_setmode(char *devpath, int mode) if (entry) entry->mode = mode; else - sms_err("%s No registry found.\n", __func__); + sms_err("No registry found."); } void smscore_registry_settype(char *devpath, enum sms_device_type_st type) @@ -208,7 +207,7 @@ void smscore_registry_settype(char *devpath, enum sms_device_type_st type) if (entry) entry->type = type; else - sms_err("%s No registry found.\n", __func__); + sms_err("No registry found."); } @@ -331,7 +330,7 @@ struct smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, struct smscore_buffer_t *cb = kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); if (!cb) { - sms_info("%s kmalloc(...) failed\n", __func__); + sms_info("kmalloc(...) failed"); return NULL; } @@ -360,7 +359,7 @@ int smscore_register_device(struct smsdevice_params_t *params, dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); if (!dev) { - sms_info("%s kzalloc(...) failed\n", __func__); + sms_info("kzalloc(...) failed"); return -ENOMEM; } @@ -408,8 +407,7 @@ int smscore_register_device(struct smsdevice_params_t *params, smscore_putbuffer(dev, cb); } - sms_info("%s allocated %d buffers\n", - __func__, dev->num_buffers); + sms_info("allocated %d buffers", dev->num_buffers); dev->mode = DEVICE_MODE_NONE; dev->context = params->context; @@ -432,7 +430,7 @@ int smscore_register_device(struct smsdevice_params_t *params, *coredev = dev; - sms_info("%s device %p created\n", __func__, dev); + sms_info("device %p created", dev); return 0; } @@ -450,8 +448,7 @@ int smscore_start_device(struct smscore_device_t *coredev) int rc = smscore_set_device_mode( coredev, smscore_registry_getmode(coredev->devpath)); if (rc < 0) { - sms_info("%s set device mode faile , rc %d\n", - __func__, rc); + sms_info("set device mode faile , rc %d", rc); return rc; } @@ -459,8 +456,7 @@ int smscore_start_device(struct smscore_device_t *coredev) rc = smscore_notify_callbacks(coredev, coredev->device, 1); - sms_info("%s device %p started, rc %d\n", - __func__, coredev, rc); + sms_info("device %p started, rc %d", coredev, rc); kmutex_unlock(&g_smscore_deviceslock); @@ -472,8 +468,7 @@ int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { - sms_info("%s sendrequest returned error %d\n", - __func__, rc); + sms_info("sendrequest returned error %d", rc); return rc; } @@ -491,8 +486,8 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, u8 *payload = firmware->Payload; int rc = 0; - sms_info("%s loading FW to addr 0x%x size %d\n", - __func__, mem_address, firmware->Length); + sms_info("loading FW to addr 0x%x size %d", + mem_address, firmware->Length); if (coredev->preload_handler) { rc = coredev->preload_handler(coredev->context); if (rc < 0) @@ -505,7 +500,7 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, return -ENOMEM; if (coredev->mode != DEVICE_MODE_NONE) { - PDEBUG("Sending reload command\n"); + PDEBUG("Sending reload command"); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, @@ -578,7 +573,7 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, msleep(500); } - sms_debug("%s rc=%d, postload=%p \n", __func__, rc, + sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler); kfree(msg); @@ -612,12 +607,10 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, rc = request_firmware(&fw, filename, coredev->device); if (rc < 0) { - sms_info("%s failed to open \"%s\"\n", - __func__, filename); + sms_info("failed to open \"%s\"", filename); return rc; } - sms_info("%s read FW %s, size=%d\"\n", __func__, - filename, fw->size); + sms_info("read FW %s, size=%d\"", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { @@ -632,8 +625,7 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, kfree(fw_buffer); } else { - sms_info("%s failed to allocate firmware buffer\n", - __func__); + sms_info("failed to allocate firmware buffer"); rc = -ENOMEM; } @@ -645,7 +637,7 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, u8 *buffer, int size, int new_mode) { - PERROR("Feature not implemented yet\n"); + PERROR("Feature not implemented yet"); return -EFAULT; } @@ -680,17 +672,17 @@ void smscore_unregister_device(struct smscore_device_t *coredev) if (num_buffers == coredev->num_buffers) break; if (++retry > 10) { - sms_info("%s exiting although " - "not all buffers released.\n", __func__); + sms_info("exiting although " + "not all buffers released."); break; } - sms_info("%s waiting for %d buffer(s)\n", __func__, + sms_info("waiting for %d buffer(s)", coredev->num_buffers - num_buffers); msleep(100); } - sms_info("%s freed %d buffers\n", __func__, num_buffers); + sms_info("freed %d buffers", num_buffers); if (coredev->common_buffer) dma_free_coherent(NULL, coredev->common_buffer_size, @@ -702,7 +694,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) kmutex_unlock(&g_smscore_deviceslock); - sms_info("%s device %p destroyed\n", __func__, coredev); + sms_info("device %p destroyed", coredev); } int smscore_detect_mode(struct smscore_device_t *coredev) @@ -722,8 +714,7 @@ int smscore_detect_mode(struct smscore_device_t *coredev) rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc == -ETIME) { - sms_err("%s: MSG_SMS_GET_VERSION_EX_REQ " - "failed first try\n", __func__); + sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); if (wait_for_completion_timeout(&coredev->resume_done, msecs_to_jiffies(5000))) { @@ -731,9 +722,8 @@ int smscore_detect_mode(struct smscore_device_t *coredev) coredev, msg, msg->msgLength, &coredev->version_ex_done); if (rc < 0) - sms_err("%s: " - "MSG_SMS_GET_VERSION_EX_REQ failed " - "second try, rc %d\n", __func__, rc); + sms_err("MSG_SMS_GET_VERSION_EX_REQ failed " + "second try, rc %d", rc); } else rc = -ETIME; } @@ -780,11 +770,10 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) int rc = 0; enum sms_device_type_st type; - PDEBUG("set device mode to %d\n", mode); + PDEBUG("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { - sms_info("%s invalid mode specified %d\n", - __func__, mode); + sms_info("invalid mode specified %d", mode); return -EINVAL; } @@ -793,15 +782,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); if (rc < 0) { - sms_info("%s mode detect failed %d\n", - __func__, rc); + sms_info("mode detect failed %d", rc); return rc; } } if (coredev->mode == mode) { - sms_info("%s device mode %d already set\n", - __func__, mode); + sms_info("device mode %d already set", mode); return 0; } @@ -810,13 +797,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) rc = smscore_load_firmware_from_file( coredev, smscore_fw_lkup[mode][type], NULL); if (rc < 0) { - sms_info("%s load firmware " - "failed %d\n", __func__, rc); + sms_info("load firmware " + "failed %d", rc); return rc; } } else - sms_info("%s mode %d supported by running " - "firmware\n", __func__, mode); + sms_info("mode %d supported by running " + "firmware", mode); buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); @@ -835,14 +822,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) kfree(buffer); } else { - sms_info("%s Could not allocate buffer for " - "init device message.\n", __func__); + sms_info("Could not allocate buffer for " + "init device message."); rc = -ENOMEM; } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_info("%s invalid mode specified %d\n", - __func__, mode); + sms_info("invalid mode specified %d", mode); return -EINVAL; } @@ -862,7 +848,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc != 0) - sms_info("%s return error code %d.\n", __func__, rc); + sms_info("return error code %d.", rc); return rc; } @@ -945,7 +931,7 @@ void smscore_onresponse(struct smscore_device_t *coredev, last_sample_time = time_now; if (time_now - last_sample_time > 10000) { - sms_debug("\n%s data rate %d bytes/secs\n", __func__, + sms_debug("\ndata rate %d bytes/secs", (int)((data_total * 1000) / (time_now - last_sample_time))); @@ -965,8 +951,8 @@ void smscore_onresponse(struct smscore_device_t *coredev, { struct SmsVersionRes_ST *ver = (struct SmsVersionRes_ST *) phdr; - sms_debug("%s: MSG_SMS_GET_VERSION_EX_RES " - "id %d prots 0x%x ver %d.%d\n", __func__, + sms_debug("MSG_SMS_GET_VERSION_EX_RES " + "id %d prots 0x%x ver %d.%d", ver->FirmwareId, ver->SupportedProtocols, ver->RomVersionMajor, ver->RomVersionMinor); @@ -978,25 +964,21 @@ void smscore_onresponse(struct smscore_device_t *coredev, break; } case MSG_SMS_INIT_DEVICE_RES: - sms_debug("%s: MSG_SMS_INIT_DEVICE_RES\n", - __func__); + sms_debug("MSG_SMS_INIT_DEVICE_RES"); complete(&coredev->init_device_done); break; case MSG_SW_RELOAD_START_RES: - sms_debug("%s: MSG_SW_RELOAD_START_RES\n", - __func__); + sms_debug("MSG_SW_RELOAD_START_RES"); complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; case MSG_SW_RELOAD_EXEC_RES: - sms_debug("%s: MSG_SW_RELOAD_EXEC_RES\n", - __func__); + sms_debug("MSG_SW_RELOAD_EXEC_RES"); break; case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - sms_debug("%s: MSG_SMS_SWDOWNLOAD_TRIGGER_RES\n", - __func__); + sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); complete(&coredev->trigger_done); break; case MSG_SMS_SLEEP_RESUME_COMP_IND: @@ -1056,7 +1038,7 @@ int smscore_validate_client(struct smscore_device_t *coredev, struct smscore_client_t *registered_client; if (!client) { - PERROR("bad parameter.\n"); + PERROR("bad parameter."); return -EFAULT; } registered_client = smscore_find_client(coredev, data_type, id); @@ -1064,12 +1046,12 @@ int smscore_validate_client(struct smscore_device_t *coredev, return 0; if (registered_client) { - PERROR("The msg ID already registered to another client.\n"); + PERROR("The msg ID already registered to another client."); return -EEXIST; } listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); if (!listentry) { - PERROR("Can't allocate memory for client id.\n"); + PERROR("Can't allocate memory for client id."); return -ENOMEM; } listentry->id = id; @@ -1101,13 +1083,13 @@ int smscore_register_client(struct smscore_device_t *coredev, /* check that no other channel with same parameters exists */ if (smscore_find_client(coredev, params->data_type, params->initial_id)) { - PERROR("Client already exist.\n"); + PERROR("Client already exist."); return -EEXIST; } newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); if (!newclient) { - PERROR("Failed to allocate memory for client.\n"); + PERROR("Failed to allocate memory for client."); return -ENOMEM; } @@ -1121,7 +1103,7 @@ int smscore_register_client(struct smscore_device_t *coredev, smscore_validate_client(coredev, newclient, params->data_type, params->initial_id); *client = newclient; - PDEBUG("%p %d %d\n", params->context, params->data_type, + PDEBUG("%p %d %d", params->context, params->data_type, params->initial_id); return 0; @@ -1149,7 +1131,7 @@ void smscore_unregister_client(struct smscore_client_t *client) kfree(identry); } - sms_info("%s %p\n", __func__, client->context); + sms_info("%p", client->context); list_del(&client->entry); kfree(client); @@ -1176,7 +1158,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, int rc; if (client == NULL) { - sms_err("%s Got NULL client\n", __func__); + sms_err("Got NULL client"); return -EINVAL; } @@ -1184,7 +1166,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, /* check that no other channel with same id exists */ if (coredev == NULL) { - sms_err("%s Got NULL coredev\n", __func__); + sms_err("Got NULL coredev"); return -EINVAL; } @@ -1225,20 +1207,20 @@ int smscore_map_common_buffer(struct smscore_device_t *coredev, if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) { - sms_info("%s invalid vm flags\n", __func__); + sms_info("invalid vm flags"); return -EINVAL; } if ((end - start) != size) { - sms_info("%s invalid size %d expected %d\n", - __func__, (int)(end - start), (int) size); + sms_info("invalid size %d expected %d", + (int)(end - start), (int) size); return -EINVAL; } if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) { - sms_info("%s remap_page_range failed\n", __func__); + sms_info("remap_page_range failed"); return -EAGAIN; } @@ -1262,7 +1244,7 @@ int smscore_module_init(void) /* DVB Register */ rc = smsdvb_register(); - sms_info("%s, rc %d\n", __func__, rc); + sms_debug("rc %d", rc); return rc; } @@ -1298,7 +1280,7 @@ void smscore_module_exit(void) /* Unregister USB */ smsusb_unregister(); - sms_info("%s\n", __func__); + sms_debug(""); } module_init(smscore_module_init); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 2799ea7bb41a..ccc7e1012958 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -414,9 +414,12 @@ void smsdvb_unregister(void); int smsusb_register(void); void smsusb_unregister(void); -#define sms_err(fmt, arg...) printk(KERN_ERR fmt, ##arg) -#define sms_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) -#define sms_debug(fmt, arg...) printk(KERN_DEBUG fmt, ##arg) +#define sms_err(fmt, arg...) \ + printk(KERN_ERR "%s " fmt "\n", __func__, ##arg) +#define sms_info(fmt, arg...) \ + printk(KERN_INFO "%s " fmt "\n", __func__, ##arg) +#define sms_debug(fmt, arg...) \ + printk(KERN_DEBUG "%s " fmt "\n", __func__, ##arg) #endif /* __smscoreapi_h__ */ diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 57ab7db56a65..a54e9c77edd8 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -113,7 +113,7 @@ static int smsdvb_start_feed(struct dvb_demux_feed *feed) container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - sms_debug("%s add pid %d(%x)\n", __func__, + sms_debug("add pid %d(%x)", feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; @@ -133,7 +133,7 @@ static int smsdvb_stop_feed(struct dvb_demux_feed *feed) container_of(feed->demux, struct smsdvb_client_t, demux); struct SmsMsgData_ST PidMsg; - sms_debug("%s remove pid %d(%x)\n", __func__, + sms_debug("remove pid %d(%x)", feed->pid, feed->pid); PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; @@ -220,7 +220,7 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) static int smsdvb_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune) { - sms_debug("%s\n", __func__); + sms_debug(""); tune->min_delay_ms = 400; tune->step_size = 250000; @@ -247,7 +247,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe, Msg.Data[0] = fep->frequency; Msg.Data[2] = 12000000; - sms_debug("%s freq %d band %d\n", __func__, + sms_debug("freq %d band %d", fep->frequency, fep->u.ofdm.bandwidth); switch (fep->u.ofdm.bandwidth) { @@ -268,7 +268,7 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe, struct smsdvb_client_t *client = container_of(fe, struct smsdvb_client_t, frontend); - sms_debug("%s\n", __func__); + sms_debug(""); /* todo: */ memcpy(fep, &client->fe_params, @@ -322,14 +322,14 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, return 0; if (smscore_get_device_mode(coredev) != 4) { - sms_err("%sSMS Device mode is not set for " - "DVB operation.\n", __func__); + sms_err("SMS Device mode is not set for " + "DVB operation."); return 0; } client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); if (!client) { - sms_info("%s kmalloc() failed\n", __func__); + sms_info("kmalloc() failed"); return -ENOMEM; } @@ -339,8 +339,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, smscore_get_board_id(coredev))->name, THIS_MODULE, device, adapter_nr); if (rc < 0) { - sms_err("%s dvb_register_adapter() failed %d\n", - __func__, rc); + sms_err("dvb_register_adapter() failed %d", rc); goto adapter_error; } @@ -353,8 +352,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_dmx_init(&client->demux); if (rc < 0) { - sms_err("%s dvb_dmx_init failed %d\n\n", - __func__, rc); + sms_err("dvb_dmx_init failed %d", rc); goto dvbdmx_error; } @@ -365,8 +363,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); if (rc < 0) { - sms_err("%s dvb_dmxdev_init failed %d\n", - __func__, rc); + sms_err("dvb_dmxdev_init failed %d", rc); goto dmxdev_error; } @@ -376,8 +373,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = dvb_register_frontend(&client->adapter, &client->frontend); if (rc < 0) { - sms_err("%s frontend registration failed %d\n", - __func__, rc); + sms_err("frontend registration failed %d", rc); goto frontend_error; } @@ -389,8 +385,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = smscore_register_client(coredev, ¶ms, &client->smsclient); if (rc < 0) { - sms_info("%s smscore_register_client() failed %d\n", - __func__, rc); + sms_info("smscore_register_client() failed %d", rc); goto client_error; } @@ -405,7 +400,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, kmutex_unlock(&g_smsdvb_clientslock); - sms_info("%s success\n", __func__); + sms_info("success"); return 0; @@ -435,7 +430,7 @@ int smsdvb_register(void) rc = smscore_register_hotplug(smsdvb_hotplug); - sms_info("%s\n", __func__); + sms_debug(""); return rc; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 34e60482facb..01f5c74c41e9 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -60,8 +60,8 @@ void smsusb_onresponse(struct urb *urb) struct smsusb_device_t *dev = surb->dev; if (urb->status < 0) { - sms_info("%s error, urb status %d, %d bytes\n", - __func__, urb->status, urb->actual_length); + sms_info("error, urb status %d, %d bytes", + urb->status, urb->actual_length); return; } @@ -81,9 +81,9 @@ void smsusb_onresponse(struct urb *urb) /* sanity check */ if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) { - sms_info("%s: invalid response " + sms_info("invalid response " "msglen %d offset %d " - "size %d\n", __func__, + "size %d", phdr->msgLength, surb->cb->offset, urb->actual_length); @@ -100,8 +100,8 @@ void smsusb_onresponse(struct urb *urb) smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; } else { - sms_info("%s invalid response " - "msglen %d actual %d\n", __func__, + sms_info("invalid response " + "msglen %d actual %d", phdr->msgLength, urb->actual_length); } } @@ -115,8 +115,8 @@ int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); if (!surb->cb) { - sms_info("%s smscore_getbuffer(...) " - "returned NULL\n", __func__); + sms_info("smscore_getbuffer(...) " + "returned NULL"); return -ENOMEM; } } @@ -157,8 +157,8 @@ int smsusb_start_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { rc = smsusb_submit_urb(dev, &dev->surbs[i]); if (rc < 0) { - sms_info("%s smsusb_submit_urb(...) " - "failed\n", __func__); + sms_info("smsusb_submit_urb(...) " + "failed"); smsusb_stop_streaming(dev); break; } @@ -191,15 +191,14 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) int rc, dummy; if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - sms_info("%s invalid firmware id specified %d\n", - __func__, id); + sms_info("invalid firmware id specified %d", id); return -EINVAL; } rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); if (rc < 0) { - sms_info("%s failed to open \"%s\" mode %d\n", - __func__, smsusb1_fw_lkup[id], id); + sms_info("failed to open \"%s\" mode %d", + smsusb1_fw_lkup[id], id); return rc; } @@ -210,12 +209,11 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); - sms_info("%s: sent %d(%d) bytes, rc %d\n", - __func__, fw->size, dummy, rc); + sms_info("sent %d(%d) bytes, rc %d", fw->size, dummy, rc); kfree(fw_buffer); } else { - sms_info("failed to allocate firmware buffer\n"); + sms_info("failed to allocate firmware buffer"); rc = -ENOMEM; } @@ -233,7 +231,7 @@ void smsusb1_detectmode(void *context, int *mode) if (!product_string) { product_string = "none"; - sms_err("%s product string not found\n", __func__); + sms_err("product string not found"); } else if (strstr(product_string, "DVBH")) *mode = 1; else if (strstr(product_string, "BDA")) @@ -243,7 +241,7 @@ void smsusb1_detectmode(void *context, int *mode) else if (strstr(product_string, "TDMB")) *mode = 2; - sms_info("%s: %d \"%s\"\n", __func__, *mode, product_string); + sms_info("%d \"%s\"", *mode, product_string); } int smsusb1_setmode(void *context, int mode) @@ -252,8 +250,7 @@ int smsusb1_setmode(void *context, int mode) sizeof(struct SmsMsgHdr_ST), 0 }; if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_info("%s invalid firmware id specified %d\n", - __func__, mode); + sms_info("invalid firmware id specified %d", mode); return -EINVAL; } @@ -274,7 +271,7 @@ void smsusb_term_device(struct usb_interface *intf) kfree(dev); - sms_info("%s device %p destroyed\n", __func__, dev); + sms_info("device %p destroyed", dev); } usb_set_intfdata(intf, NULL); @@ -290,8 +287,8 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* create device object */ dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); if (!dev) { - sms_info("%s kzalloc(sizeof(struct smsusb_device_t) " - "failed\n", __func__); + sms_info("kzalloc(sizeof(struct smsusb_device_t) " + "failed"); return -ENOMEM; } @@ -309,25 +306,24 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) params.setmode_handler = smsusb1_setmode; params.detectmode_handler = smsusb1_detectmode; params.device_type = SMS_STELLAR; - sms_info("%s stellar device found\n", __func__); + sms_info("stellar device found"); break; default: switch (board->type) { case SMS_NOVA_A0: params.device_type = SMS_NOVA_A0; - sms_info("%s nova A0 found\n", __func__); + sms_info("nova A0 found"); break; case SMS_NOVA_B0: params.device_type = SMS_NOVA_B0; - sms_info("%s nova B0 found\n", __func__); + sms_info("nova B0 found"); break; case SMS_VEGA: params.device_type = SMS_VEGA; - sms_info("%s Vega found\n", __func__); + sms_info("Vega found"); break; default: - sms_err("%s Unspecified sms device type!\n", - __func__); + sms_err("Unspecified sms device type!"); } dev->buffer_size = USB2_BUFFER_SIZE; @@ -350,8 +346,8 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* register in smscore */ rc = smscore_register_device(¶ms, &dev->coredev); if (rc < 0) { - sms_info("%s smscore_register_device(...) failed, " - "rc %d\n", __func__, rc); + sms_info("smscore_register_device(...) failed, " + "rc %d", rc); smsusb_term_device(intf); return rc; } @@ -364,24 +360,22 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) usb_init_urb(&dev->surbs[i].urb); } - sms_info("%s smsusb_start_streaming(...).\n", __func__); + sms_info("smsusb_start_streaming(...)."); rc = smsusb_start_streaming(dev); if (rc < 0) { - sms_info("%s smsusb_start_streaming(...) failed\n", - __func__); + sms_info("smsusb_start_streaming(...) failed"); smsusb_term_device(intf); return rc; } rc = smscore_start_device(dev->coredev); if (rc < 0) { - sms_info("%s smscore_start_device(...) failed\n", - __func__); + sms_info("smscore_start_device(...) failed"); smsusb_term_device(intf); return rc; } - sms_info("%s device %p created\n", __func__, dev); + sms_info("device %p created", dev); return rc; } @@ -399,36 +393,36 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_set_interface( udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); if (rc < 0) { - sms_info("%s usb_set_interface failed, " - "rc %d\n", __func__, rc); + sms_info("usb_set_interface failed, " + "rc %d", rc); return rc; } } - sms_info("smsusb_probe %d\n", + sms_info("smsusb_probe %d", intf->cur_altsetting->desc.bInterfaceNumber); for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - sms_info("endpoint %d %02x %02x %d\n", i, + sms_info("endpoint %d %02x %02x %d", i, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); if ((udev->actconfig->desc.bNumInterfaces == 2) && (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { - sms_info("rom interface 0 is not used\n"); + sms_info("rom interface 0 is not used"); return -ENODEV; } if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { snprintf(devpath, sizeof(devpath), "usb\\%d-%s", udev->bus->busnum, udev->devpath); - sms_info("stellar device was found.\n"); + sms_info("stellar device was found."); return smsusb1_load_firmware( udev, smscore_registry_getmode(devpath)); } rc = smsusb_init_device(intf, id->driver_info); - sms_info("%s rc %d\n", __func__, rc); + sms_info("rc %d", rc); return rc; } @@ -448,16 +442,16 @@ int smsusb_register(void) { int rc = usb_register(&smsusb_driver); if (rc) - sms_info("usb_register failed. Error number %d\n", rc); + sms_info("usb_register failed. Error number %d", rc); - sms_info("%s\n", __func__); + sms_debug(""); return rc; } void smsusb_unregister(void) { - sms_debug("%s\n", __func__); + sms_debug(""); /* Regular USB Cleanup */ usb_deregister(&smsusb_driver); } -- cgit v1.2.3 From f14d56a99bddb779f6f7ec028bcd9d142536589e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 20:59:08 -0300 Subject: V4L/DVB (8295): sms1xxx: add debug module option, to enable debug messages All dmesg spam turned off by default, for now. Values for debug: (info=1, adv=2 (or-able) Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 4 ++++ drivers/media/dvb/siano/smscoreapi.h | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 6e2cc3d57161..402ed03be424 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -33,6 +33,10 @@ #include "smscoreapi.h" +int sms_debug; +module_param_named(debug, sms_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); + #define PERROR(fmt, args...)\ sms_err("smscore error: line %d- %s(): " fmt, \ __LINE__, __func__, ## args) diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index ccc7e1012958..a21f01f71ba4 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -414,12 +414,26 @@ void smsdvb_unregister(void); int smsusb_register(void); void smsusb_unregister(void); +/* ------------------------------------------------------------------------ */ + +extern int sms_debug; + +#define DBG_INFO 1 +#define DBG_ADV 2 + +#define sms_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt "\n", __func__, ##arg) + +#define dprintk(kern, lvl, fmt, arg...) do {\ + if (sms_debug & lvl) \ + sms_printk(kern, fmt, ##arg); } while (0) + #define sms_err(fmt, arg...) \ - printk(KERN_ERR "%s " fmt "\n", __func__, ##arg) + sms_printk(KERN_ERR, "%s " fmt "\n", __func__, ##arg) #define sms_info(fmt, arg...) \ - printk(KERN_INFO "%s " fmt "\n", __func__, ##arg) + dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) #define sms_debug(fmt, arg...) \ - printk(KERN_DEBUG "%s " fmt "\n", __func__, ##arg) + dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) #endif /* __smscoreapi_h__ */ -- cgit v1.2.3 From eb250942fe3cf2a129ab55d65161bc66b7009853 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 22:07:23 -0300 Subject: V4L/DVB (8296): sms1xxx: always show error messages Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 21 +++++++------- drivers/media/dvb/siano/smsdvb.c | 4 +-- drivers/media/dvb/siano/smsusb.c | 55 ++++++++++++++++-------------------- 3 files changed, 37 insertions(+), 43 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 402ed03be424..6685c56ee0e5 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -777,7 +777,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) PDEBUG("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { - sms_info("invalid mode specified %d", mode); + sms_err("invalid mode specified %d", mode); return -EINVAL; } @@ -786,7 +786,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { rc = smscore_detect_mode(coredev); if (rc < 0) { - sms_info("mode detect failed %d", rc); + sms_err("mode detect failed %d", rc); return rc; } } @@ -801,8 +801,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) rc = smscore_load_firmware_from_file( coredev, smscore_fw_lkup[mode][type], NULL); if (rc < 0) { - sms_info("load firmware " - "failed %d", rc); + sms_err("load firmware failed %d", rc); return rc; } } else @@ -826,13 +825,13 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) kfree(buffer); } else { - sms_info("Could not allocate buffer for " - "init device message."); + sms_err("Could not allocate buffer for " + "init device message."); rc = -ENOMEM; } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_info("invalid mode specified %d", mode); + sms_err("invalid mode specified %d", mode); return -EINVAL; } @@ -852,7 +851,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc != 0) - sms_info("return error code %d.", rc); + sms_err("return error code %d.", rc); return rc; } @@ -1211,12 +1210,12 @@ int smscore_map_common_buffer(struct smscore_device_t *coredev, if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || (vma->vm_flags & VM_WRITE)) { - sms_info("invalid vm flags"); + sms_err("invalid vm flags"); return -EINVAL; } if ((end - start) != size) { - sms_info("invalid size %d expected %d", + sms_err("invalid size %d expected %d", (int)(end - start), (int) size); return -EINVAL; } @@ -1224,7 +1223,7 @@ int smscore_map_common_buffer(struct smscore_device_t *coredev, if (remap_pfn_range(vma, start, coredev->common_buffer_phys >> PAGE_SHIFT, size, pgprot_noncached(vma->vm_page_prot))) { - sms_info("remap_page_range failed"); + sms_err("remap_page_range failed"); return -EAGAIN; } diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index a54e9c77edd8..f9a6ce0441f7 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -329,7 +329,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); if (!client) { - sms_info("kmalloc() failed"); + sms_err("kmalloc() failed"); return -ENOMEM; } @@ -385,7 +385,7 @@ int smsdvb_hotplug(struct smscore_device_t *coredev, rc = smscore_register_client(coredev, ¶ms, &client->smsclient); if (rc < 0) { - sms_info("smscore_register_client() failed %d", rc); + sms_err("smscore_register_client() failed %d", rc); goto client_error; } diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 01f5c74c41e9..221b024e9d83 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -60,8 +60,8 @@ void smsusb_onresponse(struct urb *urb) struct smsusb_device_t *dev = surb->dev; if (urb->status < 0) { - sms_info("error, urb status %d, %d bytes", - urb->status, urb->actual_length); + sms_err("error, urb status %d, %d bytes", + urb->status, urb->actual_length); return; } @@ -81,12 +81,12 @@ void smsusb_onresponse(struct urb *urb) /* sanity check */ if (((int) phdr->msgLength + surb->cb->offset) > urb->actual_length) { - sms_info("invalid response " - "msglen %d offset %d " - "size %d", - phdr->msgLength, - surb->cb->offset, - urb->actual_length); + sms_err("invalid response " + "msglen %d offset %d " + "size %d", + phdr->msgLength, + surb->cb->offset, + urb->actual_length); goto exit_and_resubmit; } @@ -100,9 +100,9 @@ void smsusb_onresponse(struct urb *urb) smscore_onresponse(dev->coredev, surb->cb); surb->cb = NULL; } else { - sms_info("invalid response " - "msglen %d actual %d", - phdr->msgLength, urb->actual_length); + sms_err("invalid response " + "msglen %d actual %d", + phdr->msgLength, urb->actual_length); } } @@ -115,8 +115,7 @@ int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); if (!surb->cb) { - sms_info("smscore_getbuffer(...) " - "returned NULL"); + sms_err("smscore_getbuffer(...) returned NULL"); return -ENOMEM; } } @@ -157,8 +156,7 @@ int smsusb_start_streaming(struct smsusb_device_t *dev) for (i = 0; i < MAX_URBS; i++) { rc = smsusb_submit_urb(dev, &dev->surbs[i]); if (rc < 0) { - sms_info("smsusb_submit_urb(...) " - "failed"); + sms_err("smsusb_submit_urb(...) failed"); smsusb_stop_streaming(dev); break; } @@ -191,14 +189,14 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) int rc, dummy; if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - sms_info("invalid firmware id specified %d", id); + sms_err("invalid firmware id specified %d", id); return -EINVAL; } rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); if (rc < 0) { - sms_info("failed to open \"%s\" mode %d", - smsusb1_fw_lkup[id], id); + sms_err("failed to open \"%s\" mode %d", + smsusb1_fw_lkup[id], id); return rc; } @@ -213,7 +211,7 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) kfree(fw_buffer); } else { - sms_info("failed to allocate firmware buffer"); + sms_err("failed to allocate firmware buffer"); rc = -ENOMEM; } @@ -250,7 +248,7 @@ int smsusb1_setmode(void *context, int mode) sizeof(struct SmsMsgHdr_ST), 0 }; if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_info("invalid firmware id specified %d", mode); + sms_err("invalid firmware id specified %d", mode); return -EINVAL; } @@ -287,8 +285,7 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* create device object */ dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); if (!dev) { - sms_info("kzalloc(sizeof(struct smsusb_device_t) " - "failed"); + sms_err("kzalloc(sizeof(struct smsusb_device_t) failed"); return -ENOMEM; } @@ -346,8 +343,7 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) /* register in smscore */ rc = smscore_register_device(¶ms, &dev->coredev); if (rc < 0) { - sms_info("smscore_register_device(...) failed, " - "rc %d", rc); + sms_err("smscore_register_device(...) failed, rc %d", rc); smsusb_term_device(intf); return rc; } @@ -363,14 +359,14 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) sms_info("smsusb_start_streaming(...)."); rc = smsusb_start_streaming(dev); if (rc < 0) { - sms_info("smsusb_start_streaming(...) failed"); + sms_err("smsusb_start_streaming(...) failed"); smsusb_term_device(intf); return rc; } rc = smscore_start_device(dev->coredev); if (rc < 0) { - sms_info("smscore_start_device(...) failed"); + sms_err("smscore_start_device(...) failed"); smsusb_term_device(intf); return rc; } @@ -393,8 +389,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) rc = usb_set_interface( udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); if (rc < 0) { - sms_info("usb_set_interface failed, " - "rc %d", rc); + sms_err("usb_set_interface failed, rc %d", rc); return rc; } } @@ -409,7 +404,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) if ((udev->actconfig->desc.bNumInterfaces == 2) && (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { - sms_info("rom interface 0 is not used"); + sms_err("rom interface 0 is not used"); return -ENODEV; } @@ -442,7 +437,7 @@ int smsusb_register(void) { int rc = usb_register(&smsusb_driver); if (rc) - sms_info("usb_register failed. Error number %d", rc); + sms_err("usb_register failed. Error number %d", rc); sms_debug(""); -- cgit v1.2.3 From 2522dc13245073f75399ada8e7f6acecde834953 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 22:15:38 -0300 Subject: V4L/DVB (8297): sms1xxx: remove old printk macros Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 37 ++++++++++-------------------------- drivers/media/dvb/siano/smscoreapi.h | 6 +++++- 2 files changed, 15 insertions(+), 28 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 6685c56ee0e5..142fe00c37fc 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -37,23 +37,6 @@ int sms_debug; module_param_named(debug, sms_debug, int, 0644); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); -#define PERROR(fmt, args...)\ - sms_err("smscore error: line %d- %s(): " fmt, \ - __LINE__, __func__, ## args) - -#ifdef SMSCORE_DEBUG -#undef PWARNING -# define PWARNING(fmt, args...) sms_info("smscore warning: " \ - "line %d- %s(): " fmt, \ - __LINE__, __func__, ## args) -#undef PDEBUG /* undef it, just in case */ -# define PDEBUG(fmt, args...) sms_info("smscore - %s(): " fmt, \ - __func__, ## args) -#else /*SMSCORE_DEBUG*/ -#define PDEBUG(fmt, args...) -#define PWARNING(fmt, args...) -#endif - struct smscore_device_notifyee_t { struct list_head entry; hotplug_t hotplug; @@ -504,7 +487,7 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, return -ENOMEM; if (coredev->mode != DEVICE_MODE_NONE) { - PDEBUG("Sending reload command"); + sms_debug("sending reload command."); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, @@ -641,7 +624,7 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, u8 *buffer, int size, int new_mode) { - PERROR("Feature not implemented yet"); + sms_err("feature not yet implemented."); return -EFAULT; } @@ -774,7 +757,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) int rc = 0; enum sms_device_type_st type; - PDEBUG("set device mode to %d", mode); + sms_debug("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { sms_err("invalid mode specified %d", mode); @@ -1041,7 +1024,7 @@ int smscore_validate_client(struct smscore_device_t *coredev, struct smscore_client_t *registered_client; if (!client) { - PERROR("bad parameter."); + sms_err("bad parameter."); return -EFAULT; } registered_client = smscore_find_client(coredev, data_type, id); @@ -1049,12 +1032,12 @@ int smscore_validate_client(struct smscore_device_t *coredev, return 0; if (registered_client) { - PERROR("The msg ID already registered to another client."); + sms_err("The msg ID already registered to another client."); return -EEXIST; } listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); if (!listentry) { - PERROR("Can't allocate memory for client id."); + sms_err("Can't allocate memory for client id."); return -ENOMEM; } listentry->id = id; @@ -1086,13 +1069,13 @@ int smscore_register_client(struct smscore_device_t *coredev, /* check that no other channel with same parameters exists */ if (smscore_find_client(coredev, params->data_type, params->initial_id)) { - PERROR("Client already exist."); + sms_err("Client already exist."); return -EEXIST; } newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); if (!newclient) { - PERROR("Failed to allocate memory for client."); + sms_err("Failed to allocate memory for client."); return -ENOMEM; } @@ -1106,8 +1089,8 @@ int smscore_register_client(struct smscore_device_t *coredev, smscore_validate_client(coredev, newclient, params->data_type, params->initial_id); *client = newclient; - PDEBUG("%p %d %d", params->context, params->data_type, - params->initial_id); + sms_debug("%p %d %d", params->context, params->data_type, + params->initial_id); return 0; } diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index a21f01f71ba4..b84606b30fd8 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -429,7 +429,11 @@ extern int sms_debug; sms_printk(kern, fmt, ##arg); } while (0) #define sms_err(fmt, arg...) \ - sms_printk(KERN_ERR, "%s " fmt "\n", __func__, ##arg) + sms_printk(KERN_ERR, "%s() line: %d: " fmt "\n", \ + __func__, __LINE__, ##arg) +#define sms_warn(fmt, arg...) \ + sms_printk(KERN_WARNING, "%s() line: %d: " fmt "\n", \ + __func__, __LINE__, ##arg) #define sms_info(fmt, arg...) \ dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) #define sms_debug(fmt, arg...) \ -- cgit v1.2.3 From c65c7a652ff10b86d33eda36f9c4200027bd8dd4 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 19 Jun 2008 22:20:49 -0300 Subject: V4L/DVB (8298): sms1xxx: remove redundant __func__ in sms_err macro Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index b84606b30fd8..eb0ed6542e94 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -429,11 +429,9 @@ extern int sms_debug; sms_printk(kern, fmt, ##arg); } while (0) #define sms_err(fmt, arg...) \ - sms_printk(KERN_ERR, "%s() line: %d: " fmt "\n", \ - __func__, __LINE__, ##arg) + sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) #define sms_warn(fmt, arg...) \ - sms_printk(KERN_WARNING, "%s() line: %d: " fmt "\n", \ - __func__, __LINE__, ##arg) + sms_printk(KERN_WARNING, "line: %d: " fmt, __LINE__, ##arg) #define sms_info(fmt, arg...) \ dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) #define sms_debug(fmt, arg...) \ -- cgit v1.2.3 From 0c071f374f66f05aded3be970f683d54fd918806 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 21 Jun 2008 02:44:02 -0300 Subject: V4L/DVB (8299): sms1xxx: mark functions static Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 101 +++++++++-------------------------- drivers/media/dvb/siano/smscoreapi.h | 7 --- drivers/media/dvb/siano/smsdvb.c | 10 ++-- drivers/media/dvb/siano/smsusb.c | 31 ++++++----- 4 files changed, 47 insertions(+), 102 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 142fe00c37fc..bbb3ad9c804a 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -162,7 +162,7 @@ int smscore_registry_getmode(char *devpath) return default_mode; } -enum sms_device_type_st smscore_registry_gettype(char *devpath) +static enum sms_device_type_st smscore_registry_gettype(char *devpath) { struct smscore_registry_entry_t *entry; @@ -186,7 +186,8 @@ void smscore_registry_setmode(char *devpath, int mode) sms_err("No registry found."); } -void smscore_registry_settype(char *devpath, enum sms_device_type_st type) +static void smscore_registry_settype(char *devpath, + enum sms_device_type_st type) { struct smscore_registry_entry_t *entry; @@ -198,8 +199,8 @@ void smscore_registry_settype(char *devpath, enum sms_device_type_st type) } -void list_add_locked(struct list_head *new, struct list_head *head, - spinlock_t *lock) +static void list_add_locked(struct list_head *new, struct list_head *head, + spinlock_t *lock) { unsigned long flags; @@ -280,7 +281,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug) kmutex_unlock(&g_smscore_deviceslock); } -void smscore_notify_clients(struct smscore_device_t *coredev) +static void smscore_notify_clients(struct smscore_device_t *coredev) { struct smscore_client_t *client; @@ -291,8 +292,8 @@ void smscore_notify_clients(struct smscore_device_t *coredev) } } -int smscore_notify_callbacks(struct smscore_device_t *coredev, - struct device *device, int arrival) +static int smscore_notify_callbacks(struct smscore_device_t *coredev, + struct device *device, int arrival) { struct list_head *next, *first; int rc = 0; @@ -311,7 +312,8 @@ int smscore_notify_callbacks(struct smscore_device_t *coredev, return rc; } -struct smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, +static struct +smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, dma_addr_t common_buffer_phys) { struct smscore_buffer_t *cb = @@ -450,8 +452,9 @@ int smscore_start_device(struct smscore_device_t *coredev) return rc; } -int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, - size_t size, struct completion *completion) +static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, + void *buffer, size_t size, + struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { @@ -464,8 +467,8 @@ int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, 0 : -ETIME; } -int smscore_load_firmware_family2(struct smscore_device_t *coredev, - void *buffer, size_t size) +static int smscore_load_firmware_family2(struct smscore_device_t *coredev, + void *buffer, size_t size) { struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; struct SmsMsgHdr_ST *msg; @@ -580,9 +583,9 @@ int smscore_load_firmware_family2(struct smscore_device_t *coredev, * * @return 0 on success, <0 on error. */ -int smscore_load_firmware_from_file(struct smscore_device_t *coredev, - char *filename, - loadfirmware_t loadfirmware_handler) +static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, + char *filename, + loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; const struct firmware *fw; @@ -621,13 +624,6 @@ int smscore_load_firmware_from_file(struct smscore_device_t *coredev, return rc; } -int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, - u8 *buffer, int size, int new_mode) -{ - sms_err("feature not yet implemented."); - return -EFAULT; -} - /** * notifies all clients registered with the device, notifies hotplugs, * frees all buffers and coredev object @@ -684,7 +680,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("device %p destroyed", coredev); } -int smscore_detect_mode(struct smscore_device_t *coredev) +static int smscore_detect_mode(struct smscore_device_t *coredev) { void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); @@ -720,7 +716,7 @@ int smscore_detect_mode(struct smscore_device_t *coredev) return rc; } -char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { +static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*Stellar NOVA A0 Nova B0 VEGA*/ /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, @@ -861,7 +857,8 @@ int smscore_get_device_mode(struct smscore_device_t *coredev) * @param id client id (SMS_DONT_CARE for all id) * */ -struct smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, +static struct +smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, int data_type, int id) { struct smscore_client_t *client = NULL; @@ -1016,9 +1013,9 @@ void smscore_putbuffer(struct smscore_device_t *coredev, list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } -int smscore_validate_client(struct smscore_device_t *coredev, - struct smscore_client_t *client, - int data_type, int id) +static int smscore_validate_client(struct smscore_device_t *coredev, + struct smscore_client_t *client, + int data_type, int id) { struct smscore_idlist_t *listentry; struct smscore_client_t *registered_client; @@ -1164,54 +1161,6 @@ int smsclient_sendrequest(struct smscore_client_t *client, return coredev->sendrequest_handler(coredev->context, buffer, size); } -/** - * return the size of large (common) buffer - * - * @param coredev pointer to a coredev object from clients hotplug - * - * @return size (in bytes) of the buffer - */ -int smscore_get_common_buffer_size(struct smscore_device_t *coredev) -{ - return coredev->common_buffer_size; -} - -/** - * maps common buffer (if supported by platform) - * - * @param coredev pointer to a coredev object from clients hotplug - * @param vma pointer to vma struct from mmap handler - * - * @return 0 on success, <0 on error. - */ -int smscore_map_common_buffer(struct smscore_device_t *coredev, - struct vm_area_struct *vma) -{ - unsigned long end = vma->vm_end, - start = vma->vm_start, - size = PAGE_ALIGN(coredev->common_buffer_size); - - if (!(vma->vm_flags & (VM_READ | VM_SHARED)) || - (vma->vm_flags & VM_WRITE)) { - sms_err("invalid vm flags"); - return -EINVAL; - } - - if ((end - start) != size) { - sms_err("invalid size %d expected %d", - (int)(end - start), (int) size); - return -EINVAL; - } - - if (remap_pfn_range(vma, start, - coredev->common_buffer_phys >> PAGE_SHIFT, - size, pgprot_noncached(vma->vm_page_prot))) { - sms_err("remap_page_range failed"); - return -EAGAIN; - } - - return 0; -} int smscore_module_init(void) { diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index eb0ed6542e94..3e4e7dbc54da 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -378,10 +378,6 @@ extern int smscore_load_firmware(struct smscore_device_t *coredev, char *filename, loadfirmware_t loadfirmware_handler); -extern int smscore_load_firmware_from_buffer(struct smscore_device_t *coredev, - u8 *buffer, int size, - int new_mode); - extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); extern int smscore_get_device_mode(struct smscore_device_t *coredev); @@ -395,9 +391,6 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); -extern int smscore_map_common_buffer(struct smscore_device_t *coredev, - struct vm_area_struct *vma); extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); extern void smscore_putbuffer(struct smscore_device_t *coredev, diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index f9a6ce0441f7..61c06b770c6c 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -30,7 +30,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct list_head g_smsdvb_clients; kmutex_t g_smsdvb_clientslock; -int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) +static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; struct SmsMsgHdr_ST *phdr = @@ -84,7 +84,7 @@ int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) return 0; } -void smsdvb_unregister_client(struct smsdvb_client_t *client) +static void smsdvb_unregister_client(struct smsdvb_client_t *client) { /* must be called under clientslock */ @@ -98,7 +98,7 @@ void smsdvb_unregister_client(struct smsdvb_client_t *client) kfree(client); } -void smsdvb_onremove(void *context) +static void smsdvb_onremove(void *context) { kmutex_lock(&g_smsdvb_clientslock); @@ -310,8 +310,8 @@ static struct dvb_frontend_ops smsdvb_fe_ops = { .read_snr = smsdvb_read_snr, }; -int smsdvb_hotplug(struct smscore_device_t *coredev, - struct device *device, int arrival) +static int smsdvb_hotplug(struct smscore_device_t *coredev, + struct device *device, int arrival) { struct smsclient_params_t params; struct smsdvb_client_t *client; diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 221b024e9d83..e6ee4434a294 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -52,9 +52,10 @@ struct smsusb_device_t { int buffer_size; }; -int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb); +static int smsusb_submit_urb(struct smsusb_device_t *dev, + struct smsusb_urb_t *surb); -void smsusb_onresponse(struct urb *urb) +static void smsusb_onresponse(struct urb *urb) { struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; struct smsusb_device_t *dev = surb->dev; @@ -110,7 +111,8 @@ exit_and_resubmit: smsusb_submit_urb(dev, surb); } -int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) +static int smsusb_submit_urb(struct smsusb_device_t *dev, + struct smsusb_urb_t *surb) { if (!surb->cb) { surb->cb = smscore_getbuffer(dev->coredev); @@ -135,7 +137,7 @@ int smsusb_submit_urb(struct smsusb_device_t *dev, struct smsusb_urb_t *surb) return usb_submit_urb(&surb->urb, GFP_ATOMIC); } -void smsusb_stop_streaming(struct smsusb_device_t *dev) +static void smsusb_stop_streaming(struct smsusb_device_t *dev) { int i; @@ -149,7 +151,7 @@ void smsusb_stop_streaming(struct smsusb_device_t *dev) } } -int smsusb_start_streaming(struct smsusb_device_t *dev) +static int smsusb_start_streaming(struct smsusb_device_t *dev) { int i, rc; @@ -165,7 +167,7 @@ int smsusb_start_streaming(struct smsusb_device_t *dev) return rc; } -int smsusb_sendrequest(void *context, void *buffer, size_t size) +static int smsusb_sendrequest(void *context, void *buffer, size_t size) { struct smsusb_device_t *dev = (struct smsusb_device_t *) context; int dummy; @@ -174,7 +176,7 @@ int smsusb_sendrequest(void *context, void *buffer, size_t size) buffer, size, &dummy, 1000); } -char *smsusb1_fw_lkup[] = { +static char *smsusb1_fw_lkup[] = { "dvbt_stellar_usb.inp", "dvbh_stellar_usb.inp", "tdmb_stellar_usb.inp", @@ -182,7 +184,7 @@ char *smsusb1_fw_lkup[] = { "dvbt_bda_stellar_usb.inp", }; -int smsusb1_load_firmware(struct usb_device *udev, int id) +static int smsusb1_load_firmware(struct usb_device *udev, int id) { const struct firmware *fw; u8 *fw_buffer; @@ -220,7 +222,7 @@ int smsusb1_load_firmware(struct usb_device *udev, int id) return rc; } -void smsusb1_detectmode(void *context, int *mode) +static void smsusb1_detectmode(void *context, int *mode) { char *product_string = ((struct smsusb_device_t *) context)->udev->product; @@ -242,7 +244,7 @@ void smsusb1_detectmode(void *context, int *mode) sms_info("%d \"%s\"", *mode, product_string); } -int smsusb1_setmode(void *context, int mode) +static int smsusb1_setmode(void *context, int mode) { struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; @@ -255,7 +257,7 @@ int smsusb1_setmode(void *context, int mode) return smsusb_sendrequest(context, &Msg, sizeof(Msg)); } -void smsusb_term_device(struct usb_interface *intf) +static void smsusb_term_device(struct usb_interface *intf) { struct smsusb_device_t *dev = (struct smsusb_device_t *) usb_get_intfdata(intf); @@ -275,7 +277,7 @@ void smsusb_term_device(struct usb_interface *intf) usb_set_intfdata(intf, NULL); } -int smsusb_init_device(struct usb_interface *intf, int board_id) +static int smsusb_init_device(struct usb_interface *intf, int board_id) { struct smsdevice_params_t params; struct smsusb_device_t *dev; @@ -376,7 +378,8 @@ int smsusb_init_device(struct usb_interface *intf, int board_id) return rc; } -int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int smsusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); char devpath[32]; @@ -421,7 +424,7 @@ int smsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) return rc; } -void smsusb_disconnect(struct usb_interface *intf) +static void smsusb_disconnect(struct usb_interface *intf) { smsusb_term_device(intf); } -- cgit v1.2.3 From 2708e888c57904f78649dcd91dcda9768d580ecf Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 21 Jun 2008 05:24:38 -0300 Subject: V4L/DVB (8300): sms1xxx: simplify smsusb_init_device switch..case block Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index e6ee4434a294..e7e0fe735427 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -281,7 +281,6 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) { struct smsdevice_params_t params; struct smsusb_device_t *dev; - struct sms_board *board; int i, rc; /* create device object */ @@ -295,36 +294,21 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) usb_set_intfdata(intf, dev); dev->udev = interface_to_usbdev(intf); - board = sms_get_board(board_id); - - switch (board->type) { + params.device_type = sms_get_board(board_id)->type; + switch (params.device_type) { case SMS_STELLAR: dev->buffer_size = USB1_BUFFER_SIZE; params.setmode_handler = smsusb1_setmode; params.detectmode_handler = smsusb1_detectmode; - params.device_type = SMS_STELLAR; - sms_info("stellar device found"); break; default: - switch (board->type) { - case SMS_NOVA_A0: - params.device_type = SMS_NOVA_A0; - sms_info("nova A0 found"); - break; - case SMS_NOVA_B0: - params.device_type = SMS_NOVA_B0; - sms_info("nova B0 found"); - break; - case SMS_VEGA: - params.device_type = SMS_VEGA; - sms_info("Vega found"); - break; - default: - sms_err("Unspecified sms device type!"); - } - + sms_err("Unspecified sms device type!"); + /* fall-thru */ + case SMS_NOVA_A0: + case SMS_NOVA_B0: + case SMS_VEGA: dev->buffer_size = USB2_BUFFER_SIZE; dev->response_alignment = dev->udev->ep_in[1]->desc.wMaxPacketSize - -- cgit v1.2.3 From 02aea4fb640cdc4018e0a6d34e235eb63e4482d7 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Thu, 26 Jun 2008 04:58:30 -0300 Subject: V4L/DVB (8301): sms1xxx: add capability to define device-specific firmware filenames Add the capability to define device-specific firmware filenames for the SMS1150, with a mechanism to fall back to the generic firmware if the device-specific firmware is not present. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.h | 2 +- drivers/media/dvb/siano/smscoreapi.c | 31 ++++++++++++++++++++++++++----- drivers/media/dvb/siano/smsusb.c | 1 + 3 files changed, 28 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 7ba3df63dffe..9e93f0b5b231 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -31,8 +31,8 @@ #define SMS1XXX_BOARD_SIANO_VEGA 5 struct sms_board { - char *name; enum sms_device_type_st type; + char *name, *fw[DEVICE_MODE_MAX]; }; struct sms_board *sms_get_board(int id); diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index bbb3ad9c804a..eaa7cf22715b 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -32,6 +32,7 @@ #include #include "smscoreapi.h" +#include "sms-cards.h" int sms_debug; module_param_named(debug, sms_debug, int, 0644); @@ -600,7 +601,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, sms_info("failed to open \"%s\"", filename); return rc; } - sms_info("read FW %s, size=%d\"", filename, fw->size); + sms_info("read FW %s, size=%d", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { @@ -736,6 +737,12 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; +static inline char *sms_get_fw_name(struct smscore_device_t *coredev, + int mode, enum sms_device_type_st type) +{ + char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; + return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; +} /** * calls device handler to change mode of operation @@ -776,12 +783,26 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (!(coredev->modes_supported & (1 << mode))) { + char *fw_filename; + type = smscore_registry_gettype(coredev->devpath); - rc = smscore_load_firmware_from_file( - coredev, smscore_fw_lkup[mode][type], NULL); + fw_filename = sms_get_fw_name(coredev, mode, type); + + rc = smscore_load_firmware_from_file(coredev, + fw_filename, NULL); if (rc < 0) { - sms_err("load firmware failed %d", rc); - return rc; + sms_err("error %d loading firmware: %s, " + "trying again with default firmware", + rc, fw_filename); + + /* try again with the default firmware */ + rc = smscore_load_firmware_from_file(coredev, + smscore_fw_lkup[mode][type], NULL); + + if (rc < 0) { + sms_err("load firmware failed %d", rc); + return rc; + } } } else sms_info("mode %d supported by running " diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index e7e0fe735427..f85210f2bd0d 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -216,6 +216,7 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id) sms_err("failed to allocate firmware buffer"); rc = -ENOMEM; } + sms_info("read FW %s, size=%d", smsusb1_fw_lkup[id], fw->size); release_firmware(fw); -- cgit v1.2.3 From cf1cfe1ba70952093a46bb0e21b58357f36f2e8f Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 16:45:36 -0300 Subject: V4L/DVB (8302): sms1xxx: fix Siano board names Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 12 ++++-------- drivers/media/dvb/siano/sms-cards.h | 9 ++++----- 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 88fc2a4edc1e..6a22ec10fe20 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -38,24 +38,20 @@ static struct sms_board sms_boards[] = { [SMS_BOARD_UNKNOWN] = { .name = "Unknown board", }, - [SMS1XXX_BOARD_SIANO_SMS1000] = { - .name = "Siano Digital Receiver", - .type = SMS_STELLAR, - }, [SMS1XXX_BOARD_SIANO_STELLAR] = { - .name = "Siano Stellar reference board", + .name = "Siano Stellar Digital Receiver", .type = SMS_STELLAR, }, [SMS1XXX_BOARD_SIANO_NOVA_A] = { - .name = "Siano Nova A reference board", + .name = "Siano Nova A Digital Receiver", .type = SMS_NOVA_A0, }, [SMS1XXX_BOARD_SIANO_NOVA_B] = { - .name = "Siano Nova B reference board", + .name = "Siano Nova B Digital Receiver", .type = SMS_NOVA_B0, }, [SMS1XXX_BOARD_SIANO_VEGA] = { - .name = "Siano Vega reference board", + .name = "Siano Vega Digital Receiver", .type = SMS_VEGA, }, }; diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 9e93f0b5b231..262e3ffbc29c 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -24,11 +24,10 @@ #include "smscoreapi.h" #define SMS_BOARD_UNKNOWN 0 -#define SMS1XXX_BOARD_SIANO_SMS1000 1 -#define SMS1XXX_BOARD_SIANO_STELLAR 2 -#define SMS1XXX_BOARD_SIANO_NOVA_A 3 -#define SMS1XXX_BOARD_SIANO_NOVA_B 4 -#define SMS1XXX_BOARD_SIANO_VEGA 5 +#define SMS1XXX_BOARD_SIANO_STELLAR 1 +#define SMS1XXX_BOARD_SIANO_NOVA_A 2 +#define SMS1XXX_BOARD_SIANO_NOVA_B 3 +#define SMS1XXX_BOARD_SIANO_VEGA 4 struct sms_board { enum sms_device_type_st type; -- cgit v1.2.3 From 8f37356b065206316e0b66dbee2718c82329684c Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 17:09:28 -0300 Subject: V4L/DVB (8303): sms1xxx: update MODULE_DESCRIPTION set MODULE_DESCRIPTION to "Driver for the Siano SMS1XXX USB dongle" Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- drivers/media/dvb/siano/smsdvb.c | 2 +- drivers/media/dvb/siano/smsusb.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index eaa7cf22715b..14475c8a7222 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1242,6 +1242,6 @@ void smscore_module_exit(void) module_init(smscore_module_init); module_exit(smscore_module_exit); -MODULE_DESCRIPTION("smscore"); +MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 61c06b770c6c..72d1de7a6dea 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -1,5 +1,5 @@ /* - * Driver for the Siano SMS10xx USB dongle + * Driver for the Siano SMS1xxx USB dongle * * author: Anatoly Greenblat * diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index f85210f2bd0d..0f9f5d585e37 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -1,5 +1,5 @@ /* - * Driver for the Siano SMS10xx USB dongle + * Driver for the Siano SMS1xxx USB dongle * * author: Anatoly Greenblat * -- cgit v1.2.3 From 0f2a1ee112a4709a3b1a3c3c64b5d11752da1eef Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 20:53:45 -0300 Subject: V4L/DVB (8305): sms1xxx: fix warning: format '%d' expects type 'int', but argument x has type 'size_t' Fix the following 64bit build warning: make[2]: Entering directory `/usr/src/linux-headers-2.6.24-16-generic' CC [M] smscoreapi.o smscoreapi.c: In function 'smscore_load_firmware_from_file': smscoreapi.c:604: warning: format '%d' expects type 'int', but argument 4 has type 'size_t' CC [M] smsusb.o smsusb.c: In function 'smsusb1_load_firmware': smsusb.c:216: warning: format '%d' expects type 'int', but argument 3 has type 'size_t' smsusb.c:223: warning: format '%d' expects type 'int', but argument 4 has type 'size_t' Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- drivers/media/dvb/siano/smsusb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 14475c8a7222..c54c7180e39e 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -601,7 +601,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, sms_info("failed to open \"%s\"", filename); return rc; } - sms_info("read FW %s, size=%d", filename, fw->size); + sms_info("read FW %s, size=%zd", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 0f9f5d585e37..b62ca96dfbec 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -209,14 +209,14 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id) rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), fw_buffer, fw->size, &dummy, 1000); - sms_info("sent %d(%d) bytes, rc %d", fw->size, dummy, rc); + sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc); kfree(fw_buffer); } else { sms_err("failed to allocate firmware buffer"); rc = -ENOMEM; } - sms_info("read FW %s, size=%d", smsusb1_fw_lkup[id], fw->size); + sms_info("read FW %s, size=%zd", smsusb1_fw_lkup[id], fw->size); release_firmware(fw); -- cgit v1.2.3 From 5068b7a449293ced0ea963f3c944189d78fe1b1e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 23:27:19 -0300 Subject: V4L/DVB (8306): sms1xxx: log firmware download process by default Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 14 +++++++++----- drivers/media/dvb/siano/smscoreapi.h | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index c54c7180e39e..1dd196600036 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -791,19 +791,23 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) rc = smscore_load_firmware_from_file(coredev, fw_filename, NULL); if (rc < 0) { - sms_err("error %d loading firmware: %s, " - "trying again with default firmware", - rc, fw_filename); + sms_warn("error %d loading firmware: %s, " + "trying again with default firmware", + rc, fw_filename); /* try again with the default firmware */ + fw_filename = smscore_fw_lkup[mode][type]; rc = smscore_load_firmware_from_file(coredev, - smscore_fw_lkup[mode][type], NULL); + fw_filename, NULL); if (rc < 0) { - sms_err("load firmware failed %d", rc); + sms_warn("error %d loading " + "firmware: %s", rc, + fw_filename); return rc; } } + sms_log("firmware download success: %s", fw_filename); } else sms_info("mode %d supported by running " "firmware", mode); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 3e4e7dbc54da..c1f56900b3ea 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -421,10 +421,10 @@ extern int sms_debug; if (sms_debug & lvl) \ sms_printk(kern, fmt, ##arg); } while (0) +#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) #define sms_err(fmt, arg...) \ sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) -#define sms_warn(fmt, arg...) \ - sms_printk(KERN_WARNING, "line: %d: " fmt, __LINE__, ##arg) +#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg) #define sms_info(fmt, arg...) \ dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) #define sms_debug(fmt, arg...) \ -- cgit v1.2.3 From eb383bddc5ec52087ccfad4cccd8c6cc57c846d8 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 29 Jun 2008 01:33:23 -0300 Subject: V4L/DVB (8307): sms1xxx: change smsusb_driver.name to sms1xxx Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index b62ca96dfbec..9a2144c547ab 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -415,7 +415,7 @@ static void smsusb_disconnect(struct usb_interface *intf) } static struct usb_driver smsusb_driver = { - .name = "smsusb", + .name = "sms1xxx", .probe = smsusb_probe, .disconnect = smsusb_disconnect, .id_table = smsusb_id_table, -- cgit v1.2.3 From 14a638cd3b6031c27b33560506244b9bf1913ad9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 23:53:51 -0300 Subject: V4L/DVB (8308): sms1xxx: Provide option to support Siano default usb ids Provide an option to enable / disable support for Siano's default usb ids. This allows the support for Siano's USB IDs to be disabled, so that Siano's external driver can be used, instead. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/Kconfig | 20 +++++++++++++++----- drivers/media/dvb/siano/sms-cards.c | 2 ++ 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig index 878d48c1cfc0..dd863f261672 100644 --- a/drivers/media/dvb/siano/Kconfig +++ b/drivers/media/dvb/siano/Kconfig @@ -3,14 +3,24 @@ # config DVB_SIANO_SMS1XXX - tristate "Siano SMS1xxx USB dongle support" + tristate "Siano SMS1XXX USB dongle support" depends on DVB_CORE && USB ---help--- - Choose Y here if you have USB dongle with SMS1xxx chipset. - - Further documentation on this driver can be found on the WWW at - . + Choose Y here if you have a USB dongle with a SMS1XXX chipset. To compile this driver as a module, choose M here: the module will be called sms1xxx. +config DVB_SIANO_SMS1XXX_SMS_IDS + bool "Enable support for Siano Mobile Silicon default USB IDs" + depends on DVB_SIANO_SMS1XXX + default y + ---help--- + Choose Y here if you have a USB dongle with a SMS1XXX chipset + that uses Siano Mobile Silicon's default usb vid:pid. + + Choose N here if you would prefer to use Siano's external driver. + + Further documentation on this driver can be found on the WWW at + . + diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index 6a22ec10fe20..c4c9ab0232e3 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -20,6 +20,7 @@ #include "sms-cards.h" struct usb_device_id smsusb_id_table[] = { +#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS { USB_DEVICE(0x187f, 0x0010), .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, { USB_DEVICE(0x187f, 0x0100), @@ -30,6 +31,7 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, { USB_DEVICE(0x187f, 0x0300), .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, +#endif { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, smsusb_id_table); -- cgit v1.2.3 From 4411d29165d83a4a73ea351ffccfdc0fd8baeb1e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 29 Jun 2008 14:45:37 -0300 Subject: V4L/DVB (8309): sms1xxx: fix OOPS on 64 bit kernels due to a bad cast Fix the following build warning: smscoreapi.c: In function 'smscore_detect_mode': smscoreapi.c:689: warning: cast from pointer to integer of different size smscoreapi.c:689: warning: cast to pointer from integer of different size smscoreapi.c: In function 'smscore_set_device_mode': smscoreapi.c:820: warning: cast from pointer to integer of different size smscoreapi.c:820: warning: cast to pointer from integer of different size ...and fix the following OOPS on 64bit kernels: [ 717.263667] usb 6-4: new high speed USB device using ehci_hcd and address 2 [ 717.396386] usb 6-4: configuration #1 chosen from 1 choice [ 717.473650] Unable to handle kernel paging request at 0000000000c02000 RIP: [ 717.473657] [] :sms1xxx:smscore_set_device_mode+0x22c/0x4a0 [ 717.473669] PGD 3c6f7067 PUD 3d484067 PMD 0 [ 717.473674] Oops: 0002 [1] SMP [ 717.473678] CPU 0 [Modules linked in snipped] [ 717.473773] Pid: 8380, comm: modprobe Tainted: P 2.6.24-16-generic #1 [ 717.473776] RIP: 0010:[] [] :sms1xxx:smscore_set_device_mode+0x22c/0x4a0 [ 717.473784] RSP: 0018:ffff81003d495ba8 EFLAGS: 00010206 [ 717.473786] RAX: ffff81003d8cd8d0 RBX: ffff81003d8cd800 RCX: ffff81003d8cd8d0 [ 717.473788] RDX: 0000000000000008 RSI: ffff81003f080070 RDI: ffff81003d8cd800 [ 717.473791] RBP: 0000000000000004 R08: ffff81003ec0104b R09: ffffffffffffffff [ 717.473793] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000c02000 [ 717.473796] R13: 00000000fffffff4 R14: ffff810000c02000 R15: ffff81003d8cd878 [ 717.473799] FS: 00007f70a680f6e0(0000) GS:ffffffff805b0000(0000) knlGS:0000000000000000 [ 717.473801] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 717.473804] CR2: 0000000000c02000 CR3: 000000003c68b000 CR4: 00000000000006e0 [ 717.473806] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 717.473809] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 717.473812] Process modprobe (pid: 8380, threadinfo ffff81003d494000, task ffff81003d2fc000) [ 717.473814] Stack: ffff81003d8cd800 ffff81003d8cd800 0000000000000000 ffff81003c6d8000 [ 717.473820] ffff81003dcac800 0000000000000008 ffffc20000787bb0 ffffffff88dba16c [ 717.473825] ffff81003dcac800 000000000000000a 0000000000000000 ffffffff88dbb2fa [ 717.473829] Call Trace: [ 717.473866] [] :sms1xxx:smscore_start_device+0x1c/0xb0 [ 717.473885] [] :sms1xxx:smsusb_probe+0x29a/0x670 [ 717.473929] [] :sms1xxx:smsusb_sendrequest+0x0/0x30 [ 717.473965] [] mutex_lock+0x9/0x20 [ 717.473998] [] :usbcore:usb_autopm_do_device+0x8e/0x130 [ 717.474040] [] :usbcore:usb_probe_interface+0xda/0x160 [ 717.474067] [] driver_probe_device+0x9c/0x1b0 [ 717.474091] [] __driver_attach+0xc9/0xd0 [ 717.474107] [] __driver_attach+0x0/0xd0 [ 717.474115] [] bus_for_each_dev+0x4d/0x80 [ 717.474156] [] bus_add_driver+0xac/0x220 [ 717.474203] [] :usbcore:usb_register_driver+0xa9/0x120 [ 717.474232] [] :sms1xxx:smsusb_register+0x1b/0x70 [ 717.474243] [] :sms1xxx:smscore_module_init+0x7c/0xb0 [ 717.474253] [] sys_init_module+0x18e/0x1a90 [ 717.474426] [] system_call+0x7e/0x83 [ 717.474490] [ 717.474491] [ 717.474492] Code: 66 41 c7 04 24 9c 02 41 c6 44 24 02 00 4c 89 e6 41 c6 44 24 [ 717.474506] RIP [] :sms1xxx:smscore_set_device_mode+0x22c/0x4a0 [ 717.474513] RSP [ 717.474515] CR2: 0000000000c02000 [ 717.474521] ---[ end trace 52d9c6f207be106a ]--- Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index c1f56900b3ea..eeb5c0a7f62b 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -50,7 +50,7 @@ typedef struct mutex kmutex_t; #define SMS_ALLOC_ALIGNMENT 128 #define SMS_DMA_ALIGNMENT 16 #define SMS_ALIGN_ADDRESS(addr) \ - ((((u32)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) + ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) #define SMS_DEVICE_FAMILY2 1 #define SMS_ROM_NO_RESPONSE 2 -- cgit v1.2.3 From b1d8f9f5b8036b61a7ec562dfb86361f5b18e8f2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sun, 29 Jun 2008 15:15:19 -0300 Subject: V4L/DVB (8310): sms1xxx: remove kmutex_t typedef remove typedef struct mutex kmutex_t fix one line > 80 columns Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 4 ++-- drivers/media/dvb/siano/smscoreapi.h | 5 ++--- drivers/media/dvb/siano/smsdvb.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 1dd196600036..9e7730a40e0f 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -112,10 +112,10 @@ struct smscore_registry_entry_t { struct list_head g_smscore_notifyees; struct list_head g_smscore_devices; -kmutex_t g_smscore_deviceslock; +struct mutex g_smscore_deviceslock; struct list_head g_smscore_registry; -kmutex_t g_smscore_registrylock; +struct mutex g_smscore_registrylock; static int default_mode = 4; diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index eeb5c0a7f62b..fb6acaefcbc6 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -36,8 +36,6 @@ #include -typedef struct mutex kmutex_t; - #define kmutex_init(_p_) mutex_init(_p_) #define kmutex_lock(_p_) mutex_lock(_p_) #define kmutex_trylock(_p_) mutex_trylock(_p_) @@ -392,7 +390,8 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); +extern +struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); extern void smscore_putbuffer(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 72d1de7a6dea..6f9c18563867 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -28,7 +28,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct list_head g_smsdvb_clients; -kmutex_t g_smsdvb_clientslock; +struct mutex g_smsdvb_clientslock; static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { -- cgit v1.2.3 From 1fbc3caff47785aca67b4bd5b29c04f3f20c770e Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 1 Jul 2008 04:35:26 -0300 Subject: V4L/DVB (8311): sms1xxx: support device-specific firmware filenames on stellar usb1 sticks Add the capability to define device-specific firmware filenames for the SMS1010, with a mechanism to fall back to the generic firmware if the device-specific firmware is not present. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smsusb.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 9a2144c547ab..c10b1849c6a3 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -184,22 +184,39 @@ static char *smsusb1_fw_lkup[] = { "dvbt_bda_stellar_usb.inp", }; -static int smsusb1_load_firmware(struct usb_device *udev, int id) +static inline char *sms_get_fw_name(int mode, int board_id) +{ + char **fw = sms_get_board(board_id)->fw; + return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode]; +} + +static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) { const struct firmware *fw; u8 *fw_buffer; int rc, dummy; + char *fw_filename; if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { sms_err("invalid firmware id specified %d", id); return -EINVAL; } - rc = request_firmware(&fw, smsusb1_fw_lkup[id], &udev->dev); + fw_filename = sms_get_fw_name(id, board_id); + + rc = request_firmware(&fw, fw_filename, &udev->dev); if (rc < 0) { - sms_err("failed to open \"%s\" mode %d", - smsusb1_fw_lkup[id], id); - return rc; + sms_warn("failed to open \"%s\" mode %d, " + "trying again with default firmware", fw_filename, id); + + fw_filename = smsusb1_fw_lkup[id]; + rc = request_firmware(&fw, fw_filename, &udev->dev); + if (rc < 0) { + sms_warn("failed to open \"%s\" mode %d", + fw_filename, id); + + return rc; + } } fw_buffer = kmalloc(fw->size, GFP_KERNEL); @@ -216,7 +233,7 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id) sms_err("failed to allocate firmware buffer"); rc = -ENOMEM; } - sms_info("read FW %s, size=%zd", smsusb1_fw_lkup[id], fw->size); + sms_info("read FW %s, size=%zd", fw_filename, fw->size); release_firmware(fw); @@ -401,7 +418,8 @@ static int smsusb_probe(struct usb_interface *intf, udev->bus->busnum, udev->devpath); sms_info("stellar device was found."); return smsusb1_load_firmware( - udev, smscore_registry_getmode(devpath)); + udev, smscore_registry_getmode(devpath), + id->driver_info); } rc = smsusb_init_device(intf, id->driver_info); -- cgit v1.2.3 From a745f0a12cab631b92f9e13b31997192c7df3823 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 1 Jul 2008 04:47:10 -0300 Subject: V4L/DVB (8312): sms1xxx: add firmware filenames to board properties for stellar and nova Assign the following firmware filenames: sms1xxx-stellar-dvbt-01.fw sms1xxx-nova-a-dvbt-01.fw sms1xxx-nova-b-dvbt-01.fw Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index c4c9ab0232e3..c75c27c18b12 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -43,14 +43,17 @@ static struct sms_board sms_boards[] = { [SMS1XXX_BOARD_SIANO_STELLAR] = { .name = "Siano Stellar Digital Receiver", .type = SMS_STELLAR, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_NOVA_A] = { .name = "Siano Nova A Digital Receiver", .type = SMS_NOVA_A0, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_NOVA_B] = { .name = "Siano Nova B Digital Receiver", .type = SMS_NOVA_B0, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", }, [SMS1XXX_BOARD_SIANO_VEGA] = { .name = "Siano Vega Digital Receiver", -- cgit v1.2.3 From 44f71c3fcefbfea3628cca52c0a177252cf83b60 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 28 Jun 2008 23:55:36 -0300 Subject: V4L/DVB (8313): sms1xxx: add support for Hauppauge WinTV-Nova-T-MiniStick Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/sms-cards.c | 32 ++++++++++++++++++++++++++++++++ drivers/media/dvb/siano/sms-cards.h | 4 ++++ 2 files changed, 36 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index c75c27c18b12..e7a8ac0c4049 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -32,6 +32,18 @@ struct usb_device_id smsusb_id_table[] = { { USB_DEVICE(0x187f, 0x0300), .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, #endif + { USB_DEVICE(0x2040, 0x1700), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, + { USB_DEVICE(0x2040, 0x1800), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, + { USB_DEVICE(0x2040, 0x1801), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, + { USB_DEVICE(0x2040, 0x5500), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5580), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0x5590), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, smsusb_id_table); @@ -59,6 +71,26 @@ static struct sms_board sms_boards[] = { .name = "Siano Vega Digital Receiver", .type = SMS_VEGA, }, + [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = { + .name = "Hauppauge Catamount", + .type = SMS_STELLAR, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", + }, + [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = { + .name = "Hauppauge Okemo-A", + .type = SMS_NOVA_A0, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", + }, + [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = { + .name = "Hauppauge Okemo-B", + .type = SMS_NOVA_B0, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", + }, + [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { + .name = "Hauppauge WinTV-Nova-T-MiniStick", + .type = SMS_NOVA_B0, + .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw", + }, }; struct sms_board *sms_get_board(int id) diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 262e3ffbc29c..83b39bc203fe 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -28,6 +28,10 @@ #define SMS1XXX_BOARD_SIANO_NOVA_A 2 #define SMS1XXX_BOARD_SIANO_NOVA_B 3 #define SMS1XXX_BOARD_SIANO_VEGA 4 +#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5 +#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6 +#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7 +#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 struct sms_board { enum sms_device_type_st type; -- cgit v1.2.3 From 203c204b39fef2c1c99e4b39e61ba292aa60142a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 2 Jul 2008 15:59:29 -0300 Subject: V4L/DVB (8315): zr36067: Delete dead code This has been commented out for years, it's about time to get rid of it. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_card.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 5ce1ec7338bf..0929edb2d4f1 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -358,14 +358,6 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_VPX3220: name = "vpx3220"; break; -/* case I2C_DRIVERID_VPX3224: - name = "vpx3224"; - break; - case I2C_DRIVERID_MSE3000: - name = "mse3000"; - break;*/ - default: - break; } return name; @@ -386,8 +378,6 @@ codecid_to_modulename (u16 codecid) case CODEC_TYPE_ZR36016: name = "zr36016"; break; - default: - break; } return name; @@ -428,7 +418,6 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = { .type = DC10_old, .name = "DC10(old)", .i2c_decoder = I2C_DRIVERID_VPX3220, - /*.i2c_encoder = I2C_DRIVERID_MSE3000,*/ .video_codec = CODEC_TYPE_ZR36050, .video_vfe = CODEC_TYPE_ZR36016, -- cgit v1.2.3 From 91a1d912f61b91e44336efe100a2bd0821777e24 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 2 Jul 2008 16:01:21 -0300 Subject: V4L/DVB (8316): bt819: Fix a debug message Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt819.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 8bfd5c75cb3a..ddd2a7964dec 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -516,7 +516,7 @@ bt819_detect_client (struct i2c_adapter *adapter, dprintk(1, KERN_INFO - "saa7111.c: detecting bt819 client on address 0x%x\n", + "bt819: detecting bt819 client on address 0x%x\n", address << 1); /* Check if the adapter supports the needed features */ -- cgit v1.2.3 From 3f8d6f73da4332b4ff4150b9bae8e5f680bcbbde Mon Sep 17 00:00:00 2001 From: Dean Anderson Date: Mon, 30 Jun 2008 21:28:34 -0300 Subject: V4L/DVB (8317): Sensoray 2255 V4l driver checkpatch fixes This patch fixes some coding style issues. It also fixes a NULL de-reference on driver unload. The permissions for the module parameters were changed to 0644. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s2255drv.c | 61 ++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 6d5fbad95c29..04eb2c3fabd8 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -67,17 +67,17 @@ /* maximum time for DSP to start responding after last FW word loaded(ms) */ #define S2255_DSP_BOOTTIME 400 /* maximum time to wait for firmware to load (ms) */ -#define S2255_LOAD_TIMEOUT (5000+S2255_DSP_BOOTTIME) +#define S2255_LOAD_TIMEOUT (5000 + S2255_DSP_BOOTTIME) #define S2255_DEF_BUFS 16 #define MAX_CHANNELS 4 #define FRAME_MARKER 0x2255DA4AL -#define MAX_PIPE_USBBLOCK (40*1024) -#define DEFAULT_PIPE_USBBLOCK (16*1024) +#define MAX_PIPE_USBBLOCK (40 * 1024) +#define DEFAULT_PIPE_USBBLOCK (16 * 1024) #define MAX_CHANNELS 4 #define MAX_PIPE_BUFFERS 1 #define SYS_FRAMES 4 /* maximum size is PAL full size plus room for the marker header(s) */ -#define SYS_FRAMES_MAXSIZE (720*288*2*2 + 4096) +#define SYS_FRAMES_MAXSIZE (720 * 288 * 2 * 2 + 4096) #define DEF_USB_BLOCK (4096) #define LINE_SZ_4CIFS_NTSC 640 #define LINE_SZ_2CIFS_NTSC 640 @@ -168,7 +168,7 @@ struct s2255_bufferi { #define DEF_MODEI_NTSC_CONT {FORMAT_NTSC, DEF_SCALE, DEF_COLOR, \ DEF_FDEC, DEF_BRIGHT, DEF_CONTRAST, DEF_SATURATION, \ - DEF_HUE, 0, DEF_USB_BLOCK, 0 } + DEF_HUE, 0, DEF_USB_BLOCK, 0} struct s2255_dmaqueue { struct list_head active; @@ -275,6 +275,10 @@ struct s2255_fh { struct s2255_mode mode; }; +/* + * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles. + * Limit V4L to one stream at a time. + */ #define S2255_MAX_USERS 1 #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ @@ -293,7 +297,7 @@ struct s2255_fh { #define PREFIX_SIZE 512 /* Channels on box are in reverse order */ -static unsigned long G_chnmap[MAX_CHANNELS] = { 3, 2, 1, 0 }; +static unsigned long G_chnmap[MAX_CHANNELS] = {3, 2, 1, 0}; static LIST_HEAD(s2255_devlist); @@ -329,11 +333,11 @@ static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ /* start video number */ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -module_param(debug, int, 0); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level(0-100) default 0"); -module_param(vid_limit, int, 0); +module_param(vid_limit, int, 0644); MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)"); -module_param(video_nr, int, 0); +module_param(video_nr, int, 0644); MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)"); /* USB device table */ @@ -437,7 +441,10 @@ static int norm_minh(struct video_device *vdev) } -/* converts 2255 planar format to yuyv or uyvy */ +/* + * TODO: fixme: move YUV reordering to hardware + * converts 2255 planar format to yuyv or uyvy + */ static void planar422p_to_yuv_packed(const unsigned char *in, unsigned char *out, int width, int height, @@ -502,7 +509,7 @@ static void s2255_fwchunk_complete(struct urb *urb) struct usb_device *udev = urb->dev; int len; dprintk(100, "udev %p urb %p", udev, urb); - + /* TODO: fixme. reflect change in status */ if (urb->status) { dev_err(&udev->dev, "URB failed with status %d", urb->status); return; @@ -682,7 +689,7 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count, if (0 == *count) *count = S2255_DEF_BUFS; - while (*size * *count > vid_limit * 1024 * 1024) + while (*size * (*count) > vid_limit * 1024 * 1024) (*count)--; return 0; @@ -789,7 +796,7 @@ static int res_get(struct s2255_dev *dev, struct s2255_fh *fh) static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh) { - return (dev->resources[fh->channel]); + return dev->resources[fh->channel]; } static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) @@ -806,7 +813,8 @@ static int vidioc_querycap(struct file *file, void *priv, struct s2255_dev *dev = fh->dev; strlcpy(cap->driver, "s2255", sizeof(cap->driver)); strlcpy(cap->card, "s2255", sizeof(cap->card)); - strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); + strlcpy(cap->bus_info, dev_name(&dev->udev->dev), + sizeof(cap->bus_info)); cap->version = S2255_VERSION; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; return 0; @@ -839,8 +847,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, f->fmt.pix.pixelformat = fh->fmt->fourcc; f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3); f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; - - return (0); + return 0; } static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, @@ -961,7 +968,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, ret = vidioc_try_fmt_vid_cap(file, fh, f); if (ret < 0) - return (ret); + return ret; fmt = format_by_fourcc(f->fmt.pix.pixelformat); @@ -1336,7 +1343,7 @@ static int vidioc_enum_input(struct file *file, void *priv, inp->type = V4L2_INPUT_TYPE_CAMERA; inp->std = S2255_NORMS; strlcpy(inp->name, "Camera", sizeof(inp->name)); - return (0); + return 0; } static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) @@ -1360,7 +1367,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) if (qc->id && qc->id == s2255_qctrl[i].id) { memcpy(qc, &(s2255_qctrl[i]), sizeof(*qc)); - return (0); + return 0; } dprintk(4, "query_ctrl -EINVAL %d\n", qc->id); @@ -1375,7 +1382,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv, for (i = 0; i < ARRAY_SIZE(s2255_qctrl); i++) if (ctrl->id == s2255_qctrl[i].id) { ctrl->value = qctl_regs[i]; - return (0); + return 0; } dprintk(4, "g_ctrl -EINVAL\n"); @@ -1395,7 +1402,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, if (ctrl->id == s2255_qctrl[i].id) { if (ctrl->value < s2255_qctrl[i].minimum || ctrl->value > s2255_qctrl[i].maximum) - return (-ERANGE); + return -ERANGE; qctl_regs[i] = ctrl->value; /* update the mode to the corresponding value */ @@ -1571,6 +1578,11 @@ static void s2255_destroy(struct kref *kref) usb_free_urb(dev->fw_data->fw_urb); dev->fw_data->fw_urb = NULL; } + /* + * TODO: fixme(above, below): potentially leaving timers alive. + * do not ignore timeout below if + * it occurs. + */ /* make sure we aren't waiting for the DSP */ if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) { @@ -1582,15 +1594,12 @@ static void s2255_destroy(struct kref *kref) } if (dev->fw_data) { + if (dev->fw_data->fw) + release_firmware(dev->fw_data->fw); kfree(dev->fw_data->pfw_data); kfree(dev->fw_data); } - if (dev->fw_data->fw) { - release_firmware(dev->fw_data->fw); - dev->fw_data->fw = NULL; - } - usb_put_dev(dev->udev); dprintk(1, "%s", __func__); kfree(dev); -- cgit v1.2.3 From cd257a6f4dd908d94e504d2431710f0fcfe62036 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 30 Jun 2008 20:57:39 -0300 Subject: V4L/DVB (8318): OV7670: don't reject unsupported settings For VIDIOC_G_FMT/VIDIOC_TRY_FMT, the V4L2 API spec states: "Drivers should not return an error code unless the input is ambiguous" "Very simple, inflexible devices may even ignore all input and always return the default parameters." "When the requested buffer type is not supported drivers return an EINVAL error code." i.e. returning errors for unsupported fields is bad, and it's ok to unconditionally overwrite user-requested settings This patch makes ov7670 meet that behaviour, and brings it in line with other drivers e.g. stk-webcam. It also fixes compatibility with (unpatched) gstreamer. Signed-off-by: Daniel Drake Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ov7670.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index d7bfd30f74a9..5e0d4e2ee510 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -682,17 +682,17 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt, for (index = 0; index < N_OV7670_FMTS; index++) if (ov7670_formats[index].pixelformat == pix->pixelformat) break; - if (index >= N_OV7670_FMTS) - return -EINVAL; + if (index >= N_OV7670_FMTS) { + /* default to first format */ + index = 0; + pix->pixelformat = ov7670_formats[0].pixelformat; + } if (ret_fmt != NULL) *ret_fmt = ov7670_formats + index; /* * Fields: the OV devices claim to be progressive. */ - if (pix->field == V4L2_FIELD_ANY) - pix->field = V4L2_FIELD_NONE; - else if (pix->field != V4L2_FIELD_NONE) - return -EINVAL; + pix->field = V4L2_FIELD_NONE; /* * Round requested image size down to the nearest * we support, but not below the smallest. -- cgit v1.2.3 From 0b17d0edbc22eda3d0407f98ce4f16ceefb9a97f Mon Sep 17 00:00:00 2001 From: Hermann Pitton Date: Sat, 12 Jul 2008 12:27:59 -0300 Subject: V4L/DVB (8319): saa7134: Add support for analog only ASUSTeK P7131 saa7134: add a separate entry for the ASUSTeK P7131 analog only and do some eeprom detection to escape from the TVFM7135 with the same PCI subsystem on auto detection. Signed-off-by: Hermann Pitton Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.saa7134 | 1 + drivers/media/video/saa7134/saa7134-cards.c | 43 +++++++++++++++++++++++++++++ drivers/media/video/saa7134/saa7134-input.c | 1 + drivers/media/video/saa7134/saa7134.h | 1 + 4 files changed, 46 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 171905e872f1..39868af9cf9f 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -144,3 +144,4 @@ 143 -> Beholder BeholdTV M63 [5ace:6191] 144 -> Beholder BeholdTV M6 Extra [5ace:6193] 145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636] +146 -> ASUSTeK P7131 Analog diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 4e6e5ccaa35e..6893f998d292 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -3519,6 +3519,39 @@ struct saa7134_board saa7134_boards[] = { .amux = TV, .gpio = 0x0200000, }, + }, + [SAA7134_BOARD_ASUSTeK_P7131_ANALOG] = { + .name = "ASUSTeK P7131 Analog", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .gpiomask = 1 << 21, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x0000000, + }, { + .name = name_comp1, + .vmux = 3, + .amux = LINE2, + }, { + .name = name_comp2, + .vmux = 0, + .amux = LINE2, + }, { + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + } }, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, }, [SAA7134_BOARD_SABRENT_TV_PCB05] = { .name = "Sabrent PCMCIA TV-PCB05", @@ -5605,6 +5638,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBT_LR301: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: case SAA7134_BOARD_FLYDVBTDUO: case SAA7134_BOARD_PROTEUS_2309: case SAA7134_BOARD_AVERMEDIA_A16AR: @@ -5941,6 +5975,15 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); break; } + case SAA7134_BOARD_ASUSTeK_TVFM7135: + /* The card below is detected as card=53, but is different */ + if (dev->autodetected && (dev->eedata[0x27] == 0x03)) { + dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG; + printk(KERN_INFO "%s: P7131 analog only, using " + "entry of %s\n", + dev->name, saa7134_boards[dev->board].name); + } + break; case SAA7134_BOARD_HAUPPAUGE_HVR1110: hauppauge_eeprom(dev, dev->eedata+0x80); /* break intentionally omitted */ diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index 6edabc06e6d0..e6217fe13339 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -409,6 +409,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA: + case SAA7134_BOARD_ASUSTeK_P7131_ANALOG: ir_codes = ir_codes_asus_pc39; mask_keydown = 0x0040000; rc5_gpio = 1; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 6e5a4094d6be..6927cbea8624 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -267,6 +267,7 @@ struct saa7134_format { #define SAA7134_BOARD_BEHOLD_M63 143 #define SAA7134_BOARD_BEHOLD_M6_EXTRA 144 #define SAA7134_BOARD_AVERMEDIA_M103 145 +#define SAA7134_BOARD_ASUSTeK_P7131_ANALOG 146 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 -- cgit v1.2.3 From f1f74aa2cf7f109b2eaf3502b8bd13bf40bf6633 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 12 Jul 2008 00:37:08 -0300 Subject: V4L/DVB (8322): sms1xxx: fix improper usage of asm/foo.h Fix the following warnings generated by checkpatch.pl: WARNING: Use #include instead of 251: FILE: linux/drivers/media/dvb/siano/smscoreapi.c:30: +#include WARNING: Use #include instead of 1566: FILE: linux/drivers/media/dvb/siano/smscoreapi.h:29: +#include Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 2 +- drivers/media/dvb/siano/smscoreapi.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 9e7730a40e0f..b4b8ed795c95 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index fb6acaefcbc6..926ec8ca47ad 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include "dmxdev.h" -- cgit v1.2.3 From 2c6a37bb076b9718c6362d4ffa1c7e58fdb1a0e9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 12 Jul 2008 22:58:24 -0300 Subject: V4L/DVB (8326): sms1xxx: fix missing #include Fix the build error: smscoreapi.c:689: error: 'uintptr_t' undeclared Thanks to Peter Schlaf for reporting this. Cc: Peter Schlaf Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 926ec8ca47ad..c1f8f1dccb11 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "dmxdev.h" -- cgit v1.2.3 From 8abdd00dcc6a58cab3afe6a23a0ce819dc08049a Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Jul 2008 19:05:25 -0300 Subject: V4L/DVB (8331): cx18: Add locking for struct cx18 GPIO state variables cx18: Add locking for struct cx18 GPIO state variables in anticpation of adding IR microcontroller reset support for use by external IR modules. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-driver.c | 1 + drivers/media/video/cx18/cx18-driver.h | 1 + drivers/media/video/cx18/cx18-gpio.c | 15 +++++++++++++-- drivers/media/video/cx18/cx18-ioctl.c | 2 ++ 4 files changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index e73de6252257..22434aadde31 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -421,6 +421,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx) mutex_init(&cx->serialize_lock); mutex_init(&cx->i2c_bus_lock[0]); mutex_init(&cx->i2c_bus_lock[1]); + mutex_init(&cx->gpio_lock); spin_lock_init(&cx->lock); spin_lock_init(&cx->dma_reg_lock); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index b78d0e38d53d..45e31b04730e 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -427,6 +427,7 @@ struct cx18 { /* gpio */ u32 gpio_dir; u32 gpio_val; + struct mutex gpio_lock; /* v4l2 and User settings */ diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index 089bad6d85a0..d753a40973ba 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -69,6 +69,7 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) /* Assuming that the masks are a subset of the bits in gpio_dir */ /* Assert */ + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); gpio_write(cx); @@ -79,10 +80,12 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); gpio_write(cx); schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); + mutex_unlock(&cx->gpio_lock); } void cx18_gpio_init(struct cx18 *cx) { + mutex_lock(&cx->gpio_lock); cx->gpio_dir = cx->card->gpio_init.direction; cx->gpio_val = cx->card->gpio_init.initial_value; @@ -91,14 +94,17 @@ void cx18_gpio_init(struct cx18 *cx) cx->gpio_val |= 1 << cx->card->xceive_pin; } - if (cx->gpio_dir == 0) + if (cx->gpio_dir == 0) { + mutex_unlock(&cx->gpio_lock); return; + } CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } /* Xceive tuner reset function */ @@ -112,13 +118,16 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) return 0; CX18_DEBUG_INFO("Resetting tuner\n"); + mutex_lock(&cx->gpio_lock); cx->gpio_val &= ~(1 << cx->card->xceive_pin); - gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); + mutex_lock(&cx->gpio_lock); cx->gpio_val |= 1 << cx->card->xceive_pin; gpio_write(cx); + mutex_unlock(&cx->gpio_lock); schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; } @@ -151,8 +160,10 @@ int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) return -EINVAL; } if (mask) { + mutex_lock(&cx->gpio_lock); cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); gpio_write(cx); + mutex_unlock(&cx->gpio_lock); } return 0; } diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 6eaf77b99e9d..146a4b856496 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -716,8 +716,10 @@ static int cx18_log_status(struct file *file, void *fh) cx18_get_audio_input(cx, cx->audio_input, &audin); CX18_INFO("Video Input: %s\n", vidin.name); CX18_INFO("Audio Input: %s\n", audin.name); + mutex_lock(&cx->gpio_lock); CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", cx->gpio_dir, cx->gpio_val); + mutex_unlock(&cx->gpio_lock); CX18_INFO("Tuner: %s\n", test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&cx->params, cx->name); -- cgit v1.2.3 From 02fa272fcb6edda9059d6dbaab20dfe919f4f4d2 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 13 Jul 2008 19:30:15 -0300 Subject: V4L/DVB (8332): cx18: Suport external reset of the Z8F0811 IR controller on HVR-1600 for lirc cx18: added in cx18_ir_reset_gpio function for lirc_pvr150 like module. Also added the ability to reset the IR chip via ioctl like ivtv. This needs the mutex to protect gpio_dir and gpio_val in struct cx18 as gpio changes can come from a few different asynchronous sources now. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-cards.c | 2 ++ drivers/media/video/cx18/cx18-cards.h | 1 + drivers/media/video/cx18/cx18-gpio.c | 41 +++++++++++++++++++++++++++++++++++ drivers/media/video/cx18/cx18-gpio.h | 1 + drivers/media/video/cx18/cx18-ioctl.c | 9 ++++++++ 5 files changed, 54 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 0caae1a5edc4..8fe5f38c4d7c 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -88,6 +88,7 @@ static const struct cx18_card cx18_card_hvr1600_esmt = { .active_lo_mask = 0x3001, .msecs_asserted = 10, .msecs_recovery = 40, + .ir_reset_mask = 0x0001, }, .i2c = &cx18_i2c_std, }; @@ -133,6 +134,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { .active_lo_mask = 0x3001, .msecs_asserted = 10, .msecs_recovery = 40, + .ir_reset_mask = 0x0001, }, .i2c = &cx18_i2c_std, }; diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index dc283d756907..32155f6e6fe4 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -83,6 +83,7 @@ struct cx18_gpio_i2c_slave_reset { u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ int msecs_asserted; /* time period reset must remain asserted */ int msecs_recovery; /* time after deassert for chips to be ready */ + u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */ }; struct cx18_gpio_audio_input { /* select tuner/line in input */ diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c index d753a40973ba..3d495dba4983 100644 --- a/drivers/media/video/cx18/cx18-gpio.c +++ b/drivers/media/video/cx18/cx18-gpio.c @@ -83,6 +83,47 @@ void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) mutex_unlock(&cx->gpio_lock); } +void cx18_reset_ir_gpio(void *data) +{ + struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; + const struct cx18_gpio_i2c_slave_reset *p; + + p = &cx->card->gpio_i2c_slave_reset; + + if (p->ir_reset_mask == 0) + return; + + CX18_DEBUG_INFO("Resetting IR microcontroller\n"); + + /* + Assert timing for the Z8F0811 on HVR-1600 boards: + 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate + 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles + (6,601,085 nanoseconds ~= 7 milliseconds) + 3. DBG pin must be high before chip exits reset for normal operation. + DBG is open drain and hopefully pulled high since we don't + normally drive it (GPIO 1?) for the HVR-1600 + 4. Z8F0811 won't exit reset until RESET is deasserted + */ + mutex_lock(&cx->gpio_lock); + cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); + + /* + Zilog comes out of reset, loads reset vector address and executes + from there. Required recovery delay unknown. + */ + mutex_lock(&cx->gpio_lock); + cx->gpio_val = cx->gpio_val | p->ir_reset_mask; + gpio_write(cx); + mutex_unlock(&cx->gpio_lock); + schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); +} +EXPORT_SYMBOL(cx18_reset_ir_gpio); +/* This symbol is exported for use by an infrared module for the IR-blaster */ + void cx18_gpio_init(struct cx18 *cx) { mutex_lock(&cx->gpio_lock); diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h index 7447fed35767..22cd7ddf8554 100644 --- a/drivers/media/video/cx18/cx18-gpio.h +++ b/drivers/media/video/cx18/cx18-gpio.h @@ -22,5 +22,6 @@ void cx18_gpio_init(struct cx18 *cx); void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); +void cx18_reset_ir_gpio(void *data); int cx18_reset_tuner_gpio(void *dev, int cmd, int value); int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 146a4b856496..0d74e59e503e 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -754,6 +754,15 @@ static int cx18_default(struct file *file, void *fh, int cmd, void *arg) cx18_audio_set_route(cx, route); break; } + + case VIDIOC_INT_RESET: { + u32 val = *(u32 *)arg; + + if ((val == 0) || (val & 0x01)) + cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]); + break; + } + default: return -EINVAL; } -- cgit v1.2.3 From 4ee48c4257d842a29c032a32a19a3fcdd004b83f Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 15 Jul 2008 19:36:46 -0300 Subject: V4L/DVB (8334): tda10023: Fix typo in tda10023_attach dummy routine Fix compiler warning caused by a typo in the tda10023_attach dummy routine. Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda1002x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h index afc0a32eaabd..04d19418bf20 100644 --- a/drivers/media/dvb/frontends/tda1002x.h +++ b/drivers/media/dvb/frontends/tda1002x.h @@ -76,7 +76,7 @@ extern struct dvb_frontend *tda10023_attach( struct i2c_adapter *i2c, u8 pwm); #else static inline struct dvb_frontend *tda10023_attach( - const struct tda1002x_config *config, + const struct tda10023_config *config, struct i2c_adapter *i2c, u8 pwm) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -- cgit v1.2.3 From 439d0e4250b6fc9df3fc9183db38cf8a23d4ad93 Mon Sep 17 00:00:00 2001 From: Oliver Endriss Date: Tue, 15 Jul 2008 19:52:22 -0300 Subject: V4L/DVB (8335): dvb-ttpci: Fix build with CONFIG_INPUT_EVDEV=n (Bug #11042) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix build with CONFIG_INPUT_EVDEV=n (Bug #11042). Thanks to Toralf Förster for reporting. Thanks-to: Toralf Förster Signed-off-by: Oliver Endriss Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ttpci/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index 3819390b16a5..71451237294c 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile @@ -3,7 +3,11 @@ # and the AV7110 DVB device driver # -dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o +dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o + +ifdef CONFIG_INPUT_EVDEV +dvb-ttpci-objs += av7110_ir.o +endif obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o -- cgit v1.2.3 From 092d3921195c4553a1818e698cee7a281ab361f4 Mon Sep 17 00:00:00 2001 From: Paulius Zaleckas Date: Fri, 11 Jul 2008 20:50:31 -0300 Subject: V4L/DVB (8337): soc_camera: make videobuf independent Makes SoC camera videobuf independent. Includes all necessary changes for PXA camera driver (currently the only driver using soc_camera in the mainline). These changes are important for the future soc_camera based drivers. Signed-off-by: Paulius Zaleckas Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 3 ++- drivers/media/video/pxa_camera.c | 14 ++++++++++++-- drivers/media/video/soc_camera.c | 9 +++------ include/media/soc_camera.h | 6 +++--- 4 files changed, 20 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index a6fbee4d41b7..2103f7bfd48c 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -921,7 +921,7 @@ endif # V4L_USB_DRIVERS config SOC_CAMERA tristate "SoC camera support" depends on VIDEO_V4L2 && HAS_DMA - select VIDEOBUF_DMA_SG + select VIDEOBUF_GEN help SoC Camera is a common API to several cameras, not connecting over a bus like PCI or USB. For example some i2c camera connected @@ -960,6 +960,7 @@ config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x select SOC_CAMERA + select VIDEOBUF_DMA_SG ---help--- This is a v4l2 driver for the PXA27x Quick Capture Interface diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 5ec5bb9a94d2..c3a7d476dc4b 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -30,6 +30,7 @@ #include #include +#include #include #include @@ -582,6 +583,16 @@ static struct videobuf_queue_ops pxa_videobuf_ops = { .buf_release = pxa_videobuf_release, }; +static void pxa_camera_init_videobuf(struct videobuf_queue *q, spinlock_t *lock, + struct soc_camera_device *icd) +{ + /* We must pass NULL as dev pointer, then all pci_* dma operations + * transform to normal dma_* ones. */ + videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, + sizeof(struct pxa_buffer), icd); +} + static int mclk_get_divisor(struct pxa_camera_dev *pcdev) { unsigned int mclk_10khz = pcdev->platform_mclk_10khz; @@ -998,6 +1009,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .remove = pxa_camera_remove_device, .set_fmt_cap = pxa_camera_set_fmt_cap, .try_fmt_cap = pxa_camera_try_fmt_cap, + .init_videobuf = pxa_camera_init_videobuf, .reqbufs = pxa_camera_reqbufs, .poll = pxa_camera_poll, .querycap = pxa_camera_querycap, @@ -1009,8 +1021,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { /* Should be allocated dynamically too, but we have only one. */ static struct soc_camera_host pxa_soc_camera_host = { .drv_name = PXA_CAM_DRV_NAME, - .vbq_ops = &pxa_videobuf_ops, - .msize = sizeof(struct pxa_buffer), .ops = &pxa_soc_camera_host_ops, }; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 8ae2d9916d9f..38a89f133164 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -26,6 +26,7 @@ #include #include +#include #include static LIST_HEAD(hosts); @@ -233,11 +234,7 @@ static int soc_camera_open(struct inode *inode, struct file *file) file->private_data = icf; dev_dbg(&icd->dev, "camera device open\n"); - /* We must pass NULL as dev pointer, then all pci_* dma operations - * transform to normal dma_* ones. */ - videobuf_queue_sg_init(&icf->vb_vidq, ici->vbq_ops, NULL, icf->lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, - ici->msize, icd); + ici->ops->init_videobuf(&icf->vb_vidq, icf->lock, icd); return 0; @@ -787,7 +784,7 @@ int soc_camera_host_register(struct soc_camera_host *ici) int ret; struct soc_camera_host *ix; - if (!ici->vbq_ops || !ici->ops->add || !ici->ops->remove) + if (!ici->ops->init_videobuf || !ici->ops->add || !ici->ops->remove) return -EINVAL; /* Number might be equal to the platform device ID */ diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 6a8c8be7a1ae..b204c0dee956 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -13,7 +13,7 @@ #define SOC_CAMERA_H #include -#include +#include struct soc_camera_device { struct list_head list; @@ -55,8 +55,6 @@ struct soc_camera_host { struct list_head list; struct device dev; unsigned char nr; /* Host number */ - size_t msize; - struct videobuf_queue_ops *vbq_ops; void *priv; char *drv_name; struct soc_camera_host_ops *ops; @@ -69,6 +67,8 @@ struct soc_camera_host_ops { int (*set_fmt_cap)(struct soc_camera_device *, __u32, struct v4l2_rect *); int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); + void (*init_videobuf)(struct videobuf_queue*, spinlock_t *, + struct soc_camera_device *); int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); int (*try_bus_param)(struct soc_camera_device *, __u32); -- cgit v1.2.3 From a034d1b76b173b37f9a3646aa8f50a2c14a0f3ea Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 11 Jul 2008 20:59:34 -0300 Subject: V4L/DVB (8338): soc_camera: Move spinlocks This patch moves the spinlock handling from soc_camera.c to the actual camera host driver. The spinlock_alloc/free callbacks are replaced with code in init_videobuf(). So far all camera host drivers implement their own spinlock_alloc/free methods anyway, and videobuf_queue_core_init() BUGs on a NULL spinlock argument, so, new camera host drivers will not forget to provide a spinlock when initialising their videobuf queues. Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pxa_camera.c | 17 +++++------------ drivers/media/video/soc_camera.c | 39 +-------------------------------------- include/media/soc_camera.h | 5 +---- 3 files changed, 7 insertions(+), 54 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index c3a7d476dc4b..b15f82c49766 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c @@ -583,12 +583,15 @@ static struct videobuf_queue_ops pxa_videobuf_ops = { .buf_release = pxa_videobuf_release, }; -static void pxa_camera_init_videobuf(struct videobuf_queue *q, spinlock_t *lock, +static void pxa_camera_init_videobuf(struct videobuf_queue *q, struct soc_camera_device *icd) { + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct pxa_camera_dev *pcdev = ici->priv; + /* We must pass NULL as dev pointer, then all pci_* dma operations * transform to normal dma_* ones. */ - videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, lock, + videobuf_queue_sg_init(q, &pxa_videobuf_ops, NULL, &pcdev->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, sizeof(struct pxa_buffer), icd); } @@ -994,15 +997,6 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, return 0; } -static spinlock_t *pxa_camera_spinlock_alloc(struct soc_camera_file *icf) -{ - struct soc_camera_host *ici = - to_soc_camera_host(icf->icd->dev.parent); - struct pxa_camera_dev *pcdev = ici->priv; - - return &pcdev->lock; -} - static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .owner = THIS_MODULE, .add = pxa_camera_add_device, @@ -1015,7 +1009,6 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .querycap = pxa_camera_querycap, .try_bus_param = pxa_camera_try_bus_param, .set_bus_param = pxa_camera_set_bus_param, - .spinlock_alloc = pxa_camera_spinlock_alloc, }; /* Should be allocated dynamically too, but we have only one. */ diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 38a89f133164..e39b98f1eca4 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -183,7 +183,6 @@ static int soc_camera_open(struct inode *inode, struct file *file) struct soc_camera_device *icd; struct soc_camera_host *ici; struct soc_camera_file *icf; - spinlock_t *lock; int ret; icf = vmalloc(sizeof(*icf)); @@ -210,13 +209,6 @@ static int soc_camera_open(struct inode *inode, struct file *file) } icf->icd = icd; - - icf->lock = ici->ops->spinlock_alloc(icf); - if (!icf->lock) { - ret = -ENOMEM; - goto esla; - } - icd->use_count++; /* Now we really have to activate the camera */ @@ -234,17 +226,12 @@ static int soc_camera_open(struct inode *inode, struct file *file) file->private_data = icf; dev_dbg(&icd->dev, "camera device open\n"); - ici->ops->init_videobuf(&icf->vb_vidq, icf->lock, icd); + ici->ops->init_videobuf(&icf->vb_vidq, icd); return 0; /* All errors are entered with the video_lock held */ eiciadd: - lock = icf->lock; - icf->lock = NULL; - if (ici->ops->spinlock_free) - ici->ops->spinlock_free(lock); -esla: module_put(ici->ops->owner); emgi: module_put(icd->ops->owner); @@ -260,15 +247,11 @@ static int soc_camera_close(struct inode *inode, struct file *file) struct soc_camera_device *icd = icf->icd; struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct video_device *vdev = icd->vdev; - spinlock_t *lock = icf->lock; mutex_lock(&video_lock); icd->use_count--; if (!icd->use_count) ici->ops->remove(icd); - icf->lock = NULL; - if (ici->ops->spinlock_free) - ici->ops->spinlock_free(lock); module_put(icd->ops->owner); module_put(ici->ops->owner); mutex_unlock(&video_lock); @@ -764,21 +747,6 @@ static void dummy_release(struct device *dev) { } -static spinlock_t *spinlock_alloc(struct soc_camera_file *icf) -{ - spinlock_t *lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL); - - if (lock) - spin_lock_init(lock); - - return lock; -} - -static void spinlock_free(spinlock_t *lock) -{ - kfree(lock); -} - int soc_camera_host_register(struct soc_camera_host *ici) { int ret; @@ -808,11 +776,6 @@ int soc_camera_host_register(struct soc_camera_host *ici) if (ret) goto edevr; - if (!ici->ops->spinlock_alloc) { - ici->ops->spinlock_alloc = spinlock_alloc; - ici->ops->spinlock_free = spinlock_free; - } - scan_add_host(ici); return 0; diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index b204c0dee956..bae160213657 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -48,7 +48,6 @@ struct soc_camera_device { struct soc_camera_file { struct soc_camera_device *icd; struct videobuf_queue vb_vidq; - spinlock_t *lock; }; struct soc_camera_host { @@ -67,15 +66,13 @@ struct soc_camera_host_ops { int (*set_fmt_cap)(struct soc_camera_device *, __u32, struct v4l2_rect *); int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); - void (*init_videobuf)(struct videobuf_queue*, spinlock_t *, + void (*init_videobuf)(struct videobuf_queue *, struct soc_camera_device *); int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); int (*try_bus_param)(struct soc_camera_device *, __u32); int (*set_bus_param)(struct soc_camera_device *, __u32); unsigned int (*poll)(struct file *, poll_table *); - spinlock_t* (*spinlock_alloc)(struct soc_camera_file *); - void (*spinlock_free)(spinlock_t *); }; struct soc_camera_link { -- cgit v1.2.3 From 5d6aaf50e2986d3289d16fc2859c490c66a1be63 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 16 Jul 2008 21:27:49 -0300 Subject: V4L/DVB (8340): videobuf: Fix gather spelling Use "scatter gather" instead of "scatter gatter". Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-sg.c | 2 +- drivers/media/video/videobuf-vmalloc.c | 2 +- include/media/videobuf-dma-sg.h | 2 +- include/media/videobuf-vmalloc.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c index 8ed60827d350..bc6d5aba0fe6 100644 --- a/drivers/media/video/videobuf-dma-sg.c +++ b/drivers/media/video/videobuf-dma-sg.c @@ -1,7 +1,7 @@ /* * helper functions for SG DMA video4linux capture buffers * - * The functions expect the hardware being able to scatter gatter + * The functions expect the hardware being able to scatter gather * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need * to touch the video data. diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index c91e1d8e3802..a868b7ed75ff 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -1,7 +1,7 @@ /* * helper functions for vmalloc video4linux capture buffers * - * The functions expect the hardware being able to scatter gatter + * The functions expect the hardware being able to scatter gather * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need * to touch the video data. diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index be8da269ee33..90edd22d343c 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -1,7 +1,7 @@ /* * helper functions for SG DMA video4linux capture buffers * - * The functions expect the hardware being able to scatter gatter + * The functions expect the hardware being able to scatter gather * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need * to touch the video data. diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index aed39460c154..e87222c6a125 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h @@ -1,7 +1,7 @@ /* * helper functions for vmalloc capture buffers * - * The functions expect the hardware being able to scatter gatter + * The functions expect the hardware being able to scatter gather * (i.e. the buffers are not linear in physical memory, but fragmented * into PAGE_SIZE chunks). They also assume the driver does not need * to touch the video data. -- cgit v1.2.3 From 2cc45cf25a2c14da6d18b7570a23ec09fb8f439a Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 16 Jul 2008 21:33:39 -0300 Subject: V4L/DVB (8341): videobuf: Add physically contiguous queue code V3 This is V3 of the physically contiguous videobuf queues patch. Useful for hardware such as the SuperH Mobile CEU which doesn't support scatter gatter bus mastering. Since it may be difficult to allocate large chunks of physically contiguous memory after some uptime due to fragmentation, this code allocates memory using dma_alloc_coherent(). Architectures supporting dma_declare_coherent_memory() can easily avoid fragmentation issues by using dma_declare_coherent_memory() to force dma_alloc_coherent() to allocate from a certain pre-allocated memory area. Changes since V2 - use dma_handle for physical address - use "scatter gather" instead of "scatter gatter" Changes since V1: - use dev_err() instead of pr_err() - remember size in struct videobuf_dma_contig_memory - keep struct videobuf_dma_contig_memory in .c file - let videobuf_to_dma_contig() return dma_addr_t - implement __videobuf_sync() - return statements, white space and other minor fixes Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 5 + drivers/media/video/Makefile | 1 + drivers/media/video/videobuf-dma-contig.c | 417 ++++++++++++++++++++++++++++++ include/media/videobuf-dma-contig.h | 32 +++ 4 files changed, 455 insertions(+) create mode 100644 drivers/media/video/videobuf-dma-contig.c create mode 100644 include/media/videobuf-dma-contig.h (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 2103f7bfd48c..9a4265e5cd84 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -24,6 +24,11 @@ config VIDEOBUF_VMALLOC select VIDEOBUF_GEN tristate +config VIDEOBUF_DMA_CONTIG + depends on HAS_DMA + select VIDEOBUF_GEN + tristate + config VIDEOBUF_DVB tristate select VIDEOBUF_GEN diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index d5f6eea7d2fd..3106eaa893d6 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -88,6 +88,7 @@ obj-$(CONFIG_VIDEO_TUNER) += tuner.o obj-$(CONFIG_VIDEOBUF_GEN) += videobuf-core.o obj-$(CONFIG_VIDEOBUF_DMA_SG) += videobuf-dma-sg.o +obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += videobuf-dma-contig.o obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c new file mode 100644 index 000000000000..2475535cbe7f --- /dev/null +++ b/drivers/media/video/videobuf-dma-contig.c @@ -0,0 +1,417 @@ +/* + * helper functions for physically contiguous capture buffers + * + * The functions support hardware lacking scatter gather support + * (i.e. the buffers must be linear in physical memory) + * + * Copyright (c) 2008 Magnus Damm + * + * Based on videobuf-vmalloc.c, + * (c) 2007 Mauro Carvalho Chehab, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 + */ + +#include +#include +#include +#include + +struct videobuf_dma_contig_memory { + u32 magic; + void *vaddr; + dma_addr_t dma_handle; + unsigned long size; +}; + +#define MAGIC_DC_MEM 0x0733ac61 +#define MAGIC_CHECK(is, should) \ + if (unlikely((is) != (should))) { \ + pr_err("magic mismatch: %x expected %x\n", is, should); \ + BUG(); \ + } + +static void +videobuf_vm_open(struct vm_area_struct *vma) +{ + struct videobuf_mapping *map = vma->vm_private_data; + + dev_dbg(map->q->dev, "vm_open %p [count=%u,vma=%08lx-%08lx]\n", + map, map->count, vma->vm_start, vma->vm_end); + + map->count++; +} + +static void videobuf_vm_close(struct vm_area_struct *vma) +{ + struct videobuf_mapping *map = vma->vm_private_data; + struct videobuf_queue *q = map->q; + int i; + + dev_dbg(map->q->dev, "vm_close %p [count=%u,vma=%08lx-%08lx]\n", + map, map->count, vma->vm_start, vma->vm_end); + + map->count--; + if (0 == map->count) { + struct videobuf_dma_contig_memory *mem; + + dev_dbg(map->q->dev, "munmap %p q=%p\n", map, q); + mutex_lock(&q->vb_lock); + + /* We need first to cancel streams, before unmapping */ + if (q->streaming) + videobuf_queue_cancel(q); + + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + if (NULL == q->bufs[i]) + continue; + + if (q->bufs[i]->map != map) + continue; + + mem = q->bufs[i]->priv; + if (mem) { + /* This callback is called only if kernel has + allocated memory and this memory is mmapped. + In this case, memory should be freed, + in order to do memory unmap. + */ + + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + /* vfree is not atomic - can't be + called with IRQ's disabled + */ + dev_dbg(map->q->dev, "buf[%d] freeing %p\n", + i, mem->vaddr); + + dma_free_coherent(q->dev, mem->size, + mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; + } + + q->bufs[i]->map = NULL; + q->bufs[i]->baddr = 0; + } + + kfree(map); + + mutex_unlock(&q->vb_lock); + } +} + +static struct vm_operations_struct videobuf_vm_ops = { + .open = videobuf_vm_open, + .close = videobuf_vm_close, +}; + +static void *__videobuf_alloc(size_t size) +{ + struct videobuf_dma_contig_memory *mem; + struct videobuf_buffer *vb; + + vb = kzalloc(size + sizeof(*mem), GFP_KERNEL); + if (vb) { + mem = vb->priv = ((char *)vb) + size; + mem->magic = MAGIC_DC_MEM; + } + + return vb; +} + +static void *__videobuf_to_vmalloc(struct videobuf_buffer *buf) +{ + struct videobuf_dma_contig_memory *mem = buf->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + return mem->vaddr; +} + +static int __videobuf_iolock(struct videobuf_queue *q, + struct videobuf_buffer *vb, + struct v4l2_framebuffer *fbuf) +{ + struct videobuf_dma_contig_memory *mem = vb->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + switch (vb->memory) { + case V4L2_MEMORY_MMAP: + dev_dbg(q->dev, "%s memory method MMAP\n", __func__); + + /* All handling should be done by __videobuf_mmap_mapper() */ + if (!mem->vaddr) { + dev_err(q->dev, "memory is not alloced/mmapped.\n"); + return -EINVAL; + } + break; + case V4L2_MEMORY_USERPTR: + dev_dbg(q->dev, "%s memory method USERPTR\n", __func__); + + /* The only USERPTR currently supported is the one needed for + read() method. + */ + if (vb->baddr) + return -EINVAL; + + mem->size = PAGE_ALIGN(vb->size); + mem->vaddr = dma_alloc_coherent(q->dev, mem->size, + &mem->dma_handle, GFP_KERNEL); + if (!mem->vaddr) { + dev_err(q->dev, "dma_alloc_coherent %ld failed\n", + mem->size); + return -ENOMEM; + } + + dev_dbg(q->dev, "dma_alloc_coherent data is at %p (%ld)\n", + mem->vaddr, mem->size); + break; + case V4L2_MEMORY_OVERLAY: + default: + dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", + __func__); + return -EINVAL; + } + + return 0; +} + +static int __videobuf_sync(struct videobuf_queue *q, + struct videobuf_buffer *buf) +{ + struct videobuf_dma_contig_memory *mem = buf->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size, + DMA_FROM_DEVICE); + return 0; +} + +static int __videobuf_mmap_free(struct videobuf_queue *q) +{ + unsigned int i; + + dev_dbg(q->dev, "%s\n", __func__); + for (i = 0; i < VIDEO_MAX_FRAME; i++) { + if (q->bufs[i] && q->bufs[i]->map) + return -EBUSY; + } + + return 0; +} + +static int __videobuf_mmap_mapper(struct videobuf_queue *q, + struct vm_area_struct *vma) +{ + struct videobuf_dma_contig_memory *mem; + struct videobuf_mapping *map; + unsigned int first; + int retval; + unsigned long size, offset = vma->vm_pgoff << PAGE_SHIFT; + + dev_dbg(q->dev, "%s\n", __func__); + if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) + return -EINVAL; + + /* look for first buffer to map */ + for (first = 0; first < VIDEO_MAX_FRAME; first++) { + if (!q->bufs[first]) + continue; + + if (V4L2_MEMORY_MMAP != q->bufs[first]->memory) + continue; + if (q->bufs[first]->boff == offset) + break; + } + if (VIDEO_MAX_FRAME == first) { + dev_dbg(q->dev, "invalid user space offset [offset=0x%lx]\n", + offset); + return -EINVAL; + } + + /* create mapping + update buffer list */ + map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL); + if (!map) + return -ENOMEM; + + q->bufs[first]->map = map; + map->start = vma->vm_start; + map->end = vma->vm_end; + map->q = q; + + q->bufs[first]->baddr = vma->vm_start; + + mem = q->bufs[first]->priv; + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + mem->size = PAGE_ALIGN(q->bufs[first]->bsize); + mem->vaddr = dma_alloc_coherent(q->dev, mem->size, + &mem->dma_handle, GFP_KERNEL); + if (!mem->vaddr) { + dev_err(q->dev, "dma_alloc_coherent size %ld failed\n", + mem->size); + goto error; + } + dev_dbg(q->dev, "dma_alloc_coherent data is at addr %p (size %ld)\n", + mem->vaddr, mem->size); + + /* Try to remap memory */ + + size = vma->vm_end - vma->vm_start; + size = (size < mem->size) ? size : mem->size; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + retval = remap_pfn_range(vma, vma->vm_start, + mem->dma_handle >> PAGE_SHIFT, + size, vma->vm_page_prot); + if (retval) { + dev_err(q->dev, "mmap: remap failed with error %d. ", retval); + dma_free_coherent(q->dev, mem->size, + mem->vaddr, mem->dma_handle); + goto error; + } + + vma->vm_ops = &videobuf_vm_ops; + vma->vm_flags |= VM_DONTEXPAND; + vma->vm_private_data = map; + + dev_dbg(q->dev, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n", + map, q, vma->vm_start, vma->vm_end, + (long int) q->bufs[first]->bsize, + vma->vm_pgoff, first); + + videobuf_vm_open(vma); + + return 0; + +error: + kfree(map); + return -ENOMEM; +} + +static int __videobuf_copy_to_user(struct videobuf_queue *q, + char __user *data, size_t count, + int nonblocking) +{ + struct videobuf_dma_contig_memory *mem = q->read_buf->priv; + void *vaddr; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + BUG_ON(!mem->vaddr); + + /* copy to userspace */ + if (count > q->read_buf->size - q->read_off) + count = q->read_buf->size - q->read_off; + + vaddr = mem->vaddr; + + if (copy_to_user(data, vaddr + q->read_off, count)) + return -EFAULT; + + return count; +} + +static int __videobuf_copy_stream(struct videobuf_queue *q, + char __user *data, size_t count, size_t pos, + int vbihack, int nonblocking) +{ + unsigned int *fc; + struct videobuf_dma_contig_memory *mem = q->read_buf->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + if (vbihack) { + /* dirty, undocumented hack -- pass the frame counter + * within the last four bytes of each vbi data block. + * We need that one to maintain backward compatibility + * to all vbi decoding software out there ... */ + fc = (unsigned int *)mem->vaddr; + fc += (q->read_buf->size >> 2) - 1; + *fc = q->read_buf->field_count >> 1; + dev_dbg(q->dev, "vbihack: %d\n", *fc); + } + + /* copy stuff using the common method */ + count = __videobuf_copy_to_user(q, data, count, nonblocking); + + if ((count == -EFAULT) && (pos == 0)) + return -EFAULT; + + return count; +} + +static struct videobuf_qtype_ops qops = { + .magic = MAGIC_QTYPE_OPS, + + .alloc = __videobuf_alloc, + .iolock = __videobuf_iolock, + .sync = __videobuf_sync, + .mmap_free = __videobuf_mmap_free, + .mmap_mapper = __videobuf_mmap_mapper, + .video_copy_to_user = __videobuf_copy_to_user, + .copy_stream = __videobuf_copy_stream, + .vmalloc = __videobuf_to_vmalloc, +}; + +void videobuf_queue_dma_contig_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv) +{ + videobuf_queue_core_init(q, ops, dev, irqlock, type, field, msize, + priv, &qops); +} +EXPORT_SYMBOL_GPL(videobuf_queue_dma_contig_init); + +dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf) +{ + struct videobuf_dma_contig_memory *mem = buf->priv; + + BUG_ON(!mem); + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + return mem->dma_handle; +} +EXPORT_SYMBOL_GPL(videobuf_to_dma_contig); + +void videobuf_dma_contig_free(struct videobuf_queue *q, + struct videobuf_buffer *buf) +{ + struct videobuf_dma_contig_memory *mem = buf->priv; + + /* mmapped memory can't be freed here, otherwise mmapped region + would be released, while still needed. In this case, the memory + release should happen inside videobuf_vm_close(). + So, it should free memory only if the memory were allocated for + read() operation. + */ + if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr) + return; + + if (!mem) + return; + + MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); + + dma_free_coherent(q->dev, mem->size, mem->vaddr, mem->dma_handle); + mem->vaddr = NULL; +} +EXPORT_SYMBOL_GPL(videobuf_dma_contig_free); + +MODULE_DESCRIPTION("helper module to manage video4linux dma contig buffers"); +MODULE_AUTHOR("Magnus Damm"); +MODULE_LICENSE("GPL"); diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h new file mode 100644 index 000000000000..549386681aab --- /dev/null +++ b/include/media/videobuf-dma-contig.h @@ -0,0 +1,32 @@ +/* + * helper functions for physically contiguous capture buffers + * + * The functions support hardware lacking scatter gather support + * (i.e. the buffers must be linear in physical memory) + * + * Copyright (c) 2008 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 + */ +#ifndef _VIDEOBUF_DMA_CONTIG_H +#define _VIDEOBUF_DMA_CONTIG_H + +#include +#include + +void videobuf_queue_dma_contig_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv); + +dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); +void videobuf_dma_contig_free(struct videobuf_queue *q, + struct videobuf_buffer *buf); + +#endif /* _VIDEOBUF_DMA_CONTIG_H */ -- cgit v1.2.3 From 0d3244d6439c8c31d2a29efd587c7aca9042c8aa Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 16 Jul 2008 22:59:28 -0300 Subject: V4L/DVB (8342): sh_mobile_ceu_camera: Add SuperH Mobile CEU driver V3 This is V3 of the SuperH Mobile CEU soc_camera driver. The CEU hardware block is configured in a transparent data fetch mode, frames are captured from the attached camera and written to physically contiguous memory buffers provided by the newly added videobuf-dma-contig queue. Tested on sh7722 and sh7723 processors. Changes since V2: - remove SUPERH Kconfig dependency - move sh_mobile_ceu.h to include/media - add board callback support with enable_camera()/disable_camera() - add support for declare_coherent_memory - rework video memory limit - more verbose error messages Changes since V1: - fixed the CEU driver to work with the newly updated patches Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 8 + drivers/media/video/Makefile | 1 + drivers/media/video/sh_mobile_ceu_camera.c | 657 +++++++++++++++++++++++++++++ include/media/sh_mobile_ceu.h | 12 + 4 files changed, 678 insertions(+) create mode 100644 drivers/media/video/sh_mobile_ceu_camera.c create mode 100644 include/media/sh_mobile_ceu.h (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 9a4265e5cd84..fdeaff257caf 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -969,4 +969,12 @@ config VIDEO_PXA27x ---help--- This is a v4l2 driver for the PXA27x Quick Capture Interface +config VIDEO_SH_MOBILE_CEU + tristate "SuperH Mobile CEU Interface driver" + depends on VIDEO_DEV + select SOC_CAMERA + select VIDEOBUF_DMA_CONTIG + ---help--- + This is a v4l2 driver for the SuperH Mobile CEU Interface + endif # VIDEO_CAPTURE_DRIVERS diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 3106eaa893d6..6dd51b01ef90 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -133,6 +133,7 @@ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o +obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c new file mode 100644 index 000000000000..6560ff496989 --- /dev/null +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -0,0 +1,657 @@ +/* + * V4L2 Driver for SuperH Mobile CEU interface + * + * Copyright (C) 2008 Magnus Damm + * + * Based on V4L2 Driver for PXA camera host - "pxa_camera.c", + * + * Copyright (C) 2006, Sascha Hauer, Pengutronix + * Copyright (C) 2008, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* register offsets for sh7722 / sh7723 */ + +#define CAPSR 0x00 +#define CAPCR 0x04 +#define CAMCR 0x08 +#define CMCYR 0x0c +#define CAMOR 0x10 +#define CAPWR 0x14 +#define CAIFR 0x18 +#define CSTCR 0x20 /* not on sh7723 */ +#define CSECR 0x24 /* not on sh7723 */ +#define CRCNTR 0x28 +#define CRCMPR 0x2c +#define CFLCR 0x30 +#define CFSZR 0x34 +#define CDWDR 0x38 +#define CDAYR 0x3c +#define CDACR 0x40 +#define CDBYR 0x44 +#define CDBCR 0x48 +#define CBDSR 0x4c +#define CFWCR 0x5c +#define CLFCR 0x60 +#define CDOCR 0x64 +#define CDDCR 0x68 +#define CDDAR 0x6c +#define CEIER 0x70 +#define CETCR 0x74 +#define CSTSR 0x7c +#define CSRTR 0x80 +#define CDSSR 0x84 +#define CDAYR2 0x90 +#define CDACR2 0x94 +#define CDBYR2 0x98 +#define CDBCR2 0x9c + +static DEFINE_MUTEX(camera_lock); + +/* per video frame buffer */ +struct sh_mobile_ceu_buffer { + struct videobuf_buffer vb; /* v4l buffer must be first */ + const struct soc_camera_data_format *fmt; +}; + +struct sh_mobile_ceu_dev { + struct device *dev; + struct soc_camera_host ici; + struct soc_camera_device *icd; + + unsigned int irq; + void __iomem *base; + unsigned long video_limit; + + spinlock_t lock; + struct list_head capture; + struct videobuf_buffer *active; + + struct sh_mobile_ceu_info *pdata; +}; + +static void ceu_write(struct sh_mobile_ceu_dev *priv, + unsigned long reg_offs, unsigned long data) +{ + iowrite32(data, priv->base + reg_offs); +} + +static unsigned long ceu_read(struct sh_mobile_ceu_dev *priv, + unsigned long reg_offs) +{ + return ioread32(priv->base + reg_offs); +} + +/* + * Videobuf operations + */ +static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq, + unsigned int *count, + unsigned int *size) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; + + *size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel); + + if (0 == *count) + *count = 2; + + if (pcdev->video_limit) { + while (*size * *count > pcdev->video_limit) + (*count)--; + } + + dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); + + return 0; +} + +static void free_buffer(struct videobuf_queue *vq, + struct sh_mobile_ceu_buffer *buf) +{ + struct soc_camera_device *icd = vq->priv_data; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + &buf->vb, buf->vb.baddr, buf->vb.bsize); + + if (in_interrupt()) + BUG(); + + videobuf_dma_contig_free(vq, &buf->vb); + dev_dbg(&icd->dev, "%s freed\n", __func__); + buf->vb.state = VIDEOBUF_NEEDS_INIT; +} + +static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) +{ + ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1); + ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313); + ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | 1); + + ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~0x10000); + + ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10); + + if (pcdev->active) { + ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active)); + ceu_write(pcdev, CAPSR, 0x1); /* start capture */ + } +} + +static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, + struct videobuf_buffer *vb, + enum v4l2_field field) +{ + struct soc_camera_device *icd = vq->priv_data; + struct sh_mobile_ceu_buffer *buf; + int ret; + + buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + vb, vb->baddr, vb->bsize); + + /* Added list head initialization on alloc */ + WARN_ON(!list_empty(&vb->queue)); + +#ifdef DEBUG + /* This can be useful if you want to see if we actually fill + * the buffer with something */ + memset((void *)vb->baddr, 0xaa, vb->bsize); +#endif + + BUG_ON(NULL == icd->current_fmt); + + if (buf->fmt != icd->current_fmt || + vb->width != icd->width || + vb->height != icd->height || + vb->field != field) { + buf->fmt = icd->current_fmt; + vb->width = icd->width; + vb->height = icd->height; + vb->field = field; + vb->state = VIDEOBUF_NEEDS_INIT; + } + + vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3); + if (0 != vb->baddr && vb->bsize < vb->size) { + ret = -EINVAL; + goto out; + } + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + ret = videobuf_iolock(vq, vb, NULL); + if (ret) + goto fail; + vb->state = VIDEOBUF_PREPARED; + } + + return 0; +fail: + free_buffer(vq, buf); +out: + return ret; +} + +static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + unsigned long flags; + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + vb, vb->baddr, vb->bsize); + + vb->state = VIDEOBUF_ACTIVE; + spin_lock_irqsave(&pcdev->lock, flags); + list_add_tail(&vb->queue, &pcdev->capture); + + if (!pcdev->active) { + pcdev->active = vb; + sh_mobile_ceu_capture(pcdev); + } + + spin_unlock_irqrestore(&pcdev->lock, flags); +} + +static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); +} + +static struct videobuf_queue_ops sh_mobile_ceu_videobuf_ops = { + .buf_setup = sh_mobile_ceu_videobuf_setup, + .buf_prepare = sh_mobile_ceu_videobuf_prepare, + .buf_queue = sh_mobile_ceu_videobuf_queue, + .buf_release = sh_mobile_ceu_videobuf_release, +}; + +static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) +{ + struct sh_mobile_ceu_dev *pcdev = data; + struct videobuf_buffer *vb; + unsigned long flags; + + spin_lock_irqsave(&pcdev->lock, flags); + + vb = pcdev->active; + list_del_init(&vb->queue); + + if (!list_empty(&pcdev->capture)) + pcdev->active = list_entry(pcdev->capture.next, + struct videobuf_buffer, queue); + else + pcdev->active = NULL; + + sh_mobile_ceu_capture(pcdev); + + vb->state = VIDEOBUF_DONE; + do_gettimeofday(&vb->ts); + vb->field_count++; + wake_up(&vb->done); + spin_unlock_irqrestore(&pcdev->lock, flags); + + return IRQ_HANDLED; +} + +static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + int ret = -EBUSY; + + mutex_lock(&camera_lock); + + if (pcdev->icd) + goto err; + + dev_info(&icd->dev, + "SuperH Mobile CEU driver attached to camera %d\n", + icd->devnum); + + if (pcdev->pdata->enable_camera) + pcdev->pdata->enable_camera(); + + ret = icd->ops->init(icd); + if (ret) + goto err; + + ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ + while (ceu_read(pcdev, CSTSR) & 1) + msleep(1); + + pcdev->icd = icd; +err: + mutex_unlock(&camera_lock); + + return ret; +} + +static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + + BUG_ON(icd != pcdev->icd); + + /* disable capture, disable interrupts */ + ceu_write(pcdev, CEIER, 0); + ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ + icd->ops->release(icd); + if (pcdev->pdata->disable_camera) + pcdev->pdata->disable_camera(); + + dev_info(&icd->dev, + "SuperH Mobile CEU driver detached from camera %d\n", + icd->devnum); + + pcdev->icd = NULL; +} + +static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, + __u32 pixfmt) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + int ret, buswidth, width, cfszr_width, cdwdr_width; + unsigned long camera_flags, common_flags, value; + + camera_flags = icd->ops->query_bus_param(icd); + common_flags = soc_camera_bus_param_compatible(camera_flags, + pcdev->pdata->flags); + if (!common_flags) + return -EINVAL; + + ret = icd->ops->set_bus_param(icd, common_flags); + if (ret < 0) + return ret; + + switch (common_flags & SOCAM_DATAWIDTH_MASK) { + case SOCAM_DATAWIDTH_8: + buswidth = 8; + break; + case SOCAM_DATAWIDTH_16: + buswidth = 16; + break; + default: + return -EINVAL; + } + + ceu_write(pcdev, CRCNTR, 0); + ceu_write(pcdev, CRCMPR, 0); + + value = 0x00000010; + value |= (common_flags & SOCAM_VSYNC_ACTIVE_LOW) ? (1 << 1) : 0; + value |= (common_flags & SOCAM_HSYNC_ACTIVE_LOW) ? (1 << 0) : 0; + value |= (buswidth == 16) ? (1 << 12) : 0; + ceu_write(pcdev, CAMCR, value); + + ceu_write(pcdev, CAPCR, 0x00300000); + ceu_write(pcdev, CAIFR, 0); + + mdelay(1); + + width = icd->width * (icd->current_fmt->depth / 8); + width = (buswidth == 16) ? width / 2 : width; + cfszr_width = (buswidth == 8) ? width / 2 : width; + cdwdr_width = (buswidth == 16) ? width * 2 : width; + + ceu_write(pcdev, CAMOR, 0); + ceu_write(pcdev, CAPWR, (icd->height << 16) | width); + ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */ + ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); + ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */ + ceu_write(pcdev, CDOCR, 0x00000016); + + ceu_write(pcdev, CDWDR, cdwdr_width); + ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ + + /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */ + /* in data fetch mode: no need for CDACR, CDBYR, CDBCR */ + + return 0; +} + +static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, + __u32 pixfmt) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + unsigned long camera_flags, common_flags; + + camera_flags = icd->ops->query_bus_param(icd); + common_flags = soc_camera_bus_param_compatible(camera_flags, + pcdev->pdata->flags); + if (!common_flags) + return -EINVAL; + + return 0; +} + +static int sh_mobile_ceu_set_fmt_cap(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + return icd->ops->set_fmt_cap(icd, pixfmt, rect); +} + +static int sh_mobile_ceu_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + /* FIXME: calculate using depth and bus width */ + + if (f->fmt.pix.height < 4) + f->fmt.pix.height = 4; + if (f->fmt.pix.height > 1920) + f->fmt.pix.height = 1920; + if (f->fmt.pix.width < 2) + f->fmt.pix.width = 2; + if (f->fmt.pix.width > 2560) + f->fmt.pix.width = 2560; + f->fmt.pix.width &= ~0x01; + f->fmt.pix.height &= ~0x03; + + /* limit to sensor capabilities */ + return icd->ops->try_fmt_cap(icd, f); +} + +static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, + struct v4l2_requestbuffers *p) +{ + int i; + + /* This is for locking debugging only. I removed spinlocks and now I + * check whether .prepare is ever called on a linked buffer, or whether + * a dma IRQ can occur for an in-work or unlinked buffer. Until now + * it hadn't triggered */ + for (i = 0; i < p->count; i++) { + struct sh_mobile_ceu_buffer *buf; + + buf = container_of(icf->vb_vidq.bufs[i], + struct sh_mobile_ceu_buffer, vb); + INIT_LIST_HEAD(&buf->vb.queue); + } + + return 0; +} + +static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_file *icf = file->private_data; + struct sh_mobile_ceu_buffer *buf; + + buf = list_entry(icf->vb_vidq.stream.next, + struct sh_mobile_ceu_buffer, vb.stream); + + poll_wait(file, &buf->vb.done, pt); + + if (buf->vb.state == VIDEOBUF_DONE || + buf->vb.state == VIDEOBUF_ERROR) + return POLLIN|POLLRDNORM; + + return 0; +} + +static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, + struct v4l2_capability *cap) +{ + strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card)); + cap->version = KERNEL_VERSION(0, 0, 5); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + return 0; +} + +static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, + struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; + + videobuf_queue_dma_contig_init(q, + &sh_mobile_ceu_videobuf_ops, + &ici->dev, &pcdev->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_NONE, + sizeof(struct sh_mobile_ceu_buffer), + icd); +} + +static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { + .owner = THIS_MODULE, + .add = sh_mobile_ceu_add_device, + .remove = sh_mobile_ceu_remove_device, + .set_fmt_cap = sh_mobile_ceu_set_fmt_cap, + .try_fmt_cap = sh_mobile_ceu_try_fmt_cap, + .reqbufs = sh_mobile_ceu_reqbufs, + .poll = sh_mobile_ceu_poll, + .querycap = sh_mobile_ceu_querycap, + .try_bus_param = sh_mobile_ceu_try_bus_param, + .set_bus_param = sh_mobile_ceu_set_bus_param, + .init_videobuf = sh_mobile_ceu_init_videobuf, +}; + +static int sh_mobile_ceu_probe(struct platform_device *pdev) +{ + struct sh_mobile_ceu_dev *pcdev; + struct resource *res; + void __iomem *base; + unsigned int irq; + int err = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq = platform_get_irq(pdev, 0); + if (!res || !irq) { + dev_err(&pdev->dev, "Not enough CEU platform resources.\n"); + err = -ENODEV; + goto exit; + } + + pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL); + if (!pcdev) { + dev_err(&pdev->dev, "Could not allocate pcdev\n"); + err = -ENOMEM; + goto exit; + } + + platform_set_drvdata(pdev, pcdev); + INIT_LIST_HEAD(&pcdev->capture); + spin_lock_init(&pcdev->lock); + + pcdev->pdata = pdev->dev.platform_data; + if (!pcdev->pdata) { + err = -EINVAL; + dev_err(&pdev->dev, "CEU platform data not set.\n"); + goto exit_kfree; + } + + base = ioremap_nocache(res->start, res->end - res->start + 1); + if (!base) { + err = -ENXIO; + dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n"); + goto exit_kfree; + } + + pcdev->irq = irq; + pcdev->base = base; + pcdev->video_limit = 0; /* only enabled if second resource exists */ + pcdev->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (res) { + err = dma_declare_coherent_memory(&pdev->dev, res->start, + res->start, + (res->end - res->start) + 1, + DMA_MEMORY_MAP | + DMA_MEMORY_EXCLUSIVE); + if (!err) { + dev_err(&pdev->dev, "Unable to declare CEU memory.\n"); + err = -ENXIO; + goto exit_iounmap; + } + + pcdev->video_limit = (res->end - res->start) + 1; + } + + /* request irq */ + err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED, + pdev->dev.bus_id, pcdev); + if (err) { + dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); + goto exit_release_mem; + } + + pcdev->ici.priv = pcdev; + pcdev->ici.dev.parent = &pdev->dev; + pcdev->ici.nr = pdev->id; + pcdev->ici.drv_name = pdev->dev.bus_id, + pcdev->ici.ops = &sh_mobile_ceu_host_ops, + + err = soc_camera_host_register(&pcdev->ici); + if (err) + goto exit_free_irq; + + return 0; + +exit_free_irq: + free_irq(pcdev->irq, pcdev); +exit_release_mem: + if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) + dma_release_declared_memory(&pdev->dev); +exit_iounmap: + iounmap(base); +exit_kfree: + kfree(pcdev); +exit: + return err; +} + +static int sh_mobile_ceu_remove(struct platform_device *pdev) +{ + struct sh_mobile_ceu_dev *pcdev = platform_get_drvdata(pdev); + + soc_camera_host_unregister(&pcdev->ici); + free_irq(pcdev->irq, pcdev); + if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) + dma_release_declared_memory(&pdev->dev); + iounmap(pcdev->base); + kfree(pcdev); + return 0; +} + +static struct platform_driver sh_mobile_ceu_driver = { + .driver = { + .name = "sh_mobile_ceu", + }, + .probe = sh_mobile_ceu_probe, + .remove = sh_mobile_ceu_remove, +}; + +static int __init sh_mobile_ceu_init(void) +{ + return platform_driver_register(&sh_mobile_ceu_driver); +} + +static void __exit sh_mobile_ceu_exit(void) +{ + return platform_driver_unregister(&sh_mobile_ceu_driver); +} + +module_init(sh_mobile_ceu_init); +module_exit(sh_mobile_ceu_exit); + +MODULE_DESCRIPTION("SuperH Mobile CEU driver"); +MODULE_AUTHOR("Magnus Damm"); +MODULE_LICENSE("GPL"); diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h new file mode 100644 index 000000000000..234a4711d2ec --- /dev/null +++ b/include/media/sh_mobile_ceu.h @@ -0,0 +1,12 @@ +#ifndef __ASM_SH_MOBILE_CEU_H__ +#define __ASM_SH_MOBILE_CEU_H__ + +#include + +struct sh_mobile_ceu_info { + unsigned long flags; /* SOCAM_... */ + void (*enable_camera)(void); + void (*disable_camera)(void); +}; + +#endif /* __ASM_SH_MOBILE_CEU_H__ */ -- cgit v1.2.3 From 326c986207cb2065b9819107caa31efd2bbc48db Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 16 Jul 2008 23:02:08 -0300 Subject: V4L/DVB (8343): soc_camera_platform: Add SoC Camera Platform driver This patch adds a simple platform camera device. Useful for testing cameras with SoC camera host drivers. Only one single pixel format and resolution combination is supported. Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/soc_camera_platform.c | 198 ++++++++++++++++++++++++++++++ include/media/soc_camera_platform.h | 15 +++ 4 files changed, 220 insertions(+) create mode 100644 drivers/media/video/soc_camera_platform.c create mode 100644 include/media/soc_camera_platform.h (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index fdeaff257caf..1199a1a2e6f5 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -961,6 +961,12 @@ config MT9V022_PCA9536_SWITCH Select this if your MT9V022 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes +config SOC_CAMERA_PLATFORM + tristate "platform camera support" + depends on SOC_CAMERA + help + This is a generic SoC camera platform driver, useful for testing + config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 6dd51b01ef90..45d5db5abb1e 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -137,6 +137,7 @@ obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o +obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o obj-$(CONFIG_VIDEO_AU0828) += au0828/ diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c new file mode 100644 index 000000000000..eefb0327ebb6 --- /dev/null +++ b/drivers/media/video/soc_camera_platform.c @@ -0,0 +1,198 @@ +/* + * Generic Platform Camera Driver + * + * Copyright (C) 2008 Magnus Damm + * Based on mt9m001 driver, + * Copyright (C) 2008, Guennadi Liakhovetski + * + * 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 + +struct soc_camera_platform_info { + int iface; + char *format_name; + unsigned long format_depth; + struct v4l2_pix_format format; + unsigned long bus_param; + int (*set_capture)(struct soc_camera_platform_info *info, int enable); +}; + +struct soc_camera_platform_priv { + struct soc_camera_platform_info *info; + struct soc_camera_device icd; + struct soc_camera_data_format format; +}; + +static struct soc_camera_platform_info * +soc_camera_platform_get_info(struct soc_camera_device *icd) +{ + struct soc_camera_platform_priv *priv; + priv = container_of(icd, struct soc_camera_platform_priv, icd); + return priv->info; +} + +static int soc_camera_platform_init(struct soc_camera_device *icd) +{ + return 0; +} + +static int soc_camera_platform_release(struct soc_camera_device *icd) +{ + return 0; +} + +static int soc_camera_platform_start_capture(struct soc_camera_device *icd) +{ + struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); + return p->set_capture(p, 1); +} + +static int soc_camera_platform_stop_capture(struct soc_camera_device *icd) +{ + struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); + return p->set_capture(p, 0); +} + +static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd, + unsigned long flags) +{ + return 0; +} + +static unsigned long +soc_camera_platform_query_bus_param(struct soc_camera_device *icd) +{ + struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); + return p->bus_param; +} + +static int soc_camera_platform_set_fmt_cap(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + return 0; +} + +static int soc_camera_platform_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); + + f->fmt.pix.width = p->format.width; + f->fmt.pix.height = p->format.height; + return 0; +} + +static int soc_camera_platform_video_probe(struct soc_camera_device *icd) +{ + struct soc_camera_platform_priv *priv; + priv = container_of(icd, struct soc_camera_platform_priv, icd); + + priv->format.name = priv->info->format_name; + priv->format.depth = priv->info->format_depth; + priv->format.fourcc = priv->info->format.pixelformat; + priv->format.colorspace = priv->info->format.colorspace; + + icd->formats = &priv->format; + icd->num_formats = 1; + + return soc_camera_video_start(icd); +} + +static void soc_camera_platform_video_remove(struct soc_camera_device *icd) +{ + soc_camera_video_stop(icd); +} + +static struct soc_camera_ops soc_camera_platform_ops = { + .owner = THIS_MODULE, + .probe = soc_camera_platform_video_probe, + .remove = soc_camera_platform_video_remove, + .init = soc_camera_platform_init, + .release = soc_camera_platform_release, + .start_capture = soc_camera_platform_start_capture, + .stop_capture = soc_camera_platform_stop_capture, + .set_fmt_cap = soc_camera_platform_set_fmt_cap, + .try_fmt_cap = soc_camera_platform_try_fmt_cap, + .set_bus_param = soc_camera_platform_set_bus_param, + .query_bus_param = soc_camera_platform_query_bus_param, +}; + +static int soc_camera_platform_probe(struct platform_device *pdev) +{ + struct soc_camera_platform_priv *priv; + struct soc_camera_platform_info *p; + struct soc_camera_device *icd; + int ret; + + p = pdev->dev.platform_data; + if (!p) + return -EINVAL; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->info = p; + platform_set_drvdata(pdev, priv); + + icd = &priv->icd; + icd->ops = &soc_camera_platform_ops; + icd->control = &pdev->dev; + icd->width_min = 0; + icd->width_max = priv->info->format.width; + icd->height_min = 0; + icd->height_max = priv->info->format.height; + icd->y_skip_top = 0; + icd->iface = priv->info->iface; + + ret = soc_camera_device_register(icd); + if (ret) + kfree(priv); + + return ret; +} + +static int soc_camera_platform_remove(struct platform_device *pdev) +{ + struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev); + + soc_camera_device_unregister(&priv->icd); + kfree(priv); + return 0; +} + +static struct platform_driver soc_camera_platform_driver = { + .driver = { + .name = "soc_camera_platform", + }, + .probe = soc_camera_platform_probe, + .remove = soc_camera_platform_remove, +}; + +static int __init soc_camera_platform_module_init(void) +{ + return platform_driver_register(&soc_camera_platform_driver); +} + +static void __exit soc_camera_platform_module_exit(void) +{ + return platform_driver_unregister(&soc_camera_platform_driver); +} + +module_init(soc_camera_platform_module_init); +module_exit(soc_camera_platform_module_exit); + +MODULE_DESCRIPTION("SoC Camera Platform driver"); +MODULE_AUTHOR("Magnus Damm"); +MODULE_LICENSE("GPL v2"); diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h new file mode 100644 index 000000000000..851f18220984 --- /dev/null +++ b/include/media/soc_camera_platform.h @@ -0,0 +1,15 @@ +#ifndef __SOC_CAMERA_H__ +#define __SOC_CAMERA_H__ + +#include + +struct soc_camera_platform_info { + int iface; + char *format_name; + unsigned long format_depth; + struct v4l2_pix_format format; + unsigned long bus_param; + int (*set_capture)(struct soc_camera_platform_info *info, int enable); +}; + +#endif /* __SOC_CAMERA_H__ */ -- cgit v1.2.3 From d0d0e39bc5912793405d3f84ffc982fa400e6cc0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 10 Jul 2008 07:06:44 -0300 Subject: V4L/DVB (8346): gspca: Bad pixel format of bridge VC0321. vc032x: Light frequency was not initialized. Change the pixel format of bridge VC0321 to V4L2_PIX_FMT_YUV420 ('YU12'). Set a bridge to all webcams. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/vc032x.c | 43 +++++++++++++------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 7ca6240c64e1..668e024aaa8f 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); @@ -58,7 +58,6 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_AUTOGAIN 0 { { .id = V4L2_CID_AUTOGAIN, @@ -67,20 +66,22 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, }, .set = sd_setautogain, .get = sd_getautogain, }, -#define SD_FREQ 1 { { .id = V4L2_CID_POWER_LINE_FREQUENCY, .type = V4L2_CTRL_TYPE_MENU, .name = "Light frequency filter", .minimum = 0, - .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .maximum = 2, /* 0: No, 1: 50Hz, 2:60Hz */ .step = 1, +#define FREQ_DEF 1 + .default_value = FREQ_DEF, .default_value = 1, }, .set = sd_setfreq, @@ -89,12 +90,12 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vc0321_mode[] = { - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {320, 240, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, .bytesperline = 320 * 2, .sizeimage = 320 * 240 * 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + {640, 480, V4L2_PIX_FMT_YUV420, V4L2_FIELD_NONE, .bytesperline = 640 * 2, .sizeimage = 640 * 480 * 2, .colorspace = V4L2_COLORSPACE_SRGB, @@ -1418,28 +1419,13 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; __u8 tmp2[4]; int sensor; - __u16 vendor; __u16 product; - vendor = id->idVendor; product = id->idProduct; - switch (vendor) { - case 0x046d: /* Logitech Labtec */ -/* switch (product) { */ -/* case 0x0892: */ -/* case 0x0896: */ - sd->bridge = BRIDGE_VC0321; -/* break; */ -/* } */ - break; + sd->bridge = BRIDGE_VC0321; + switch (id->idVendor) { case 0x0ac8: /* Vimicro z-star */ switch (product) { - case 0x0321: - case 0x0328: - case 0xc001: - case 0xc002: - sd->bridge = BRIDGE_VC0321; - break; case 0x0323: sd->bridge = BRIDGE_VC0323; break; @@ -1459,10 +1445,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x02; if (sd->bridge == BRIDGE_VC0321) { cam->cam_mode = vc0321_mode; - cam->nmodes = sizeof vc0321_mode / sizeof vc0321_mode[0]; + cam->nmodes = ARRAY_SIZE(vc0321_mode); } else { cam->cam_mode = vc0323_mode; - cam->nmodes = sizeof vc0323_mode / sizeof vc0323_mode[0]; + cam->nmodes = ARRAY_SIZE(vc0323_mode); } vc0321_reset(gspca_dev); @@ -1498,7 +1484,8 @@ static int sd_config(struct gspca_dev *gspca_dev, } sd->qindex = 7; - sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; + sd->autogain = AUTOGAIN_DEF; + sd->lightfreq = FREQ_DEF; if (sd->bridge == BRIDGE_VC0321) { reg_r(dev, 0x8a, 0, tmp2, 3); -- cgit v1.2.3 From dcef3237b652e1c02093feac0f443485a144f035 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 10 Jul 2008 10:40:53 -0300 Subject: V4L/DVB (8348): gspca: Add auto gain/exposure to sonixb and tas5110 / ov6650 sensors. sonixb: Do auto gain for tas5110 / ov6650 sensors. pac207: Move the auto_gain function to gspca. gspca: New function gspca_auto_gain_n_exposure(). Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 88 +++++++++++ drivers/media/video/gspca/gspca.h | 2 + drivers/media/video/gspca/pac207.c | 68 +-------- drivers/media/video/gspca/sonixb.c | 301 +++++++++++++++++++++++++++++++------ 4 files changed, 350 insertions(+), 109 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 09f190c689d5..2ffb00ab0811 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1790,6 +1790,94 @@ void gspca_disconnect(struct usb_interface *intf) } EXPORT_SYMBOL(gspca_disconnect); +/* -- cam driver utility functions -- */ + +/* auto gain and exposure algorithm based on the knee algorithm described here: + http://ytse.tricolour.net/docs/LowLightOptimization.html + + Returns 0 if no changes were made, 1 if the gain and or exposure settings + where changed. */ +int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, + int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee) +{ + int i, steps, gain, orig_gain, exposure, orig_exposure, autogain; + const struct ctrl *gain_ctrl = NULL; + const struct ctrl *exposure_ctrl = NULL; + const struct ctrl *autogain_ctrl = NULL; + int retval = 0; + + for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) { + if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN) + gain_ctrl = &gspca_dev->sd_desc->ctrls[i]; + if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE) + exposure_ctrl = &gspca_dev->sd_desc->ctrls[i]; + if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN) + autogain_ctrl = &gspca_dev->sd_desc->ctrls[i]; + } + if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) { + PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called " + "on cam without (auto)gain/exposure"); + return 0; + } + + if (gain_ctrl->get(gspca_dev, &gain) || + exposure_ctrl->get(gspca_dev, &exposure) || + autogain_ctrl->get(gspca_dev, &autogain) || !autogain) + return 0; + + orig_gain = gain; + orig_exposure = exposure; + + /* If we are of a multiple of deadzone, do multiple steps to reach the + desired lumination fast (with the risc of a slight overshoot) */ + steps = abs(desired_avg_lum - avg_lum) / deadzone; + + PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n", + avg_lum, desired_avg_lum, steps); + + for (i = 0; i < steps; i++) { + if (avg_lum > desired_avg_lum) { + if (gain > gain_knee) + gain--; + else if (exposure > exposure_knee) + exposure--; + else if (gain > gain_ctrl->qctrl.default_value) + gain--; + else if (exposure > exposure_ctrl->qctrl.minimum) + exposure--; + else if (gain > gain_ctrl->qctrl.minimum) + gain--; + else + break; + } else { + if (gain < gain_ctrl->qctrl.default_value) + gain++; + else if (exposure < exposure_knee) + exposure++; + else if (gain < gain_knee) + gain++; + else if (exposure < exposure_ctrl->qctrl.maximum) + exposure++; + else if (gain < gain_ctrl->qctrl.maximum) + gain++; + else + break; + } + } + + if (gain != orig_gain) { + gain_ctrl->set(gspca_dev, gain); + retval = 1; + } + if (exposure != orig_exposure) { + exposure_ctrl->set(gspca_dev, exposure); + retval = 1; + } + + return retval; +} +EXPORT_SYMBOL(gspca_auto_gain_n_exposure); + /* -- module insert / remove -- */ static int __init gspca_init(void) { diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 9b645af81a07..78fccefcd576 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -170,4 +170,6 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, struct gspca_frame *frame, const __u8 *data, int len); +int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum, + int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee); #endif /* GSPCAV2_H */ diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 4f197c1f4a76..5d68d3f42262 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -357,70 +357,20 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* auto gain and exposure algorithm based on the knee algorithm described here: - * */ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int i, steps, desired_avg_lum; - int orig_gain = sd->gain; - int orig_exposure = sd->exposure; int avg_lum = atomic_read(&sd->avg_lum); - if (!sd->autogain || avg_lum == -1) + if (avg_lum == -1) return; - if (sd->autogain_ignore_frames > 0) { + if (sd->autogain_ignore_frames > 0) sd->autogain_ignore_frames--; - return; - } - - /* correct desired lumination for the configured brightness */ - desired_avg_lum = 100 + sd->brightness / 2; - - /* If we are of a multiple of deadzone, do multiple step to reach the - desired lumination fast (with the risc of a slight overshoot) */ - steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE; - - for (i = 0; i < steps; i++) { - if (avg_lum > desired_avg_lum) { - if (sd->gain > PAC207_GAIN_KNEE) - sd->gain--; - else if (sd->exposure > PAC207_EXPOSURE_KNEE) - sd->exposure--; - else if (sd->gain > PAC207_GAIN_DEFAULT) - sd->gain--; - else if (sd->exposure > PAC207_EXPOSURE_MIN) - sd->exposure--; - else if (sd->gain > PAC207_GAIN_MIN) - sd->gain--; - else - break; - } else { - if (sd->gain < PAC207_GAIN_DEFAULT) - sd->gain++; - else if (sd->exposure < PAC207_EXPOSURE_KNEE) - sd->exposure++; - else if (sd->gain < PAC207_GAIN_KNEE) - sd->gain++; - else if (sd->exposure < PAC207_EXPOSURE_MAX) - sd->exposure++; - else if (sd->gain < PAC207_GAIN_MAX) - sd->gain++; - else - break; - } - } - - if (sd->exposure != orig_exposure || sd->gain != orig_gain) { - if (sd->exposure != orig_exposure) - pac207_write_reg(gspca_dev, 0x0002, sd->exposure); - if (sd->gain != orig_gain) - pac207_write_reg(gspca_dev, 0x000e, sd->gain); - pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */ - pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */ + else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, + 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE, + PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE)) sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES; - } } static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev, @@ -546,10 +496,6 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - /* don't allow mucking with exposure when using autogain */ - if (sd->autogain) - return -EINVAL; - sd->exposure = val; if (gspca_dev->streaming) setexposure(gspca_dev); @@ -568,10 +514,6 @@ static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - /* don't allow mucking with gain when using autogain */ - if (sd->autogain) - return -EINVAL; - sd->gain = val; if (gspca_dev->streaming) setgain(gspca_dev); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 95a6a8e98b97..274df69e6f6d 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -35,11 +35,19 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ + struct sd_desc sd_desc; /* our nctrls differ dependend upon the + sensor, so we use a per cam copy */ + atomic_t avg_lum; + + unsigned short gain; + unsigned short exposure; unsigned char brightness; - unsigned char contrast; + unsigned char autogain; + unsigned char autogain_ignore_frames; unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ + char sensor_has_gain; #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 #define SENSOR_OV7630 2 @@ -59,11 +67,24 @@ struct sd { #define SYS_CLK 0x04 +/* We calculate the autogain at the end of the transfer of a frame, at this + moment a frame with the old settings is being transmitted, and a frame is + being captured with the old settings. So if we adjust the autogain we must + ignore atleast the 2 next frames for the new settings to come into effect + before doing any other adjustments */ +#define AUTOGAIN_IGNORE_FRAMES 3 +#define AUTOGAIN_DEADZONE 500 +#define DESIRED_AVG_LUM 7000 + /* V4L2 controls supported by the driver */ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { #define SD_BRIGHTNESS 0 @@ -75,24 +96,59 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 255, .step = 1, - .default_value = 127, +#define BRIGHTNESS_DEF 127 + .default_value = BRIGHTNESS_DEF, }, .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_CONTRAST 1 +#define SD_GAIN 1 { { - .id = V4L2_CID_CONTRAST, + .id = V4L2_CID_GAIN, .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", + .name = "Gain", .minimum = 0, - .maximum = 255, + .maximum = 511, .step = 1, - .default_value = 127, +#define GAIN_DEF 255 +#define GAIN_KNEE 400 + .default_value = GAIN_DEF, }, - .set = sd_setcontrast, - .get = sd_getcontrast, + .set = sd_setgain, + .get = sd_getgain, + }, +#define SD_EXPOSURE 2 + { + { + .id = V4L2_CID_EXPOSURE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Exposure", +#define EXPOSURE_DEF 0 +#define EXPOSURE_KNEE 353 /* 10 fps */ + .minimum = 0, + .maximum = 511, + .step = 1, + .default_value = EXPOSURE_DEF, + .flags = 0, + }, + .set = sd_setexposure, + .get = sd_getexposure, + }, +#define SD_AUTOGAIN 3 + { + { + .id = V4L2_CID_AUTOGAIN, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Automatic Gain (and Exposure)", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, + }, + .set = sd_setautogain, + .get = sd_getautogain, }, }; @@ -153,8 +209,12 @@ static const __u8 ov6650_sensor_init[][8] = /* Bright, contrast, etc are set througth SCBB interface. * AVCAP on win2 do not send any data on this controls. */ /* Anyway, some registers appears to alter bright and constrat */ + + /* Reset sensor */ {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, + /* Set clock register 0x11 low nibble is clock divider */ {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10}, + /* Next some unknown stuff */ {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10}, /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10}, * THIS SET GREEN SCREEN @@ -163,31 +223,18 @@ static const __u8 ov6650_sensor_init[][8] = {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, + /* Disable autobright ? */ {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, + /* Some more unknown stuff */ {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ - {0xa0, 0x60, 0x10, 0x5d, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x2d, 0x0a, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x33, 0x40, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x11, 0xc0, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x00, 0x16, 0x99, 0x04, 0x94, 0x15}, /* bright / Lumino */ - {0xa0, 0x60, 0x2b, 0xab, 0x99, 0x04, 0x94, 0x15}, - /* ?flicker o brillo */ - {0xa0, 0x60, 0x2d, 0x2a, 0x99, 0x04, 0x94, 0x15}, - {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x33, 0x00, 0x99, 0x04, 0x94, 0x16}, {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16}, - {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16}, - /* Low Light (Enabled: 0x32 0x1 | Disabled: 0x32 0x00) */ - {0xa0, 0x60, 0x33, 0x29, 0x99, 0x04, 0x94, 0x16}, - /* Low Ligth (Enabled: 0x33 0x13 | Disabled: 0x33 0x29) */ -/* {0xa0, 0x60, 0x11, 0xc1, 0x99, 0x04, 0x94, 0x16}, */ - {0xa0, 0x60, 0x00, 0x17, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ - {0xa0, 0x60, 0x00, 0x18, 0x99, 0x04, 0x94, 0x15}, /* clip? r */ + /* Framerate adjust register for artificial light 50 hz flicker + compensation, identical to ov6630 0x2b register, see 6630 datasheet. + 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ + {0xa0, 0x60, 0x2b, 0x4f, 0x99, 0x04, 0x94, 0x15}, }; + static const __u8 initOv7630[] = { 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */ @@ -469,8 +516,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) goto err; break; } - case SENSOR_TAS5130CXX: - case SENSOR_TAS5110: { + case SENSOR_TAS5130CXX: { __u8 i2c[] = {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; @@ -481,24 +527,112 @@ static void setbrightness(struct gspca_dev *gspca_dev) goto err; break; } + case SENSOR_TAS5110: + /* FIXME figure out howto control brightness on TAS5110 */ + break; } return; err: PDEBUG(D_ERR, "i2c error brightness"); } -static void setcontrast(struct gspca_dev *gspca_dev) + +static void setsensorgain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + unsigned short gain; + + gain = (sd->gain + 1) >> 1; + if (gain > 255) + gain = 255; + + switch (sd->sensor) { + + case SENSOR_TAS5110: { + __u8 i2c[] = + {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; + + i2c[4] = 255 - gain; + if (i2c_w(gspca_dev->dev, i2c) < 0) + goto err; + break; } + + case SENSOR_OV6650: { + __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; + i2c[3] = gain; + if (i2c_w(gspca_dev->dev, i2c) < 0) + goto err; + break; } + } + return; +err: + PDEBUG(D_ERR, "i2c error gain"); +} + +static void setgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 gain; __u8 rgb_value; - gain = sd->contrast >> 4; + gain = sd->gain >> 5; + /* red and blue gain */ rgb_value = gain << 4 | gain; reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); /* green gain */ rgb_value = gain; reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); + + if (sd->sensor_has_gain) + setsensorgain(gspca_dev); +} + +static void setexposure(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + /* translate 0 - 255 to a number of fps in a 30 - 1 scale */ + int fps = 30 - sd->exposure * 29 / 511; + + switch (sd->sensor) { + case SENSOR_TAS5110: { + __u8 reg; + + /* register 19's high nibble contains the sn9c10x clock divider + The high nibble configures the no fps according to the + formula: 60 / high_nibble. With a maximum of 30 fps */ + reg = 60 / fps; + if (reg > 15) + reg = 15; + reg = (reg << 4) | 0x0b; + reg_w(gspca_dev->dev, 0x19, ®, 1); + break; } + case SENSOR_OV6650: { + __u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10}; + i2c[3] = 30 / fps - 1; + if (i2c[3] > 15) + i2c[3] = 15; + i2c[3] |= 0xc0; + if (i2c_w(gspca_dev->dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error exposure"); + break; } + } +} + + +static void do_autogain(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int avg_lum = atomic_read(&sd->avg_lum); + + if (avg_lum == -1) + return; + + if (sd->autogain_ignore_frames > 0) + sd->autogain_ignore_frames--; + else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, + sd->brightness * DESIRED_AVG_LUM / 127, + AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) + sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; } /* this function is called at probe time */ @@ -511,7 +645,13 @@ static int sd_config(struct gspca_dev *gspca_dev, __u16 product; int sif = 0; + /* nctrls depends upon the sensor, so we use a per cam copy */ + memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); + gspca_dev->sd_desc = &sd->sd_desc; + sd->fr_h_sz = 12; /* default size of the frame header */ + sd->sd_desc.nctrls = 2; /* default no ctrls */ + /* vendor = id->idVendor; */ product = id->idProduct; /* switch (vendor) { */ @@ -521,6 +661,9 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x6005: /* SN9C101 */ case 0x6007: /* SN9C101 */ sd->sensor = SENSOR_TAS5110; + sd->sensor_has_gain = 1; + sd->sd_desc.nctrls = 4; + sd->sd_desc.dq_callback = do_autogain; sif = 1; break; case 0x6009: /* SN9C101 */ @@ -531,6 +674,9 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x6011: /* SN9C101 - SN9C101G */ sd->sensor = SENSOR_OV6650; + sd->sensor_has_gain = 1; + sd->sd_desc.nctrls = 4; + sd->sd_desc.dq_callback = do_autogain; sif = 1; break; case 0x6019: /* SN9C101 */ @@ -570,8 +716,10 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; } - sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; - sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; + sd->brightness = BRIGHTNESS_DEF; + sd->gain = GAIN_DEF; + sd->exposure = EXPOSURE_DEF; + sd->autogain = 1; if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); return 0; @@ -754,8 +902,12 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x18, ®17_19[1], 2); msleep(20); - setcontrast(gspca_dev); + setgain(gspca_dev); setbrightness(gspca_dev); + setexposure(gspca_dev); + + sd->autogain_ignore_frames = 0; + atomic_set(&sd->avg_lum, -1); } static void sd_stopN(struct gspca_dev *gspca_dev) @@ -779,8 +931,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, unsigned char *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd; int i; + struct sd *sd = (struct sd *) gspca_dev; if (len > 6 && len < 24) { for (i = 0; i < len - 6; i++) { @@ -792,7 +944,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[5 + i] == 0x96) { /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - sd = (struct sd *) gspca_dev; + if (i < (len - 10)) { + atomic_set(&sd->avg_lum, data[i + 8] + + (data[i + 9] << 8)); + } else { + atomic_set(&sd->avg_lum, -1); +#ifdef CONFIG_VIDEO_ADV_DEBUG + PDEBUG(D_STREAM, "packet too short to " + "get avg brightness"); +#endif + } data += i + sd->fr_h_sz; len -= i + sd->fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, @@ -823,26 +984,74 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->gain = val; + if (gspca_dev->streaming) + setgain(gspca_dev); + return 0; +} + +static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - sd->contrast = val; + *val = sd->gain; + return 0; +} + +static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->exposure = val; if (gspca_dev->streaming) - setcontrast(gspca_dev); + setexposure(gspca_dev); + return 0; +} + +static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->exposure; + return 0; +} + +static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->autogain = val; + /* when switching to autogain set defaults to make sure + we are on a valid point of the autogain gain / + exposure knee graph, and give this change time to + take effect before doing autogain. */ + if (sd->autogain) { + sd->exposure = EXPOSURE_DEF; + sd->gain = GAIN_DEF; + if (gspca_dev->streaming) { + sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; + setexposure(gspca_dev); + setgain(gspca_dev); + } + } + return 0; } -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) { struct sd *sd = (struct sd *) gspca_dev; - *val = sd->contrast; + *val = sd->autogain; return 0; } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, .nctrls = ARRAY_SIZE(sd_ctrls), -- cgit v1.2.3 From 51fc8e3bc03aeddc557d3084d08425eb4cb8ed41 Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Thu, 10 Jul 2008 11:12:24 -0300 Subject: V4L/DVB (8349): gspca: SN9C103 OV7630 fixes in sonixb. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 76 ++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 274df69e6f6d..5d2313198807 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); @@ -87,7 +87,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { -#define SD_BRIGHTNESS 0 { { .id = V4L2_CID_BRIGHTNESS, @@ -102,7 +101,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setbrightness, .get = sd_getbrightness, }, -#define SD_GAIN 1 { { .id = V4L2_CID_GAIN, @@ -118,7 +116,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setgain, .get = sd_getgain, }, -#define SD_EXPOSURE 2 { { .id = V4L2_CID_EXPOSURE, @@ -135,7 +132,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setexposure, .get = sd_getexposure, }, -#define SD_AUTOGAIN 3 { { .id = V4L2_CID_AUTOGAIN, @@ -144,7 +140,8 @@ static struct ctrl sd_ctrls[] = { .minimum = 0, .maximum = 1, .step = 1, - .default_value = 1, +#define AUTOGAIN_DEF 1 + .default_value = AUTOGAIN_DEF, .flags = 0, }, .set = sd_setautogain, @@ -246,10 +243,12 @@ static const __u8 initOv7630[] = { static const __u8 initOv7630_3[] = { 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ - 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */ - 0x28, 0x1e, /* H & V sizes r15 .. r16 */ - 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */ - 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */ + 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ + 0x16, 0x12, /* H & V sizes r15 .. r16 */ + 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ + 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ + 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ }; static const __u8 ov7630_sensor_init_com[][8] = { {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, @@ -280,14 +279,14 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ }; static const __u8 ov7630_sensor_init_3[][8] = { - {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ - {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ + {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16}, {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ /* {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d}, * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */ /* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */ - {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d}, + {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d}, }; static const __u8 initPas106[] = { @@ -403,7 +402,7 @@ static void reg_w(struct usb_device *dev, const __u8 *buffer, int len) { - __u8 tmpbuf[32]; + __u8 tmpbuf[48]; #ifdef CONFIG_VIDEO_ADV_DEBUG if (len > sizeof tmpbuf) { @@ -554,14 +553,15 @@ static void setsensorgain(struct gspca_dev *gspca_dev) i2c[4] = 255 - gain; if (i2c_w(gspca_dev->dev, i2c) < 0) goto err; - break; } - + break; + } case SENSOR_OV6650: { __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[3] = gain; if (i2c_w(gspca_dev->dev, i2c) < 0) goto err; - break; } + break; + } } return; err: @@ -605,7 +605,8 @@ static void setexposure(struct gspca_dev *gspca_dev) reg = 15; reg = (reg << 4) | 0x0b; reg_w(gspca_dev->dev, 0x19, ®, 1); - break; } + break; + } case SENSOR_OV6650: { __u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10}; i2c[3] = 30 / fps - 1; @@ -614,7 +615,8 @@ static void setexposure(struct gspca_dev *gspca_dev) i2c[3] |= 0xc0; if (i2c_w(gspca_dev->dev, i2c) < 0) PDEBUG(D_ERR, "i2c error exposure"); - break; } + break; + } } } @@ -641,7 +643,6 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; -/* __u16 vendor; */ __u16 product; int sif = 0; @@ -650,11 +651,10 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->sd_desc = &sd->sd_desc; sd->fr_h_sz = 12; /* default size of the frame header */ - sd->sd_desc.nctrls = 2; /* default no ctrls */ + sd->sd_desc.nctrls = 2; /* default nb of ctrls */ -/* vendor = id->idVendor; */ product = id->idProduct; -/* switch (vendor) { */ +/* switch (id->idVendor) { */ /* case 0x0c45: * Sonix */ switch (product) { case 0x6001: /* SN9C102 */ @@ -711,15 +711,15 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x01; if (!sif) { cam->cam_mode = vga_mode; - cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + cam->nmodes = ARRAY_SIZE(vga_mode); } else { cam->cam_mode = sif_mode; - cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + cam->nmodes = ARRAY_SIZE(sif_mode); } sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; - sd->autogain = 1; + sd->autogain = AUTOGAIN_DEF; if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); return 0; @@ -762,6 +762,7 @@ static void sd_start(struct gspca_dev *gspca_dev) const __u8 *sn9c10x; __u8 reg01, reg17; __u8 reg17_19[3]; + static const __u8 reg15[2] = { 0x28, 0x1e }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (sd->sensor) { @@ -824,7 +825,7 @@ static void sd_start(struct gspca_dev *gspca_dev) case SENSOR_OV7630_3: reg01 = 0x44; reg17 = 0x68; - l = 0x10; + l = sizeof initOv7630_3; break; default: reg01 = sn9c10x[0]; @@ -882,18 +883,21 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } /* H_size V_size 0x28, 0x1e maybe 640x480 */ - reg_w(dev, 0x15, &sn9c10x[0x15 - 1], 2); + reg_w(dev, 0x15, reg15, 2); /* compression register */ reg_w(dev, 0x18, ®17_19[1], 1); - /* H_start */ /*fixme: not ov7630*/ - reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); - /* V_START */ /*fixme: not ov7630*/ - reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); + if (sd->sensor != SENSOR_OV7630_3) { + /* H_start */ + reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); + /* V_START */ + reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); + } /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ reg_w(dev, 0x17, ®17_19[0], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - reg_w(dev, 0x19, ®17_19[2], 1); + if (sd->sensor != SENSOR_OV7630_3) + reg_w(dev, 0x19, ®17_19[2], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); /* Enable video transfert */ @@ -912,7 +916,7 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - __u8 ByteSend = 0; + __u8 ByteSend; ByteSend = 0x09; /* 0X00 */ reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); -- cgit v1.2.3 From 5b77ae7776183d733ec86727bcc34c52a336afd6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 12 Jul 2008 09:28:04 -0300 Subject: V4L/DVB (8350): gspca: Conform to v4l2 spec and mutex unlock fix. gspca: Empty the application queues on streamoff ioctl. streamon/off and qbuf ioctls may be done by any application. Don't handle MJPEG pixel format as JPEG. (thanks to Hans de Goede) Authorize reqbufs ioctl when streaming. Bad mutex unlock in poll() when streaming problem. (thanks to Mauro Carvalho Chehab) Don't handle 'webcam disconnected' in stream off. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 146 +++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 72 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 2ffb00ab0811..a566fd394895 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -42,8 +42,8 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 6) -static const char version[] = "2.1.6"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; static int video_nr = -1; @@ -558,11 +558,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) gspca_set_alt0(gspca_dev); gspca_dev->sd_desc->stop0(gspca_dev); PDEBUG(D_STREAM, "stream off OK"); - } else { - destroy_urbs(gspca_dev); - atomic_inc(&gspca_dev->nevent); - wake_up_interruptible(&gspca_dev->wq); - PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); } } @@ -680,9 +675,6 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, w = fmt->fmt.pix.width; h = fmt->fmt.pix.height; - /* (luvcview problem) */ - if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) - fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; #ifdef CONFIG_VIDEO_ADV_DEBUG if (gspca_debug & D_CONF) PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); @@ -816,7 +808,7 @@ static int dev_close(struct inode *inode, struct file *file) return -ERESTARTSYS; gspca_dev->users--; - /* if the file did capture, free the streaming resources */ + /* if the file did the capture, free the streaming resources */ if (gspca_dev->capt_file == file) { mutex_lock(&gspca_dev->usb_lock); if (gspca_dev->streaming) @@ -981,7 +973,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; switch (rb->memory) { - case GSPCA_MEMORY_READ: + case GSPCA_MEMORY_READ: /* (internal call) */ case V4L2_MEMORY_MMAP: case V4L2_MEMORY_USERPTR: break; @@ -991,33 +983,46 @@ static int vidioc_reqbufs(struct file *file, void *priv, if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; - /* only one file may do capture */ - if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file) - || gspca_dev->streaming) { + if (gspca_dev->memory != GSPCA_MEMORY_NO + && gspca_dev->memory != rb->memory) { ret = -EBUSY; goto out; } - if (rb->count == 0) { /* unrequest */ - for (i = 0; i < gspca_dev->nframes; i++) { - if (gspca_dev->frame[i].vma_use_count) { - ret = -EBUSY; - goto out; - } - } - frame_free(gspca_dev); - gspca_dev->capt_file = NULL; - } else { - if (gspca_dev->nframes != 0) { + /* only one file may do the capture */ + if (gspca_dev->capt_file != NULL + && gspca_dev->capt_file != file) { + ret = -EBUSY; + goto out; + } + + /* if allocated, the buffers must not be mapped */ + for (i = 0; i < gspca_dev->nframes; i++) { + if (gspca_dev->frame[i].vma_use_count) { ret = -EBUSY; goto out; } - gspca_dev->memory = rb->memory; - ret = frame_alloc(gspca_dev, rb->count); - if (ret == 0) { - rb->count = gspca_dev->nframes; - gspca_dev->capt_file = file; - } + } + + /* stop streaming */ + if (gspca_dev->streaming) { + mutex_lock(&gspca_dev->usb_lock); + gspca_stream_off(gspca_dev); + mutex_unlock(&gspca_dev->usb_lock); + } + + /* free the previous allocated buffers, if any */ + if (gspca_dev->nframes != 0) { + frame_free(gspca_dev); + gspca_dev->capt_file = NULL; + } + if (rb->count == 0) /* unrequest */ + goto out; + gspca_dev->memory = rb->memory; + ret = frame_alloc(gspca_dev, rb->count); + if (ret == 0) { + rb->count = gspca_dev->nframes; + gspca_dev->capt_file = file; } out: mutex_unlock(&gspca_dev->queue_lock); @@ -1059,10 +1064,6 @@ static int vidioc_streamon(struct file *file, void *priv, ret = -EINVAL; goto out; } - if (gspca_dev->capt_file != file) { - ret = -EINVAL; - goto out; - } if (!gspca_dev->streaming) { ret = gspca_init_transfer(gspca_dev); if (ret < 0) @@ -1086,7 +1087,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = priv; - int ret; + int i, ret; if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1094,18 +1095,23 @@ static int vidioc_streamoff(struct file *file, void *priv, return 0; if (mutex_lock_interruptible(&gspca_dev->queue_lock)) return -ERESTARTSYS; + + /* stop streaming */ if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { ret = -ERESTARTSYS; goto out; } - if (gspca_dev->capt_file != file) { - ret = -EINVAL; - goto out2; - } gspca_stream_off(gspca_dev); - ret = 0; -out2: mutex_unlock(&gspca_dev->usb_lock); + + /* empty the application queues */ + for (i = 0; i < gspca_dev->nframes; i++) + gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; + gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; + gspca_dev->last_packet_type = DISCARD_PACKET; + gspca_dev->sequence = 0; + atomic_set(&gspca_dev->nevent, 0); + ret = 0; out: mutex_unlock(&gspca_dev->queue_lock); return ret; @@ -1364,14 +1370,17 @@ static int vidioc_dqbuf(struct file *file, void *priv, return -EINVAL; if (v4l2_buf->memory != gspca_dev->memory) return -EINVAL; - if (!gspca_dev->streaming) + + /* if not streaming, be sure the application will not loop forever */ + if (!(file->f_flags & O_NONBLOCK) + && !gspca_dev->streaming && gspca_dev->users == 1) return -EINVAL; - if (gspca_dev->capt_file != file) { - ret = -EINVAL; - goto out; - } - /* only one read */ + /* only the capturing file may dequeue */ + if (gspca_dev->capt_file != file) + return -EINVAL; + + /* only one dequeue / read at a time */ if (mutex_lock_interruptible(&gspca_dev->read_lock)) return -ERESTARTSYS; @@ -1416,24 +1425,23 @@ static int vidioc_qbuf(struct file *file, void *priv, if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + if (mutex_lock_interruptible(&gspca_dev->queue_lock)) + return -ERESTARTSYS; + index = v4l2_buf->index; if ((unsigned) index >= gspca_dev->nframes) { PDEBUG(D_FRAM, "qbuf idx %d >= %d", index, gspca_dev->nframes); - return -EINVAL; + ret = -EINVAL; + goto out; } - frame = &gspca_dev->frame[index]; - - if (v4l2_buf->memory != frame->v4l2_buf.memory) { + if (v4l2_buf->memory != gspca_dev->memory) { PDEBUG(D_FRAM, "qbuf bad memory type"); - return -EINVAL; + ret = -EINVAL; + goto out; } - if (gspca_dev->capt_file != file) - return -EINVAL; - - if (mutex_lock_interruptible(&gspca_dev->queue_lock)) - return -ERESTARTSYS; + frame = &gspca_dev->frame[index]; if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { PDEBUG(D_FRAM, "qbuf bad state"); ret = -EINVAL; @@ -1492,9 +1500,6 @@ static int read_alloc(struct gspca_dev *gspca_dev, v4l2_buf.memory = GSPCA_MEMORY_READ; for (i = 0; i < gspca_dev->nbufread; i++) { v4l2_buf.index = i; -/*fixme: ugly!*/ - gspca_dev->frame[i].v4l2_buf.flags |= - V4L2_BUF_FLAG_MAPPED; ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); if (ret != 0) { PDEBUG(D_STREAM, "read qbuf err: %d", ret); @@ -1522,17 +1527,13 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) if (!gspca_dev->present) return POLLERR; - /* if not streaming, the user would use read() */ - if (!gspca_dev->streaming) { - if (gspca_dev->memory != GSPCA_MEMORY_NO) { - ret = POLLERR; /* not the 1st time */ - goto out; - } + /* if reqbufs is not done, the user would use read() */ + if (gspca_dev->nframes == 0) { + if (gspca_dev->memory != GSPCA_MEMORY_NO) + return POLLERR; /* not the 1st time */ ret = read_alloc(gspca_dev, file); - if (ret != 0) { - ret = POLLERR; - goto out; - } + if (ret != 0) + return POLLERR; } if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) @@ -1542,6 +1543,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) goto out; } + /* check the next incoming buffer */ i = gspca_dev->fr_o; i = gspca_dev->fr_queue[i]; if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) -- cgit v1.2.3 From 739570bb218bb4607df1f197282561e97a98e54a Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 14 Jul 2008 09:38:29 -0300 Subject: V4L/DVB (8352): gspca: Buffers for USB exchanges cannot be in the stack. gspca: Protect dq_callback() against simultaneous USB exchanges. Temporary buffer for USB exchanges added in the device struct. (all) Use a temporary buffer for all USB exchanges. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 385 ++++++++++++++----------------- drivers/media/video/gspca/etoms.c | 443 ++++++++++++++++++------------------ drivers/media/video/gspca/gspca.c | 6 +- drivers/media/video/gspca/gspca.h | 1 + drivers/media/video/gspca/mars.c | 158 +++++++------ drivers/media/video/gspca/ov519.c | 19 +- drivers/media/video/gspca/pac207.c | 19 +- drivers/media/video/gspca/pac7311.c | 336 +++++++++++++-------------- drivers/media/video/gspca/sonixb.c | 155 +++++++------ drivers/media/video/gspca/sonixj.c | 293 ++++++++++++------------ drivers/media/video/gspca/spca500.c | 265 +++++++++++---------- drivers/media/video/gspca/spca501.c | 23 +- drivers/media/video/gspca/spca505.c | 24 +- drivers/media/video/gspca/spca506.c | 35 ++- drivers/media/video/gspca/spca508.c | 37 ++- drivers/media/video/gspca/spca561.c | 115 +++++----- drivers/media/video/gspca/stk014.c | 86 ++++--- drivers/media/video/gspca/sunplus.c | 279 +++++++++++------------ drivers/media/video/gspca/t613.c | 176 +++++++------- drivers/media/video/gspca/tv8532.c | 360 +++++++++++++---------------- drivers/media/video/gspca/vc032x.c | 81 ++++--- drivers/media/video/gspca/zc3xx.c | 199 ++++++++-------- 22 files changed, 1700 insertions(+), 1795 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index b5481017dd4f..013d593b0c67 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -25,8 +25,8 @@ #define CONEX_CAM 1 /* special JPEG header */ #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); @@ -119,40 +119,67 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -static void reg_r(struct usb_device *dev, - __u16 index, - __u8 *buffer, __u16 length) +/* the read bytes are found in gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 index, + __u16 len) { + struct usb_device *dev = gspca_dev->dev; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof gspca_dev->usb_buf) { + err("reg_r: buffer overflow"); + return; + } +#endif usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, - index, buffer, length, + index, gspca_dev->usb_buf, len, 500); - PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", index, *buffer); + PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", + index, gspca_dev->usb_buf[0]); +} + +/* the bytes to write are in gspca_dev->usb_buf */ +static void reg_w_val(struct gspca_dev *gspca_dev, + __u16 index, + __u8 val) +{ + struct usb_device *dev = gspca_dev->dev; + + gspca_dev->usb_buf[0] = val; + usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + 0, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, + index, gspca_dev->usb_buf, 1, 500); } -static void reg_w(struct usb_device *dev, +static void reg_w(struct gspca_dev *gspca_dev, __u16 index, - const __u8 *buffer, __u16 len) + const __u8 *buffer, + __u16 len) { - __u8 tmpbuf[8]; + struct usb_device *dev = gspca_dev->dev; #ifdef CONFIG_VIDEO_ADV_DEBUG - if (len > sizeof tmpbuf) { - PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); + if (len > sizeof gspca_dev->usb_buf) { + err("reg_w: buffer overflow"); return; } PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); #endif - memcpy(tmpbuf, buffer, len); + memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, - index, tmpbuf, len, 500); + index, gspca_dev->usb_buf, len, 500); } static const __u8 cx_sensor_init[][4] = { @@ -232,17 +259,14 @@ static const __u8 cx11646_fw1[][3] = { }; static void cx11646_fw(struct gspca_dev*gspca_dev) { - __u8 val; int i = 0; - val = 0x02; - reg_w(gspca_dev->dev, 0x006a, &val, 1); + reg_w_val(gspca_dev, 0x006a, 0x02); while (cx11646_fw1[i][1]) { - reg_w(gspca_dev->dev, 0x006b, cx11646_fw1[i], 3); + reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3); i++; } - val = 0x00; - reg_w(gspca_dev->dev, 0x006a, &val, 1); + reg_w_val(gspca_dev, 0x006a, 0x00); } static const __u8 cxsensor[] = { @@ -273,52 +297,47 @@ static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; static void cx_sensor(struct gspca_dev*gspca_dev) { - __u8 val; int i = 0; - __u8 bufread[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int length; const __u8 *ptsensor = cxsensor; - reg_w(gspca_dev->dev, 0x0020, reg20, 8); - reg_w(gspca_dev->dev, 0x0028, reg28, 8); - reg_w(gspca_dev->dev, 0x0010, reg10, 8); - val = 0x03; - reg_w(gspca_dev->dev, 0x0092, &val, 1); + reg_w(gspca_dev, 0x0020, reg20, 8); + reg_w(gspca_dev, 0x0028, reg28, 8); + reg_w(gspca_dev, 0x0010, reg10, 8); + reg_w_val(gspca_dev, 0x0092, 0x03); switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: - reg_w(gspca_dev->dev, 0x0071, reg71a, 4); + reg_w(gspca_dev, 0x0071, reg71a, 4); break; case 1: - reg_w(gspca_dev->dev, 0x0071, reg71b, 4); + reg_w(gspca_dev, 0x0071, reg71b, 4); break; default: /* case 2: */ - reg_w(gspca_dev->dev, 0x0071, reg71c, 4); + reg_w(gspca_dev, 0x0071, reg71c, 4); break; case 3: - reg_w(gspca_dev->dev, 0x0071, reg71d, 4); + reg_w(gspca_dev, 0x0071, reg71d, 4); break; } - reg_w(gspca_dev->dev, 0x007b, reg7b, 6); - val = 0x00; - reg_w(gspca_dev->dev, 0x00f8, &val, 1); - reg_w(gspca_dev->dev, 0x0010, reg10, 8); - val = 0x41; - reg_w(gspca_dev->dev, 0x0098, &val, 1); + reg_w(gspca_dev, 0x007b, reg7b, 6); + reg_w_val(gspca_dev, 0x00f8, 0x00); + reg_w(gspca_dev, 0x0010, reg10, 8); + reg_w_val(gspca_dev, 0x0098, 0x41); for (i = 0; i < 11; i++) { if (i == 3 || i == 5 || i == 8) length = 8; else length = 4; - reg_w(gspca_dev->dev, 0x00e5, ptsensor, length); + reg_w(gspca_dev, 0x00e5, ptsensor, length); if (length == 4) - reg_r(gspca_dev->dev, 0x00e8, &val, 1); + reg_r(gspca_dev, 0x00e8, 1); else - reg_r(gspca_dev->dev, 0x00e8, bufread, length); + reg_r(gspca_dev, 0x00e8, length); ptsensor += length; } - reg_r(gspca_dev->dev, 0x00e7, bufread, 8); + reg_r(gspca_dev, 0x00e7, 8); } static const __u8 cx_inits_176[] = { @@ -358,10 +377,9 @@ static const __u8 cx_inits_640[] = { 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static int cx11646_initsize(struct gspca_dev *gspca_dev) +static void cx11646_initsize(struct gspca_dev *gspca_dev) { const __u8 *cxinit; - __u8 val; static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 }; static const __u8 reg17[] = { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 }; @@ -381,35 +399,29 @@ static int cx11646_initsize(struct gspca_dev *gspca_dev) cxinit = cx_inits_176; break; } - val = 0x01; - reg_w(gspca_dev->dev, 0x009a, &val, 1); - val = 0x10; - reg_w(gspca_dev->dev, 0x0010, &val, 1); - reg_w(gspca_dev->dev, 0x0012, reg12, 5); - reg_w(gspca_dev->dev, 0x0017, reg17, 8); - val = 0x00; - reg_w(gspca_dev->dev, 0x00c0, &val, 1); - val = 0x04; - reg_w(gspca_dev->dev, 0x00c1, &val, 1); - val = 0x04; - reg_w(gspca_dev->dev, 0x00c2, &val, 1); - - reg_w(gspca_dev->dev, 0x0061, cxinit, 8); + reg_w_val(gspca_dev, 0x009a, 0x01); + reg_w_val(gspca_dev, 0x0010, 0x10); + reg_w(gspca_dev, 0x0012, reg12, 5); + reg_w(gspca_dev, 0x0017, reg17, 8); + reg_w_val(gspca_dev, 0x00c0, 0x00); + reg_w_val(gspca_dev, 0x00c1, 0x04); + reg_w_val(gspca_dev, 0x00c2, 0x04); + + reg_w(gspca_dev, 0x0061, cxinit, 8); cxinit += 8; - reg_w(gspca_dev->dev, 0x00ca, cxinit, 8); + reg_w(gspca_dev, 0x00ca, cxinit, 8); cxinit += 8; - reg_w(gspca_dev->dev, 0x00d2, cxinit, 8); + reg_w(gspca_dev, 0x00d2, cxinit, 8); cxinit += 8; - reg_w(gspca_dev->dev, 0x00da, cxinit, 6); + reg_w(gspca_dev, 0x00da, cxinit, 6); cxinit += 8; - reg_w(gspca_dev->dev, 0x0041, cxinit, 8); + reg_w(gspca_dev, 0x0041, cxinit, 8); cxinit += 8; - reg_w(gspca_dev->dev, 0x0049, cxinit, 8); + reg_w(gspca_dev, 0x0049, cxinit, 8); cxinit += 8; - reg_w(gspca_dev->dev, 0x0051, cxinit, 2); + reg_w(gspca_dev, 0x0051, cxinit, 2); - reg_r(gspca_dev->dev, 0x0010, &val, 1); - return val; + reg_r(gspca_dev, 0x0010, 1); } static const __u8 cx_jpeg_init[][8] = { @@ -636,26 +648,21 @@ static const __u8 cxjpeg_qtable[][8] = { static void cx11646_jpegInit(struct gspca_dev*gspca_dev) { - __u8 val; int i; int length; - val = 0x01; - reg_w(gspca_dev->dev, 0x00c0, &val, 1); - val = 0x00; - reg_w(gspca_dev->dev, 0x00c3, &val, 1); - val = 0x00; - reg_w(gspca_dev->dev, 0x00c0, &val, 1); - reg_r(gspca_dev->dev, 0x0001, &val, 1); + reg_w_val(gspca_dev, 0x00c0, 0x01); + reg_w_val(gspca_dev, 0x00c3, 0x00); + reg_w_val(gspca_dev, 0x00c0, 0x00); + reg_r(gspca_dev, 0x0001, 1); length = 8; for (i = 0; i < 79; i++) { if (i == 78) length = 6; - reg_w(gspca_dev->dev, 0x0008, cx_jpeg_init[i], length); + reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length); } - reg_r(gspca_dev->dev, 0x0002, &val, 1); - val = 0x14; - reg_w(gspca_dev->dev, 0x0055, &val, 1); + reg_r(gspca_dev, 0x0002, 1); + reg_w_val(gspca_dev, 0x0055, 0x14); } static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 }; @@ -665,31 +672,26 @@ static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 }; static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 }; static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 }; static const __u8 reg51[] = { 0x77, 0x03 }; -static const __u8 reg70 = 0x03; +#define reg70 0x03 static void cx11646_jpeg(struct gspca_dev*gspca_dev) { - __u8 val; int i; int length; __u8 Reg55; - __u8 bufread[8]; int retry; - val = 0x01; - reg_w(gspca_dev->dev, 0x00c0, &val, 1); - val = 0x00; - reg_w(gspca_dev->dev, 0x00c3, &val, 1); - val = 0x00; - reg_w(gspca_dev->dev, 0x00c0, &val, 1); - reg_r(gspca_dev->dev, 0x0001, &val, 1); + reg_w_val(gspca_dev, 0x00c0, 0x01); + reg_w_val(gspca_dev, 0x00c3, 0x00); + reg_w_val(gspca_dev, 0x00c0, 0x00); + reg_r(gspca_dev, 0x0001, 1); length = 8; switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 0: for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, cxjpeg_640[i], length); + reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length); } Reg55 = 0x28; break; @@ -697,7 +699,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, cxjpeg_352[i], length); + reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length); } Reg55 = 0x16; break; @@ -706,7 +708,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, cxjpeg_320[i], length); + reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length); } Reg55 = 0x14; break; @@ -714,124 +716,98 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev) for (i = 0; i < 27; i++) { if (i == 26) length = 2; - reg_w(gspca_dev->dev, 0x0008, cxjpeg_176[i], length); + reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length); } Reg55 = 0x0B; break; } - reg_r(gspca_dev->dev, 0x0002, &val, 1); - val = Reg55; - reg_w(gspca_dev->dev, 0x0055, &val, 1); - reg_r(gspca_dev->dev, 0x0002, &val, 1); - reg_w(gspca_dev->dev, 0x0010, reg10, 2); - val = 0x02; - reg_w(gspca_dev->dev, 0x0054, &val, 1); - val = 0x01; - reg_w(gspca_dev->dev, 0x0054, &val, 1); - val = 0x94; - reg_w(gspca_dev->dev, 0x0000, &val, 1); - val = 0xc0; - reg_w(gspca_dev->dev, 0x0053, &val, 1); - val = 0xe1; - reg_w(gspca_dev->dev, 0x00fc, &val, 1); - val = 0x00; - reg_w(gspca_dev->dev, 0x0000, &val, 1); + reg_r(gspca_dev, 0x0002, 1); + reg_w_val(gspca_dev, 0x0055, Reg55); + reg_r(gspca_dev, 0x0002, 1); + reg_w(gspca_dev, 0x0010, reg10, 2); + reg_w_val(gspca_dev, 0x0054, 0x02); + reg_w_val(gspca_dev, 0x0054, 0x01); + reg_w_val(gspca_dev, 0x0000, 0x94); + reg_w_val(gspca_dev, 0x0053, 0xc0); + reg_w_val(gspca_dev, 0x00fc, 0xe1); + reg_w_val(gspca_dev, 0x0000, 0x00); /* wait for completion */ retry = 50; while (retry--) { - reg_r(gspca_dev->dev, 0x0002, &val, 1); + reg_r(gspca_dev, 0x0002, 1); /* 0x07 until 0x00 */ - if (val == 0x00) + if (gspca_dev->usb_buf[0] == 0x00) break; - val = 0x00; - reg_w(gspca_dev->dev, 0x0053, &val, 1); + reg_w_val(gspca_dev, 0x0053, 0x00); } if (retry == 0) PDEBUG(D_ERR, "Damned Errors sending jpeg Table"); /* send the qtable now */ - reg_r(gspca_dev->dev, 0x0001, &val, 1); /* -> 0x18 */ + reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */ length = 8; for (i = 0; i < 18; i++) { if (i == 17) length = 2; - reg_w(gspca_dev->dev, 0x0008, cxjpeg_qtable[i], length); + reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length); } - reg_r(gspca_dev->dev, 0x0002, &val, 1); /* 0x00 */ - reg_r(gspca_dev->dev, 0x0053, &val, 1); /* 0x00 */ - val = 0x02; - reg_w(gspca_dev->dev, 0x0054, &val, 1); - val = 0x01; - reg_w(gspca_dev->dev, 0x0054, &val, 1); - val = 0x94; - reg_w(gspca_dev->dev, 0x0000, &val, 1); - val = 0xc0; - reg_w(gspca_dev->dev, 0x0053, &val, 1); - - reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ - reg_r(gspca_dev->dev, 0x0038, &val, 1); /* 0x40 */ - reg_r(gspca_dev->dev, 0x001f, &val, 1); /* 0x38 */ - reg_w(gspca_dev->dev, 0x0012, reg12, 5); - reg_w(gspca_dev->dev, 0x00e5, regE5_8, 8); - reg_r(gspca_dev->dev, 0x00e8, bufread, 8); - reg_w(gspca_dev->dev, 0x00e5, regE5a, 4); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ - val = 0x01; - reg_w(gspca_dev->dev, 0x009a, &val, 1); - reg_w(gspca_dev->dev, 0x00e5, regE5b, 4); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ - reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ - - reg_w(gspca_dev->dev, 0x0051, reg51, 2); - reg_w(gspca_dev->dev, 0x0010, reg10, 2); - reg_w(gspca_dev->dev, 0x0070, ®70, 1); + reg_r(gspca_dev, 0x0002, 1); /* 0x00 */ + reg_r(gspca_dev, 0x0053, 1); /* 0x00 */ + reg_w_val(gspca_dev, 0x0054, 0x02); + reg_w_val(gspca_dev, 0x0054, 0x01); + reg_w_val(gspca_dev, 0x0000, 0x94); + reg_w_val(gspca_dev, 0x0053, 0xc0); + + reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ + reg_r(gspca_dev, 0x0038, 1); /* 0x40 */ + reg_r(gspca_dev, 0x001f, 1); /* 0x38 */ + reg_w(gspca_dev, 0x0012, reg12, 5); + reg_w(gspca_dev, 0x00e5, regE5_8, 8); + reg_r(gspca_dev, 0x00e8, 8); + reg_w(gspca_dev, 0x00e5, regE5a, 4); + reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ + reg_w_val(gspca_dev, 0x009a, 0x01); + reg_w(gspca_dev, 0x00e5, regE5b, 4); + reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ + reg_w(gspca_dev, 0x00e5, regE5c, 4); + reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ + + reg_w(gspca_dev, 0x0051, reg51, 2); + reg_w(gspca_dev, 0x0010, reg10, 2); + reg_w_val(gspca_dev, 0x0070, reg70); } static void cx11646_init1(struct gspca_dev *gspca_dev) { - __u8 val; int i = 0; - val = 0; - reg_w(gspca_dev->dev, 0x0010, &val, 1); - reg_w(gspca_dev->dev, 0x0053, &val, 1); - reg_w(gspca_dev->dev, 0x0052, &val, 1); - val = 0x2f; - reg_w(gspca_dev->dev, 0x009b, &val, 1); - val = 0x10; - reg_w(gspca_dev->dev, 0x009c, &val, 1); - reg_r(gspca_dev->dev, 0x0098, &val, 1); - val = 0x40; - reg_w(gspca_dev->dev, 0x0098, &val, 1); - reg_r(gspca_dev->dev, 0x0099, &val, 1); - val = 0x07; - reg_w(gspca_dev->dev, 0x0099, &val, 1); - val = 0x40; - reg_w(gspca_dev->dev, 0x0039, &val, 1); - val = 0xff; - reg_w(gspca_dev->dev, 0x003c, &val, 1); - val = 0x1f; - reg_w(gspca_dev->dev, 0x003f, &val, 1); - val = 0x40; - reg_w(gspca_dev->dev, 0x003d, &val, 1); -/* val= 0x60; */ -/* reg_w(gspca_dev->dev, 0x00, 0x00, 0x003d, &val, 1); */ - reg_r(gspca_dev->dev, 0x0099, &val, 1); /* ->0x07 */ + reg_w_val(gspca_dev, 0x0010, 0x00); + reg_w_val(gspca_dev, 0x0053, 0x00); + reg_w_val(gspca_dev, 0x0052, 0x00); + reg_w_val(gspca_dev, 0x009b, 0x2f); + reg_w_val(gspca_dev, 0x009c, 0x10); + reg_r(gspca_dev, 0x0098, 1); + reg_w_val(gspca_dev, 0x0098, 0x40); + reg_r(gspca_dev, 0x0099, 1); + reg_w_val(gspca_dev, 0x0099, 0x07); + reg_w_val(gspca_dev, 0x0039, 0x40); + reg_w_val(gspca_dev, 0x003c, 0xff); + reg_w_val(gspca_dev, 0x003f, 0x1f); + reg_w_val(gspca_dev, 0x003d, 0x40); +/* reg_w_val(gspca_dev, 0x003d, 0x60); */ + reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */ while (cx_sensor_init[i][0]) { - reg_w(gspca_dev->dev, 0x00e5, cx_sensor_init[i], 1); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* -> 0x00 */ + reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]); + reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */ if (i == 1) { - val = 1; - reg_w(gspca_dev->dev, 0x00ed, &val, 1); - reg_r(gspca_dev->dev, 0x00ed, &val, 1); /* -> 0x01 */ + reg_w_val(gspca_dev, 0x00ed, 0x01); + reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */ } i++; } - val = 0x00; - reg_w(gspca_dev->dev, 0x00c3, &val, 1); + reg_w_val(gspca_dev, 0x00c3, 0x00); } /* this function is called at probe time */ @@ -880,29 +856,23 @@ static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_stop0(struct gspca_dev *gspca_dev) { int retry = 50; - __u8 val; - val = 0; - reg_w(gspca_dev->dev, 0x0000, &val, 1); - reg_r(gspca_dev->dev, 0x0002, &val, 1); - val = 0; - reg_w(gspca_dev->dev, 0x0053, &val, 1); + reg_w_val(gspca_dev, 0x0000, 0x00); + reg_r(gspca_dev, 0x0002, 1); + reg_w_val(gspca_dev, 0x0053, 0x00); while (retry--) { -/* reg_r(gspca_dev->dev, 0x0002, &val, 1);*/ - reg_r(gspca_dev->dev, 0x0053, &val, 1); - if (val == 0) +/* reg_r(gspca_dev, 0x0002, 1);*/ + reg_r(gspca_dev, 0x0053, 1); + if (gspca_dev->usb_buf[0] == 0) break; } - val = 0; - reg_w(gspca_dev->dev, 0x0000, &val, 1); - reg_r(gspca_dev->dev, 0x0002, &val, 1); - - val = 0; - reg_w(gspca_dev->dev, 0x0010, &val, 1); - reg_r(gspca_dev->dev, 0x0033, &val, 1); - val = 0xe0; - reg_w(gspca_dev->dev, 0x00fc, &val, 1); + reg_w_val(gspca_dev, 0x0000, 0x00); + reg_r(gspca_dev, 0x0002, 1); + + reg_w_val(gspca_dev, 0x0010, 0x00); + reg_r(gspca_dev, 0x0033, 1); + reg_w_val(gspca_dev, 0x00fc, 0xe0); } static void sd_close(struct gspca_dev *gspca_dev) @@ -937,22 +907,20 @@ static void setbrightness(struct gspca_dev*gspca_dev) __u8 reg51c[2]; __u8 bright; __u8 colors; - __u8 val; - __u8 bufread[8]; bright = sd->brightness; regE5cbx[2] = bright; - reg_w(gspca_dev->dev, 0x00e5, regE5cbx, 8); - reg_r(gspca_dev->dev, 0x00e8, bufread, 8); - reg_w(gspca_dev->dev, 0x00e5, regE5c, 4); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + reg_w(gspca_dev, 0x00e5, regE5cbx, 8); + reg_r(gspca_dev, 0x00e8, 8); + reg_w(gspca_dev, 0x00e5, regE5c, 4); + reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ colors = sd->colors; reg51c[0] = 0x77; reg51c[1] = colors; - reg_w(gspca_dev->dev, 0x0051, reg51c, 2); - reg_w(gspca_dev->dev, 0x0010, reg10, 2); - reg_w(gspca_dev->dev, 0x0070, ®70, 1); + reg_w(gspca_dev, 0x0051, reg51c, 2); + reg_w(gspca_dev, 0x0010, reg10, 2); + reg_w_val(gspca_dev, 0x0070, reg70); } static void setcontrast(struct gspca_dev*gspca_dev) @@ -961,16 +929,15 @@ static void setcontrast(struct gspca_dev*gspca_dev) __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */ /* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */ __u8 reg51c[2]; - __u8 val; regE5acx[2] = sd->contrast; - reg_w(gspca_dev->dev, 0x00e5, regE5acx, 4); - reg_r(gspca_dev->dev, 0x00e8, &val, 1); /* 0x00 */ + reg_w(gspca_dev, 0x00e5, regE5acx, 4); + reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */ reg51c[0] = 0x77; reg51c[1] = sd->colors; - reg_w(gspca_dev->dev, 0x0051, reg51c, 2); - reg_w(gspca_dev->dev, 0x0010, reg10, 2); - reg_w(gspca_dev->dev, 0x0070, ®70, 1); + reg_w(gspca_dev, 0x0051, reg51c, 2); + reg_w(gspca_dev, 0x0010, reg10, 2); + reg_w_val(gspca_dev, 0x0070, reg70); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 1da6a182561f..5bb8dc1adbb7 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("Etoms USB Camera Driver"); @@ -229,201 +229,215 @@ static const __u8 I2c3[] = { 0x12, 0x05 }; static const __u8 I2c4[] = { 0x41, 0x08 }; -static void reg_r(struct usb_device *dev, - __u16 index, __u8 *buffer, int len) +/* read 'len' bytes to gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 index, + __u16 len) { + struct usb_device *dev = gspca_dev->dev; + +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof gspca_dev->usb_buf) { + err("reg_r: buffer overflow"); + return; + } +#endif usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, buffer, len, 500); + 0, + index, gspca_dev->usb_buf, len, 500); + PDEBUG(D_USBI, "reg read [%02x] -> %02x ..", + index, gspca_dev->usb_buf[0]); } -static void reg_w_val(struct usb_device *dev, - __u16 index, __u8 val) +static void reg_w_val(struct gspca_dev *gspca_dev, + __u16 index, + __u8 val) { - __u8 data; + struct usb_device *dev = gspca_dev->dev; - data = val; + gspca_dev->usb_buf[0] = val; usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, &data, 1, 500); + 0, + index, gspca_dev->usb_buf, 1, 500); } -static void reg_w(struct usb_device *dev, - __u16 index, const __u8 *buffer, __u16 len) +static void reg_w(struct gspca_dev *gspca_dev, + __u16 index, + const __u8 *buffer, + __u16 len) { - __u8 tmpbuf[8]; + struct usb_device *dev = gspca_dev->dev; - memcpy(tmpbuf, buffer, len); +#ifdef CONFIG_VIDEO_ADV_DEBUG + if (len > sizeof gspca_dev->usb_buf) { + err("reg_w: buffer overflow"); + return; + } + PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer); +#endif + memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0, index, tmpbuf, len, 500); + 0, index, gspca_dev->usb_buf, len, 500); } -static int Et_i2cwrite(struct usb_device *dev, __u8 reg, - const __u8 *buffer, - __u16 len, __u8 mode) +static int i2c_w(struct gspca_dev *gspca_dev, + __u8 reg, + const __u8 *buffer, + __u16 len, __u8 mode) { /* buffer should be [D0..D7] */ __u8 ptchcount; /* set the base address */ - reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ + reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); + /* sensor base for the pas106 */ /* set count and prefetch */ ptchcount = ((len & 0x07) << 4) | (mode & 0x03); - reg_w_val(dev, ET_I2C_COUNT, ptchcount); + reg_w_val(gspca_dev, ET_I2C_COUNT, ptchcount); /* set the register base */ - reg_w_val(dev, ET_I2C_REG, reg); + reg_w_val(gspca_dev, ET_I2C_REG, reg); while (--len >= 0) - reg_w_val(dev, ET_I2C_DATA0 + len, buffer[len]); + reg_w_val(gspca_dev, ET_I2C_DATA0 + len, buffer[len]); return 0; } -static int Et_i2cread(struct usb_device *dev, __u8 reg, - __u8 *buffer, - __u16 length, __u8 mode) +static int i2c_r(struct gspca_dev *gspca_dev, + __u8 reg) { - /* buffer should be [D0..D7] */ - int i, j; - __u8 ptchcount; - /* set the base address */ - reg_w_val(dev, ET_I2C_BASE, 0x40); /* sensor base for the pas106 */ - /* set count and prefetch */ - ptchcount = ((length & 0x07) << 4) | (mode & 0x03); - reg_w_val(dev, ET_I2C_COUNT, ptchcount); - /* set the register base */ - reg_w_val(dev, ET_I2C_REG, reg); - reg_w_val(dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ - reg_w_val(dev, ET_I2C_PREFETCH, 0); - j = length - 1; - for (i = 0; i < length; i++) { - reg_r(dev, (ET_I2C_DATA0 + j), &buffer[j], 1); - j--; - } + reg_w_val(gspca_dev, ET_I2C_BASE, 0x40); + /* sensor base for the pas106 */ + /* set count and prefetch (cnd: 4 bits - mode: 4 bits) */ + reg_w_val(gspca_dev, ET_I2C_COUNT, 0x11); + reg_w_val(gspca_dev, ET_I2C_REG, reg); /* set the register base */ + reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x02); /* prefetch */ + reg_w_val(gspca_dev, ET_I2C_PREFETCH, 0x00); + reg_r(gspca_dev, ET_I2C_DATA0, 1); /* read one byte */ return 0; } -static int Et_WaitStatus(struct usb_device *dev) +static int Et_WaitStatus(struct gspca_dev *gspca_dev) { - __u8 bytereceived; int retry = 10; while (retry--) { - reg_r(dev, ET_ClCK, &bytereceived, 1); - if (bytereceived != 0) + reg_r(gspca_dev, ET_ClCK, 1); + if (gspca_dev->usb_buf[0] != 0) return 1; } return 0; } -static int et_video(struct usb_device *dev, int on) +static int et_video(struct gspca_dev *gspca_dev, + int on) { - int err; + int ret; - reg_w_val(dev, ET_GPIO_OUT, on - ? 0x10 /* startvideo - set Bit5 */ - : 0); /* stopvideo */ - err = Et_WaitStatus(dev); - if (!err) + reg_w_val(gspca_dev, ET_GPIO_OUT, + on ? 0x10 /* startvideo - set Bit5 */ + : 0); /* stopvideo */ + ret = Et_WaitStatus(gspca_dev); + if (ret != 0) PDEBUG(D_ERR, "timeout video on/off"); - return err; + return ret; } static void Et_init2(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; __u8 value; - __u8 received; static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 }; PDEBUG(D_STREAM, "Open Init2 ET"); - reg_w_val(dev, ET_GPIO_DIR_CTRL, 0x2f); - reg_w_val(dev, ET_GPIO_OUT, 0x10); - reg_r(dev, ET_GPIO_IN, &received, 1); - reg_w_val(dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ - reg_w_val(dev, ET_CTRL, 0x1b); + reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f); + reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10); + reg_r(gspca_dev, ET_GPIO_IN, 1); + reg_w_val(gspca_dev, ET_ClCK, 0x14); /* 0x14 // 0x16 enabled pattern */ + reg_w_val(gspca_dev, ET_CTRL, 0x1b); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) value = ET_COMP_VAL1; /* 320 */ else value = ET_COMP_VAL0; /* 640 */ - reg_w_val(dev, ET_COMP, value); - reg_w_val(dev, ET_MAXQt, 0x1f); - reg_w_val(dev, ET_MINQt, 0x04); + reg_w_val(gspca_dev, ET_COMP, value); + reg_w_val(gspca_dev, ET_MAXQt, 0x1f); + reg_w_val(gspca_dev, ET_MINQt, 0x04); /* undocumented registers */ - reg_w_val(dev, ET_REG1d, 0xff); - reg_w_val(dev, ET_REG1e, 0xff); - reg_w_val(dev, ET_REG1f, 0xff); - reg_w_val(dev, ET_REG20, 0x35); - reg_w_val(dev, ET_REG21, 0x01); - reg_w_val(dev, ET_REG22, 0x00); - reg_w_val(dev, ET_REG23, 0xff); - reg_w_val(dev, ET_REG24, 0xff); - reg_w_val(dev, ET_REG25, 0x0f); + reg_w_val(gspca_dev, ET_REG1d, 0xff); + reg_w_val(gspca_dev, ET_REG1e, 0xff); + reg_w_val(gspca_dev, ET_REG1f, 0xff); + reg_w_val(gspca_dev, ET_REG20, 0x35); + reg_w_val(gspca_dev, ET_REG21, 0x01); + reg_w_val(gspca_dev, ET_REG22, 0x00); + reg_w_val(gspca_dev, ET_REG23, 0xff); + reg_w_val(gspca_dev, ET_REG24, 0xff); + reg_w_val(gspca_dev, ET_REG25, 0x0f); /* colors setting */ - reg_w_val(dev, 0x30, 0x11); /* 0x30 */ - reg_w_val(dev, 0x31, 0x40); - reg_w_val(dev, 0x32, 0x00); - reg_w_val(dev, ET_O_RED, 0x00); /* 0x34 */ - reg_w_val(dev, ET_O_GREEN1, 0x00); - reg_w_val(dev, ET_O_BLUE, 0x00); - reg_w_val(dev, ET_O_GREEN2, 0x00); + reg_w_val(gspca_dev, 0x30, 0x11); /* 0x30 */ + reg_w_val(gspca_dev, 0x31, 0x40); + reg_w_val(gspca_dev, 0x32, 0x00); + reg_w_val(gspca_dev, ET_O_RED, 0x00); /* 0x34 */ + reg_w_val(gspca_dev, ET_O_GREEN1, 0x00); + reg_w_val(gspca_dev, ET_O_BLUE, 0x00); + reg_w_val(gspca_dev, ET_O_GREEN2, 0x00); /*************/ - reg_w_val(dev, ET_G_RED, 0x80); /* 0x4d */ - reg_w_val(dev, ET_G_GREEN1, 0x80); - reg_w_val(dev, ET_G_BLUE, 0x80); - reg_w_val(dev, ET_G_GREEN2, 0x80); - reg_w_val(dev, ET_G_GR_H, 0x00); - reg_w_val(dev, ET_G_GB_H, 0x00); /* 0x52 */ + reg_w_val(gspca_dev, ET_G_RED, 0x80); /* 0x4d */ + reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); + reg_w_val(gspca_dev, ET_G_BLUE, 0x80); + reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); + reg_w_val(gspca_dev, ET_G_GR_H, 0x00); + reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* 0x52 */ /* Window control registers */ - reg_w_val(dev, 0x61, 0x80); /* use cmc_out */ - reg_w_val(dev, 0x62, 0x02); - reg_w_val(dev, 0x63, 0x03); - reg_w_val(dev, 0x64, 0x14); - reg_w_val(dev, 0x65, 0x0e); - reg_w_val(dev, 0x66, 0x02); - reg_w_val(dev, 0x67, 0x02); + reg_w_val(gspca_dev, 0x61, 0x80); /* use cmc_out */ + reg_w_val(gspca_dev, 0x62, 0x02); + reg_w_val(gspca_dev, 0x63, 0x03); + reg_w_val(gspca_dev, 0x64, 0x14); + reg_w_val(gspca_dev, 0x65, 0x0e); + reg_w_val(gspca_dev, 0x66, 0x02); + reg_w_val(gspca_dev, 0x67, 0x02); /**************************************/ - reg_w_val(dev, ET_SYNCHRO, 0x8f); /* 0x68 */ - reg_w_val(dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ - reg_w_val(dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ - reg_w_val(dev, ET_WIDTH_LOW, 0x80); - reg_w_val(dev, ET_HEIGTH_LOW, 0xe0); - reg_w_val(dev, ET_W_H_HEIGTH, 0x60); /* 6d */ - reg_w_val(dev, ET_REG6e, 0x86); - reg_w_val(dev, ET_REG6f, 0x01); - reg_w_val(dev, ET_REG70, 0x26); - reg_w_val(dev, ET_REG71, 0x7a); - reg_w_val(dev, ET_REG72, 0x01); + reg_w_val(gspca_dev, ET_SYNCHRO, 0x8f); /* 0x68 */ + reg_w_val(gspca_dev, ET_STARTX, 0x69); /* 0x6a //0x69 */ + reg_w_val(gspca_dev, ET_STARTY, 0x0d); /* 0x0d //0x0c */ + reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x80); + reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0xe0); + reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x60); /* 6d */ + reg_w_val(gspca_dev, ET_REG6e, 0x86); + reg_w_val(gspca_dev, ET_REG6f, 0x01); + reg_w_val(gspca_dev, ET_REG70, 0x26); + reg_w_val(gspca_dev, ET_REG71, 0x7a); + reg_w_val(gspca_dev, ET_REG72, 0x01); /* Clock Pattern registers ***************** */ - reg_w_val(dev, ET_REG73, 0x00); - reg_w_val(dev, ET_REG74, 0x18); /* 0x28 */ - reg_w_val(dev, ET_REG75, 0x0f); /* 0x01 */ + reg_w_val(gspca_dev, ET_REG73, 0x00); + reg_w_val(gspca_dev, ET_REG74, 0x18); /* 0x28 */ + reg_w_val(gspca_dev, ET_REG75, 0x0f); /* 0x01 */ /**********************************************/ - reg_w_val(dev, 0x8a, 0x20); - reg_w_val(dev, 0x8d, 0x0f); - reg_w_val(dev, 0x8e, 0x08); + reg_w_val(gspca_dev, 0x8a, 0x20); + reg_w_val(gspca_dev, 0x8d, 0x0f); + reg_w_val(gspca_dev, 0x8e, 0x08); /**************************************/ - reg_w_val(dev, 0x03, 0x08); - reg_w_val(dev, ET_PXL_CLK, 0x03); - reg_w_val(dev, 0x81, 0xff); - reg_w_val(dev, 0x80, 0x00); - reg_w_val(dev, 0x81, 0xff); - reg_w_val(dev, 0x80, 0x20); - reg_w_val(dev, 0x03, 0x01); - reg_w_val(dev, 0x03, 0x00); - reg_w_val(dev, 0x03, 0x08); + reg_w_val(gspca_dev, 0x03, 0x08); + reg_w_val(gspca_dev, ET_PXL_CLK, 0x03); + reg_w_val(gspca_dev, 0x81, 0xff); + reg_w_val(gspca_dev, 0x80, 0x00); + reg_w_val(gspca_dev, 0x81, 0xff); + reg_w_val(gspca_dev, 0x80, 0x20); + reg_w_val(gspca_dev, 0x03, 0x01); + reg_w_val(gspca_dev, 0x03, 0x00); + reg_w_val(gspca_dev, 0x03, 0x08); /********************************************/ -/* reg_r(dev, ET_I2C_BASE, &received, 1); +/* reg_r(gspca_dev, ET_I2C_BASE, 1); always 0x40 as the pas106 ??? */ /* set the sensor */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) @@ -435,25 +449,24 @@ static void Et_init2(struct gspca_dev *gspca_dev) * 0x0b -> 24/(11+1) = 2 Mhz * 0x17 -> 24/(23+1) = 1 Mhz */ - reg_w_val(dev, ET_PXL_CLK, value); + reg_w_val(gspca_dev, ET_PXL_CLK, value); /* now set by fifo the FormatLine setting */ - reg_w(dev, 0x62, FormLine, 6); + reg_w(gspca_dev, 0x62, FormLine, 6); /* set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue */ - reg_w_val(dev, 0x81, 0x47); /* 0x47; */ - reg_w_val(dev, 0x80, 0x40); /* 0x40; */ + reg_w_val(gspca_dev, 0x81, 0x47); /* 0x47; */ + reg_w_val(gspca_dev, 0x80, 0x40); /* 0x40; */ /* Pedro change */ /* Brightness change Brith+ decrease value */ /* Brigth- increase value */ /* original value = 0x70; */ - reg_w_val(dev, 0x81, 0x30); /* 0x20; - set brightness */ - reg_w_val(dev, 0x80, 0x20); /* 0x20; */ + reg_w_val(gspca_dev, 0x81, 0x30); /* 0x20; - set brightness */ + reg_w_val(gspca_dev, 0x80, 0x20); /* 0x20; */ } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 I2cc[] = { 0x05, 0x02, 0x02, 0x05, 0x0d }; __u8 i2cflags = 0x01; /* __u8 green = 0; */ @@ -464,8 +477,8 @@ static void setcolors(struct gspca_dev *gspca_dev) /* green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1); */ /* I2cc[1] = I2cc[2] = green; */ if (sd->sensor == SENSOR_PAS106) { - Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); - Et_i2cwrite(dev, PAS106_REG9, I2cc, sizeof I2cc, 1); + i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); + i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1); } /* PDEBUG(D_CONF , "Etoms red %d blue %d green %d", I2cc[3], I2cc[0], green); */ @@ -474,21 +487,17 @@ static void setcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; -/* __u8 valblue; */ - __u8 valred; if (sd->sensor == SENSOR_PAS106) { -/* Et_i2cread(gspca_dev->dev, PAS106_REG9, &valblue, 1, 1); */ - Et_i2cread(gspca_dev->dev, PAS106_REG9 + 3, &valred, 1, 1); - sd->colors = valred & 0x0f; +/* i2c_r(gspca_dev, PAS106_REG9); * blue */ + i2c_r(gspca_dev, PAS106_REG9 + 3); /* red */ + sd->colors = gspca_dev->usb_buf[0] & 0x0f; } } static void Et_init1(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; __u8 value; - __u8 received; /* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0x22, 0xac, 0x00, 0x01, 0x00}; */ __u8 I2c0[] = { 0x0a, 0x12, 0x05, 0x6d, 0xcd, 0x00, 0x01, 0x00 }; /* try 1/120 0x6d 0xcd 0x40 */ @@ -496,12 +505,12 @@ static void Et_init1(struct gspca_dev *gspca_dev) * 1/60000 hmm ?? */ PDEBUG(D_STREAM, "Open Init1 ET"); - reg_w_val(dev, ET_GPIO_DIR_CTRL, 7); - reg_r(dev, ET_GPIO_IN, &received, 1); - reg_w_val(dev, ET_RESET_ALL, 1); - reg_w_val(dev, ET_RESET_ALL, 0); - reg_w_val(dev, ET_ClCK, 0x10); - reg_w_val(dev, ET_CTRL, 0x19); + reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7); + reg_r(gspca_dev, ET_GPIO_IN, 1); + reg_w_val(gspca_dev, ET_RESET_ALL, 1); + reg_w_val(gspca_dev, ET_RESET_ALL, 0); + reg_w_val(gspca_dev, ET_ClCK, 0x10); + reg_w_val(gspca_dev, ET_CTRL, 0x19); /* compression et subsampling */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) value = ET_COMP_VAL1; @@ -510,80 +519,79 @@ static void Et_init1(struct gspca_dev *gspca_dev) PDEBUG(D_STREAM, "Open mode %d Compression %d", gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv, value); - reg_w_val(dev, ET_COMP, value); - reg_w_val(dev, ET_MAXQt, 0x1d); - reg_w_val(dev, ET_MINQt, 0x02); + reg_w_val(gspca_dev, ET_COMP, value); + reg_w_val(gspca_dev, ET_MAXQt, 0x1d); + reg_w_val(gspca_dev, ET_MINQt, 0x02); /* undocumented registers */ - reg_w_val(dev, ET_REG1d, 0xff); - reg_w_val(dev, ET_REG1e, 0xff); - reg_w_val(dev, ET_REG1f, 0xff); - reg_w_val(dev, ET_REG20, 0x35); - reg_w_val(dev, ET_REG21, 0x01); - reg_w_val(dev, ET_REG22, 0x00); - reg_w_val(dev, ET_REG23, 0xf7); - reg_w_val(dev, ET_REG24, 0xff); - reg_w_val(dev, ET_REG25, 0x07); + reg_w_val(gspca_dev, ET_REG1d, 0xff); + reg_w_val(gspca_dev, ET_REG1e, 0xff); + reg_w_val(gspca_dev, ET_REG1f, 0xff); + reg_w_val(gspca_dev, ET_REG20, 0x35); + reg_w_val(gspca_dev, ET_REG21, 0x01); + reg_w_val(gspca_dev, ET_REG22, 0x00); + reg_w_val(gspca_dev, ET_REG23, 0xf7); + reg_w_val(gspca_dev, ET_REG24, 0xff); + reg_w_val(gspca_dev, ET_REG25, 0x07); /* colors setting */ - reg_w_val(dev, ET_G_RED, 0x80); - reg_w_val(dev, ET_G_GREEN1, 0x80); - reg_w_val(dev, ET_G_BLUE, 0x80); - reg_w_val(dev, ET_G_GREEN2, 0x80); - reg_w_val(dev, ET_G_GR_H, 0x00); - reg_w_val(dev, ET_G_GB_H, 0x00); + reg_w_val(gspca_dev, ET_G_RED, 0x80); + reg_w_val(gspca_dev, ET_G_GREEN1, 0x80); + reg_w_val(gspca_dev, ET_G_BLUE, 0x80); + reg_w_val(gspca_dev, ET_G_GREEN2, 0x80); + reg_w_val(gspca_dev, ET_G_GR_H, 0x00); + reg_w_val(gspca_dev, ET_G_GB_H, 0x00); /* Window control registers */ - reg_w_val(dev, ET_SYNCHRO, 0xf0); - reg_w_val(dev, ET_STARTX, 0x56); /* 0x56 */ - reg_w_val(dev, ET_STARTY, 0x05); /* 0x04 */ - reg_w_val(dev, ET_WIDTH_LOW, 0x60); - reg_w_val(dev, ET_HEIGTH_LOW, 0x20); - reg_w_val(dev, ET_W_H_HEIGTH, 0x50); - reg_w_val(dev, ET_REG6e, 0x86); - reg_w_val(dev, ET_REG6f, 0x01); - reg_w_val(dev, ET_REG70, 0x86); - reg_w_val(dev, ET_REG71, 0x14); - reg_w_val(dev, ET_REG72, 0x00); + reg_w_val(gspca_dev, ET_SYNCHRO, 0xf0); + reg_w_val(gspca_dev, ET_STARTX, 0x56); /* 0x56 */ + reg_w_val(gspca_dev, ET_STARTY, 0x05); /* 0x04 */ + reg_w_val(gspca_dev, ET_WIDTH_LOW, 0x60); + reg_w_val(gspca_dev, ET_HEIGTH_LOW, 0x20); + reg_w_val(gspca_dev, ET_W_H_HEIGTH, 0x50); + reg_w_val(gspca_dev, ET_REG6e, 0x86); + reg_w_val(gspca_dev, ET_REG6f, 0x01); + reg_w_val(gspca_dev, ET_REG70, 0x86); + reg_w_val(gspca_dev, ET_REG71, 0x14); + reg_w_val(gspca_dev, ET_REG72, 0x00); /* Clock Pattern registers */ - reg_w_val(dev, ET_REG73, 0x00); - reg_w_val(dev, ET_REG74, 0x00); - reg_w_val(dev, ET_REG75, 0x0a); - reg_w_val(dev, ET_I2C_CLK, 0x04); - reg_w_val(dev, ET_PXL_CLK, 0x01); + reg_w_val(gspca_dev, ET_REG73, 0x00); + reg_w_val(gspca_dev, ET_REG74, 0x00); + reg_w_val(gspca_dev, ET_REG75, 0x0a); + reg_w_val(gspca_dev, ET_I2C_CLK, 0x04); + reg_w_val(gspca_dev, ET_PXL_CLK, 0x01); /* set the sensor */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { I2c0[0] = 0x06; - Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); - Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); + i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); + i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); value = 0x06; - Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); - Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1); + i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); + i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); /* value = 0x1f; */ value = 0x04; - Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); + i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); } else { I2c0[0] = 0x0a; - Et_i2cwrite(dev, PAS106_REG2, I2c0, sizeof I2c0, 1); - Et_i2cwrite(dev, PAS106_REG9, I2c2, sizeof I2c2, 1); + i2c_w(gspca_dev, PAS106_REG2, I2c0, sizeof I2c0, 1); + i2c_w(gspca_dev, PAS106_REG9, I2c2, sizeof I2c2, 1); value = 0x0a; - - Et_i2cwrite(dev, PAS106_REG2, &value, 1, 1); - Et_i2cwrite(dev, PAS106_REG3, I2c3, sizeof I2c3, 1); + i2c_w(gspca_dev, PAS106_REG2, &value, 1, 1); + i2c_w(gspca_dev, PAS106_REG3, I2c3, sizeof I2c3, 1); value = 0x04; /* value = 0x10; */ - Et_i2cwrite(dev, PAS106_REG0e, &value, 1, 1); + i2c_w(gspca_dev, PAS106_REG0e, &value, 1, 1); /* bit 2 enable bit 1:2 select 0 1 2 3 value = 0x07; * curve 0 * - Et_i2cwrite(dev,PAS106_REG0f,&value,1,1); + i2c_w(gspca_dev, PAS106_REG0f, &value, 1, 1); */ } /* value = 0x01; */ /* value = 0x22; */ -/* Et_i2cwrite(dev, PAS106_REG5, &value, 1, 1); */ +/* i2c_w(gspca_dev, PAS106_REG5, &value, 1, 1); */ /* magnetude and sign bit for DAC */ - Et_i2cwrite(dev, PAS106_REG7, I2c4, sizeof I2c4, 1); + i2c_w(gspca_dev, PAS106_REG7, I2c4, sizeof I2c4, 1); /* now set by fifo the whole colors setting */ - reg_w(dev, ET_G_RED, GainRGBG, 6); + reg_w(gspca_dev, ET_G_RED, GainRGBG, 6); getcolors(gspca_dev); setcolors(gspca_dev); } @@ -632,14 +640,13 @@ static int sd_config(struct gspca_dev *gspca_dev, static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; if (sd->sensor == SENSOR_PAS106) Et_init1(gspca_dev); else Et_init2(gspca_dev); - reg_w_val(dev, ET_RESET_ALL, 0x08); - et_video(dev, 0); /* video off */ + reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); + et_video(gspca_dev, 0); /* video off */ return 0; } @@ -647,20 +654,19 @@ static int sd_open(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; if (sd->sensor == SENSOR_PAS106) Et_init1(gspca_dev); else Et_init2(gspca_dev); - reg_w_val(dev, ET_RESET_ALL, 0x08); - et_video(dev, 1); /* video on */ + reg_w_val(gspca_dev, ET_RESET_ALL, 0x08); + et_video(gspca_dev, 1); /* video on */ } static void sd_stopN(struct gspca_dev *gspca_dev) { - et_video(gspca_dev->dev, 0); /* video off */ + et_video(gspca_dev, 0); /* video off */ } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -678,7 +684,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 brightness = sd->brightness; for (i = 0; i < 4; i++) - reg_w_val(gspca_dev->dev, (ET_O_RED + i), brightness); + reg_w_val(gspca_dev, ET_O_RED + i, brightness); } static void getbrightness(struct gspca_dev *gspca_dev) @@ -686,11 +692,10 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; int brightness = 0; - __u8 value; for (i = 0; i < 4; i++) { - reg_r(gspca_dev->dev, (ET_O_RED + i), &value, 1); - brightness += value; + reg_r(gspca_dev, ET_O_RED + i, 1); + brightness += gspca_dev->usb_buf[0]; } sd->brightness = brightness >> 3; } @@ -701,8 +706,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) __u8 RGBG[] = { 0x80, 0x80, 0x80, 0x80, 0x00, 0x00 }; __u8 contrast = sd->contrast; - memset(RGBG, contrast, sizeof RGBG - 2); - reg_w(gspca_dev->dev, ET_G_RED, RGBG, 6); + memset(RGBG, contrast, sizeof(RGBG) - 2); + reg_w(gspca_dev, ET_G_RED, RGBG, 6); } static void getcontrast(struct gspca_dev *gspca_dev) @@ -710,11 +715,10 @@ static void getcontrast(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int i; int contrast = 0; - __u8 value = 0; for (i = 0; i < 4; i++) { - reg_r(gspca_dev->dev, (ET_G_RED + i), &value, 1); - contrast += value; + reg_r(gspca_dev, ET_G_RED + i, 1); + contrast += gspca_dev->usb_buf[0]; } sd->contrast = contrast >> 2; } @@ -722,12 +726,11 @@ static void getcontrast(struct gspca_dev *gspca_dev) static __u8 Et_getgainG(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 value = 0; if (sd->sensor == SENSOR_PAS106) { - Et_i2cread(gspca_dev->dev, PAS106_REG0e, &value, 1, 1); - PDEBUG(D_CONF, "Etoms gain G %d", value); - return value; + i2c_r(gspca_dev, PAS106_REG0e); + PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]); + return gspca_dev->usb_buf[0]; } return 0x1f; } @@ -735,12 +738,12 @@ static __u8 Et_getgainG(struct gspca_dev *gspca_dev) static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - __u8 i2cflags = 0x01; if (sd->sensor == SENSOR_PAS106) { - Et_i2cwrite(dev, PAS106_REG13, &i2cflags, 1, 3); - Et_i2cwrite(dev, PAS106_REG0e, &gain, 1, 1); + __u8 i2cflags = 0x01; + + i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3); + i2c_w(gspca_dev, PAS106_REG0e, &gain, 1, 1); } } @@ -751,8 +754,6 @@ static void Et_setgainG(struct gspca_dev *gspca_dev, __u8 gain) static void setautogain(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 GRBG[] = { 0, 0, 0, 0 }; __u8 luma = 0; __u8 luma_mean = 128; __u8 luma_delta = 20; @@ -761,10 +762,10 @@ static void setautogain(struct gspca_dev *gspca_dev) __u8 r, g, b; Gbright = Et_getgainG(gspca_dev); - reg_r(dev, ET_LUMA_CENTER, GRBG, 4); - g = (GRBG[0] + GRBG[3]) >> 1; - r = GRBG[1]; - b = GRBG[2]; + reg_r(gspca_dev, ET_LUMA_CENTER, 4); + g = (gspca_dev->usb_buf[0] + gspca_dev->usb_buf[3]) >> 1; + r = gspca_dev->usb_buf[1]; + b = gspca_dev->usb_buf[2]; r = ((r << 8) - (r << 4) - (r << 3)) >> 10; b = ((b << 7) >> 10); g = ((g << 9) + (g << 7) + (g << 5)) >> 10; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index a566fd394895..242f0fb68d6e 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1347,9 +1347,11 @@ ok: gspca_dev->fr_i, gspca_dev->fr_o); - if (gspca_dev->sd_desc->dq_callback) + if (gspca_dev->sd_desc->dq_callback) { + mutex_lock(&gspca_dev->usb_lock); gspca_dev->sd_desc->dq_callback(gspca_dev); - + mutex_unlock(&gspca_dev->usb_lock); + } return j; } diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h index 78fccefcd576..3fd2c4eee204 100644 --- a/drivers/media/video/gspca/gspca.h +++ b/drivers/media/video/gspca/gspca.h @@ -125,6 +125,7 @@ struct gspca_dev { struct cam cam; /* device information */ const struct sd_desc *sd_desc; /* subdriver description */ + __u8 usb_buf[8]; /* buffer for USB exchanges */ struct urb *urb[MAX_NURBS]; __u8 *frbuf; /* buffer for nframes */ diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 23f3dba8012a..88c2b02f380a 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); @@ -83,39 +83,53 @@ enum { REG_HW_MI_63, REG_HW_MI_64, REG_HW_MI_F1 = 0xf1, - ATTR_TOTAL_MI_REG = 242 + ATTR_TOTAL_MI_REG = 0xf2 }; -static int pcam_reg_write(struct usb_device *dev, - __u16 index, __u8 *value, int len) +/* the bytes to write are in gspca_dev->usb_buf */ +static int reg_w(struct gspca_dev *gspca_dev, + __u16 index, int len) { int rc; - rc = usb_control_msg(dev, - usb_sndbulkpipe(dev, 4), + rc = usb_control_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 4), 0x12, -/* ?? 0xc8 = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_??? !? */ - 0xc8, + 0xc8, /* ?? */ 0, /* value */ - index, value, len, 500); + index, gspca_dev->usb_buf, len, 500); if (rc < 0) PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); return rc; } -static void MISensor_BulkWrite(struct usb_device *dev, - unsigned short *pch, - char Address) +static int reg_w_buf(struct gspca_dev *gspca_dev, + __u16 index, __u8 *buf, int len) { - __u8 data[6]; + int rc; + + rc = usb_control_msg(gspca_dev->dev, + usb_sndbulkpipe(gspca_dev->dev, 4), + 0x12, + 0xc8, /* ?? */ + 0, /* value */ + index, buf, len, 500); + if (rc < 0) + PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc); + return rc; +} - data[0] = 0x1f; - data[1] = 0; /* control byte */ - data[2] = Address; - data[3] = *pch >> 8; /* high byte */ - data[4] = *pch; /* low byte */ +static void bulk_w(struct gspca_dev *gspca_dev, + __u16 *pch, + __u16 Address) +{ + gspca_dev->usb_buf[0] = 0x1f; + gspca_dev->usb_buf[1] = 0; /* control byte */ + gspca_dev->usb_buf[2] = Address; + gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */ + gspca_dev->usb_buf[4] = *pch; /* low byte */ - pcam_reg_write(dev, Address, data, 5); + reg_w(gspca_dev, Address, 5); } /* this function is called at probe time */ @@ -142,33 +156,30 @@ static int sd_open(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; int err_code; - __u8 data[12]; - __u16 MI_buf[242]; + __u8 *data; + __u16 *MI_buf; int h_size, v_size; int intpipe; -/* struct usb_device *dev = pcam->dev; */ - - memset(data, 0, sizeof data); - memset(MI_buf, 0, sizeof MI_buf); PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface); - if (usb_set_interface(dev, gspca_dev->iface, 8) < 0) { + if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8) < 0) { PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error"); return; } + data = gspca_dev->usb_buf; data[0] = 0x01; /* address */ data[1] = 0x01; - err_code = pcam_reg_write(dev, data[0], data, 2); + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return; /* Initialize the MR97113 chip register */ + data = kmalloc(16, GFP_KERNEL); data[0] = 0x00; /* address */ data[1] = 0x0c | 0x01; /* reg 0 */ data[2] = 0x01; /* reg 1 */ @@ -181,34 +192,34 @@ static void sd_start(struct gspca_dev *gspca_dev) data[6] = 4; /* reg 5, H start */ data[7] = 0xc0; /* reg 6, gamma 1.5 */ data[8] = 3; /* reg 7, V start */ -/* if(h_size == 320 ) */ +/* if (h_size == 320 ) */ /* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */ /* else */ data[9] = 0x52; /* reg 8, 24MHz, no scale down */ data[10] = 0x5d; /* reg 9, I2C device address * [for PAS5101 (0x40)] [for MI (0x5d)] */ - err_code = pcam_reg_write(dev, data[0], data, 11); + err_code = reg_w_buf(gspca_dev, data[0], data, 11); + kfree(data); if (err_code < 0) return; + data = gspca_dev->usb_buf; data[0] = 0x23; /* address */ data[1] = 0x09; /* reg 35, append frame header */ - err_code = pcam_reg_write(dev, data[0], data, 2); - if (err_code < 0) { - PDEBUG(D_ERR, "Register write failed"); + err_code = reg_w(gspca_dev, data[0], 2); + if (err_code < 0) return; - } - data[0] = 0x3C; /* address */ -/* if (pcam->width == 1280) */ + data[0] = 0x3c; /* address */ +/* if (gspca_dev->width == 1280) */ /* data[1] = 200; * reg 60, pc-cam frame size * (unit: 4KB) 800KB */ /* else */ data[1] = 50; /* 50 reg 60, pc-cam frame size * (unit: 4KB) 200KB */ - err_code = pcam_reg_write(dev, data[0], data, 2); + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return; @@ -250,19 +261,20 @@ static void sd_start(struct gspca_dev *gspca_dev) /* auto dark-gain */ data[0] = 0x5e; /* address */ - err_code = pcam_reg_write(dev, data[0], data, 6); + err_code = reg_w(gspca_dev, data[0], 6); if (err_code < 0) return; data[0] = 0x67; data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */ - err_code = pcam_reg_write(dev, data[0], data, 2); + err_code = reg_w(gspca_dev, data[0], 2); if (err_code < 0) return; /* * initialize the value of MI sensor... */ + MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL); MI_buf[REG_HW_MI_1] = 0x000a; MI_buf[REG_HW_MI_2] = 0x000c; MI_buf[REG_HW_MI_3] = 0x0405; @@ -304,48 +316,48 @@ static void sd_start(struct gspca_dev *gspca_dev) } MI_buf[0x20] = 0x1104; - MISensor_BulkWrite(dev, MI_buf + 1, 1); - MISensor_BulkWrite(dev, MI_buf + 2, 2); - MISensor_BulkWrite(dev, MI_buf + 3, 3); - MISensor_BulkWrite(dev, MI_buf + 4, 4); - MISensor_BulkWrite(dev, MI_buf + 5, 5); - MISensor_BulkWrite(dev, MI_buf + 6, 6); - MISensor_BulkWrite(dev, MI_buf + 7, 7); - MISensor_BulkWrite(dev, MI_buf + 9, 9); - MISensor_BulkWrite(dev, MI_buf + 0x0b, 0x0b); - MISensor_BulkWrite(dev, MI_buf + 0x0c, 0x0c); - MISensor_BulkWrite(dev, MI_buf + 0x0d, 0x0d); - MISensor_BulkWrite(dev, MI_buf + 0x1e, 0x1e); - MISensor_BulkWrite(dev, MI_buf + 0x20, 0x20); - MISensor_BulkWrite(dev, MI_buf + 0x2b, 0x2b); - MISensor_BulkWrite(dev, MI_buf + 0x2c, 0x2c); - MISensor_BulkWrite(dev, MI_buf + 0x2d, 0x2d); - MISensor_BulkWrite(dev, MI_buf + 0x2e, 0x2e); - MISensor_BulkWrite(dev, MI_buf + 0x35, 0x35); - MISensor_BulkWrite(dev, MI_buf + 0x5f, 0x5f); - MISensor_BulkWrite(dev, MI_buf + 0x60, 0x60); - MISensor_BulkWrite(dev, MI_buf + 0x61, 0x61); - MISensor_BulkWrite(dev, MI_buf + 0x62, 0x62); - MISensor_BulkWrite(dev, MI_buf + 0x63, 0x63); - MISensor_BulkWrite(dev, MI_buf + 0x64, 0x64); - MISensor_BulkWrite(dev, MI_buf + 0xf1, 0xf1); - - intpipe = usb_sndintpipe(dev, 0); - err_code = usb_clear_halt(dev, intpipe); + bulk_w(gspca_dev, MI_buf + 1, 1); + bulk_w(gspca_dev, MI_buf + 2, 2); + bulk_w(gspca_dev, MI_buf + 3, 3); + bulk_w(gspca_dev, MI_buf + 4, 4); + bulk_w(gspca_dev, MI_buf + 5, 5); + bulk_w(gspca_dev, MI_buf + 6, 6); + bulk_w(gspca_dev, MI_buf + 7, 7); + bulk_w(gspca_dev, MI_buf + 9, 9); + bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b); + bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c); + bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d); + bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e); + bulk_w(gspca_dev, MI_buf + 0x20, 0x20); + bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b); + bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c); + bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d); + bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e); + bulk_w(gspca_dev, MI_buf + 0x35, 0x35); + bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f); + bulk_w(gspca_dev, MI_buf + 0x60, 0x60); + bulk_w(gspca_dev, MI_buf + 0x61, 0x61); + bulk_w(gspca_dev, MI_buf + 0x62, 0x62); + bulk_w(gspca_dev, MI_buf + 0x63, 0x63); + bulk_w(gspca_dev, MI_buf + 0x64, 0x64); + bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1); + kfree(MI_buf); + + intpipe = usb_sndintpipe(gspca_dev->dev, 0); + err_code = usb_clear_halt(gspca_dev->dev, intpipe); data[0] = 0x00; data[1] = 0x4d; /* ISOC transfering enable... */ - pcam_reg_write(dev, data[0], data, 2); + reg_w(gspca_dev, data[0], 2); } static void sd_stopN(struct gspca_dev *gspca_dev) { int result; - __u8 data[2]; - data[0] = 1; - data[1] = 0; - result = pcam_reg_write(gspca_dev->dev, data[0], data, 2); + gspca_dev->usb_buf[0] = 1; + gspca_dev->usb_buf[1] = 0; + result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2); if (result < 0) PDEBUG(D_ERR, "Camera Stop failed"); } diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index ba245bafcd6f..08d99c3b78e2 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("OV519 USB Camera Driver"); @@ -282,15 +282,14 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) static int reg_w(struct sd *sd, __u16 index, __u8 value) { int ret; - __u8 data; - data = value; + sd->gspca_dev.usb_buf[0] = value; ret = usb_control_msg(sd->gspca_dev.dev, usb_sndctrlpipe(sd->gspca_dev.dev, 0), 1, /* REQ_IO (ov518/519) */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, - &data, 1, 500); + sd->gspca_dev.usb_buf, 1, 500); if (ret < 0) PDEBUG(D_ERR, "Write reg [%02x] %02x failed", index, value); return ret; @@ -301,16 +300,15 @@ static int reg_w(struct sd *sd, __u16 index, __u8 value) static int reg_r(struct sd *sd, __u16 index) { int ret; - __u8 data; ret = usb_control_msg(sd->gspca_dev.dev, usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1, /* REQ_IO */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, &data, 1, 500); + 0, index, sd->gspca_dev.usb_buf, 1, 500); if (ret >= 0) - ret = data; + ret = sd->gspca_dev.usb_buf[0]; else PDEBUG(D_ERR, "Read reg [0x%02x] failed", index); return ret; @@ -321,16 +319,15 @@ static int reg_r8(struct sd *sd, __u16 index) { int ret; - __u8 buf[8]; ret = usb_control_msg(sd->gspca_dev.dev, usb_rcvctrlpipe(sd->gspca_dev.dev, 0), 1, /* REQ_IO */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, index, &buf[0], 8, 500); + 0, index, sd->gspca_dev.usb_buf, 8, 500); if (ret >= 0) - ret = buf[0]; + ret = sd->gspca_dev.usb_buf[0]; else PDEBUG(D_ERR, "Read reg 8 [0x%02x] failed", index); return ret; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index 5d68d3f42262..fa7abc411090 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,8 +27,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); @@ -187,18 +187,18 @@ static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 }; static const unsigned char pac207_sof_marker[5] = { 0xff, 0xff, 0x00, 0xff, 0x96 }; -int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, +static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, const u8 *buffer, u16 length) { struct usb_device *udev = gspca_dev->dev; int err; - u8 kbuf[8]; - memcpy(kbuf, buffer, length); + memcpy(gspca_dev->usb_buf, buffer, length); err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x01, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x00, index, kbuf, length, PAC207_CTRL_TIMEOUT); + 0x00, index, + gspca_dev->usb_buf, length, PAC207_CTRL_TIMEOUT); if (err < 0) PDEBUG(D_ERR, "Failed to write registers to index 0x%04X, error %d)", @@ -227,12 +227,12 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) { struct usb_device *udev = gspca_dev->dev; - u8 buff; int res; res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x00, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, - 0x00, index, &buff, 1, PAC207_CTRL_TIMEOUT); + 0x00, index, + gspca_dev->usb_buf, 1, PAC207_CTRL_TIMEOUT); if (res < 0) { PDEBUG(D_ERR, "Failed to read a register (index 0x%04X, error %d)", @@ -240,10 +240,9 @@ int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) return res; } - return buff; + return gspca_dev->usb_buf[0]; } - /* this function is called at probe time */ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 1a2347aa7157..5c052e31be4a 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); @@ -206,46 +206,43 @@ static const __u8 pac7311_jpeg_header[] = { 0x11, 0x00, 0x3f, 0x00 }; -static void reg_w(struct usb_device *dev, +static void reg_w_buf(struct gspca_dev *gspca_dev, __u16 index, const char *buffer, __u16 len) { - __u8 tmpbuf[8]; - - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 1, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, tmpbuf, len, + index, gspca_dev->usb_buf, len, 500); } -static void pac7311_reg_read(struct usb_device *dev, __u16 index, - __u8 *buffer) +static __u8 reg_r(struct gspca_dev *gspca_dev, + __u16 index) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, 1, + index, gspca_dev->usb_buf, 1, 500); + return gspca_dev->usb_buf[0]; } -static void pac7311_reg_write(struct usb_device *dev, - __u16 index, - __u8 value) +static void reg_w(struct gspca_dev *gspca_dev, + __u16 index, + __u8 value) { - __u8 buf; - - buf = value; - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + gspca_dev->usb_buf[0] = value; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, index, &buf, 1, + value, index, gspca_dev->usb_buf, 1, 500); } @@ -254,20 +251,19 @@ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; struct cam *cam; PDEBUG(D_CONF, "Find Sensor PAC7311"); - pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x27, 0x80); - pac7311_reg_write(dev, 0x28, 0xca); - pac7311_reg_write(dev, 0x29, 0x53); - pac7311_reg_write(dev, 0x2a, 0x0e); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x3e, 0x20); + reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x40); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x27, 0x80); + reg_w(gspca_dev, 0x28, 0xca); + reg_w(gspca_dev, 0x29, 0x53); + reg_w(gspca_dev, 0x2a, 0x0e); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x3e, 0x20); cam = &gspca_dev->cam; cam->dev_name = (char *) id->driver_info; @@ -289,11 +285,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) /*jfm: inverted?*/ brightness = BRIGHTNESS_MAX - sd->brightness; - pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); -/* pac7311_reg_write(gspca_dev->dev, 0x0e, 0x00); */ - pac7311_reg_write(gspca_dev->dev, 0x0f, brightness); + reg_w(gspca_dev, 0xff, 0x04); +/* reg_w(gspca_dev, 0x0e, 0x00); */ + reg_w(gspca_dev, 0x0f, brightness); /* load registers to sensor (Bit 0, auto clear) */ - pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + reg_w(gspca_dev, 0x11, 0x01); PDEBUG(D_CONF|D_STREAM, "brightness: %i", brightness); } @@ -301,10 +297,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); - pac7311_reg_write(gspca_dev->dev, 0x80, sd->contrast); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x80, sd->contrast); /* load registers to sensor (Bit 0, auto clear) */ - pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + reg_w(gspca_dev, 0x11, 0x01); PDEBUG(D_CONF|D_STREAM, "contrast: %i", sd->contrast); } @@ -312,94 +308,93 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - pac7311_reg_write(gspca_dev->dev, 0xff, 0x01); - pac7311_reg_write(gspca_dev->dev, 0x10, sd->colors); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x10, sd->colors); /* load registers to sensor (Bit 0, auto clear) */ - pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + reg_w(gspca_dev, 0x11, 0x01); PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors); } /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - pac7311_reg_write(gspca_dev->dev, 0x78, 0x00); /* Turn on LED */ + reg_w(gspca_dev, 0x78, 0x00); /* Turn on LED */ return 0; } static void sd_start(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; struct sd *sd = (struct sd *) gspca_dev; - pac7311_reg_write(dev, 0xff, 0x01); - reg_w(dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); - reg_w(dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); - reg_w(dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); - reg_w(dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); - reg_w(dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); - reg_w(dev, 0x002a, "\x00\x00\x00", 3); - reg_w(dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); - reg_w(dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); - reg_w(dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); - reg_w(dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); - reg_w(dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); - reg_w(dev, 0x0066, "\xd0\xff", 2); - reg_w(dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); - reg_w(dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); - reg_w(dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); - reg_w(dev, 0x008f, "\x18\x20", 2); - reg_w(dev, 0x0096, "\x01\x08\x04", 3); - reg_w(dev, 0x00a0, "\x44\x44\x44\x04", 4); - reg_w(dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); - reg_w(dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); - - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x02, 0x04); - pac7311_reg_write(dev, 0x03, 0x54); - pac7311_reg_write(dev, 0x04, 0x07); - pac7311_reg_write(dev, 0x05, 0x2b); - pac7311_reg_write(dev, 0x06, 0x09); - pac7311_reg_write(dev, 0x07, 0x0f); - pac7311_reg_write(dev, 0x08, 0x09); - pac7311_reg_write(dev, 0x09, 0x00); - pac7311_reg_write(dev, 0x0c, 0x07); - pac7311_reg_write(dev, 0x0d, 0x00); - pac7311_reg_write(dev, 0x0e, 0x00); - pac7311_reg_write(dev, 0x0f, 0x62); - pac7311_reg_write(dev, 0x10, 0x08); - pac7311_reg_write(dev, 0x12, 0x07); - pac7311_reg_write(dev, 0x13, 0x00); - pac7311_reg_write(dev, 0x14, 0x00); - pac7311_reg_write(dev, 0x15, 0x00); - pac7311_reg_write(dev, 0x16, 0x00); - pac7311_reg_write(dev, 0x17, 0x00); - pac7311_reg_write(dev, 0x18, 0x00); - pac7311_reg_write(dev, 0x19, 0x00); - pac7311_reg_write(dev, 0x1a, 0x00); - pac7311_reg_write(dev, 0x1b, 0x03); - pac7311_reg_write(dev, 0x1c, 0xa0); - pac7311_reg_write(dev, 0x1d, 0x01); - pac7311_reg_write(dev, 0x1e, 0xf4); - pac7311_reg_write(dev, 0x21, 0x00); - pac7311_reg_write(dev, 0x22, 0x08); - pac7311_reg_write(dev, 0x24, 0x03); - pac7311_reg_write(dev, 0x26, 0x00); - pac7311_reg_write(dev, 0x27, 0x01); - pac7311_reg_write(dev, 0x28, 0xca); - pac7311_reg_write(dev, 0x29, 0x10); - pac7311_reg_write(dev, 0x2a, 0x06); - pac7311_reg_write(dev, 0x2b, 0x78); - pac7311_reg_write(dev, 0x2c, 0x00); - pac7311_reg_write(dev, 0x2d, 0x00); - pac7311_reg_write(dev, 0x2e, 0x00); - pac7311_reg_write(dev, 0x2f, 0x00); - pac7311_reg_write(dev, 0x30, 0x23); - pac7311_reg_write(dev, 0x31, 0x28); - pac7311_reg_write(dev, 0x32, 0x04); - pac7311_reg_write(dev, 0x33, 0x11); - pac7311_reg_write(dev, 0x34, 0x00); - pac7311_reg_write(dev, 0x35, 0x00); - pac7311_reg_write(dev, 0x11, 0x01); + reg_w(gspca_dev, 0xff, 0x01); + reg_w_buf(gspca_dev, 0x0002, "\x48\x0a\x40\x08\x00\x00\x08\x00", 8); + reg_w_buf(gspca_dev, 0x000a, "\x06\xff\x11\xff\x5a\x30\x90\x4c", 8); + reg_w_buf(gspca_dev, 0x0012, "\x00\x07\x00\x0a\x10\x00\xa0\x10", 8); + reg_w_buf(gspca_dev, 0x001a, "\x02\x00\x00\x00\x00\x0b\x01\x00", 8); + reg_w_buf(gspca_dev, 0x0022, "\x00\x00\x00\x00\x00\x00\x00\x00", 8); + reg_w_buf(gspca_dev, 0x002a, "\x00\x00\x00", 3); + reg_w_buf(gspca_dev, 0x003e, "\x00\x00\x78\x52\x4a\x52\x78\x6e", 8); + reg_w_buf(gspca_dev, 0x0046, "\x48\x46\x48\x6e\x5f\x49\x42\x49", 8); + reg_w_buf(gspca_dev, 0x004e, "\x5f\x5f\x49\x42\x49\x5f\x6e\x48", 8); + reg_w_buf(gspca_dev, 0x0056, "\x46\x48\x6e\x78\x52\x4a\x52\x78", 8); + reg_w_buf(gspca_dev, 0x005e, "\x00\x00\x09\x1b\x34\x49\x5c\x9b", 8); + reg_w_buf(gspca_dev, 0x0066, "\xd0\xff", 2); + reg_w_buf(gspca_dev, 0x0078, "\x44\x00\xf2\x01\x01\x80", 6); + reg_w_buf(gspca_dev, 0x007f, "\x2a\x1c\x00\xc8\x02\x58\x03\x84", 8); + reg_w_buf(gspca_dev, 0x0087, "\x12\x00\x1a\x04\x08\x0c\x10\x14", 8); + reg_w_buf(gspca_dev, 0x008f, "\x18\x20", 2); + reg_w_buf(gspca_dev, 0x0096, "\x01\x08\x04", 3); + reg_w_buf(gspca_dev, 0x00a0, "\x44\x44\x44\x04", 4); + reg_w_buf(gspca_dev, 0x00f0, "\x01\x00\x00\x00\x22\x00\x20\x00", 8); + reg_w_buf(gspca_dev, 0x00f8, "\x3f\x00\x0a\x01\x00", 5); + + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x02, 0x04); + reg_w(gspca_dev, 0x03, 0x54); + reg_w(gspca_dev, 0x04, 0x07); + reg_w(gspca_dev, 0x05, 0x2b); + reg_w(gspca_dev, 0x06, 0x09); + reg_w(gspca_dev, 0x07, 0x0f); + reg_w(gspca_dev, 0x08, 0x09); + reg_w(gspca_dev, 0x09, 0x00); + reg_w(gspca_dev, 0x0c, 0x07); + reg_w(gspca_dev, 0x0d, 0x00); + reg_w(gspca_dev, 0x0e, 0x00); + reg_w(gspca_dev, 0x0f, 0x62); + reg_w(gspca_dev, 0x10, 0x08); + reg_w(gspca_dev, 0x12, 0x07); + reg_w(gspca_dev, 0x13, 0x00); + reg_w(gspca_dev, 0x14, 0x00); + reg_w(gspca_dev, 0x15, 0x00); + reg_w(gspca_dev, 0x16, 0x00); + reg_w(gspca_dev, 0x17, 0x00); + reg_w(gspca_dev, 0x18, 0x00); + reg_w(gspca_dev, 0x19, 0x00); + reg_w(gspca_dev, 0x1a, 0x00); + reg_w(gspca_dev, 0x1b, 0x03); + reg_w(gspca_dev, 0x1c, 0xa0); + reg_w(gspca_dev, 0x1d, 0x01); + reg_w(gspca_dev, 0x1e, 0xf4); + reg_w(gspca_dev, 0x21, 0x00); + reg_w(gspca_dev, 0x22, 0x08); + reg_w(gspca_dev, 0x24, 0x03); + reg_w(gspca_dev, 0x26, 0x00); + reg_w(gspca_dev, 0x27, 0x01); + reg_w(gspca_dev, 0x28, 0xca); + reg_w(gspca_dev, 0x29, 0x10); + reg_w(gspca_dev, 0x2a, 0x06); + reg_w(gspca_dev, 0x2b, 0x78); + reg_w(gspca_dev, 0x2c, 0x00); + reg_w(gspca_dev, 0x2d, 0x00); + reg_w(gspca_dev, 0x2e, 0x00); + reg_w(gspca_dev, 0x2f, 0x00); + reg_w(gspca_dev, 0x30, 0x23); + reg_w(gspca_dev, 0x31, 0x28); + reg_w(gspca_dev, 0x32, 0x04); + reg_w(gspca_dev, 0x33, 0x11); + reg_w(gspca_dev, 0x34, 0x00); + reg_w(gspca_dev, 0x35, 0x00); + reg_w(gspca_dev, 0x11, 0x01); setcontrast(gspca_dev); setbrightness(gspca_dev); setcolors(gspca_dev); @@ -407,39 +402,39 @@ static void sd_start(struct gspca_dev *gspca_dev) /* set correct resolution */ switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { case 2: /* 160x120 */ - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x02, 0x03); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x08, 0x09); - pac7311_reg_write(dev, 0x17, 0x20); - pac7311_reg_write(dev, 0x1b, 0x00); -/* pac7311_reg_write(dev, 0x80, 0x69); */ - pac7311_reg_write(dev, 0x87, 0x10); + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x02, 0x03); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x08, 0x09); + reg_w(gspca_dev, 0x17, 0x20); + reg_w(gspca_dev, 0x1b, 0x00); +/* reg_w(gspca_dev, 0x80, 0x69); */ + reg_w(gspca_dev, 0x87, 0x10); break; case 1: /* 320x240 */ - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x02, 0x03); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x08, 0x09); - pac7311_reg_write(dev, 0x17, 0x30); -/* pac7311_reg_write(dev, 0x80, 0x3f); */ - pac7311_reg_write(dev, 0x87, 0x11); + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x02, 0x03); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x08, 0x09); + reg_w(gspca_dev, 0x17, 0x30); +/* reg_w(gspca_dev, 0x80, 0x3f); */ + reg_w(gspca_dev, 0x87, 0x11); break; case 0: /* 640x480 */ - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x02, 0x03); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x08, 0x08); - pac7311_reg_write(dev, 0x17, 0x00); -/* pac7311_reg_write(dev, 0x80, 0x1c); */ - pac7311_reg_write(dev, 0x87, 0x12); + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x02, 0x03); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x08, 0x08); + reg_w(gspca_dev, 0x17, 0x00); +/* reg_w(gspca_dev, 0x80, 0x1c); */ + reg_w(gspca_dev, 0x87, 0x12); break; } /* start stream */ - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x78, 0x04); - pac7311_reg_write(dev, 0x78, 0x05); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x78, 0x04); + reg_w(gspca_dev, 0x78, 0x05); if (sd->autogain) { sd->ag_cnt = AG_CNT_START; @@ -451,18 +446,16 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x27, 0x80); - pac7311_reg_write(dev, 0x28, 0xca); - pac7311_reg_write(dev, 0x29, 0x53); - pac7311_reg_write(dev, 0x2a, 0x0e); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x3e, 0x20); - pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x27, 0x80); + reg_w(gspca_dev, 0x28, 0xca); + reg_w(gspca_dev, 0x29, 0x53); + reg_w(gspca_dev, 0x2a, 0x0e); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x3e, 0x20); + reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -472,18 +465,16 @@ static void sd_stop0(struct gspca_dev *gspca_dev) /* this function is called at close time */ static void sd_close(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - - pac7311_reg_write(dev, 0xff, 0x04); - pac7311_reg_write(dev, 0x27, 0x80); - pac7311_reg_write(dev, 0x28, 0xca); - pac7311_reg_write(dev, 0x29, 0x53); - pac7311_reg_write(dev, 0x2a, 0x0e); - pac7311_reg_write(dev, 0xff, 0x01); - pac7311_reg_write(dev, 0x3e, 0x20); - pac7311_reg_write(dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ - pac7311_reg_write(dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x27, 0x80); + reg_w(gspca_dev, 0x28, 0xca); + reg_w(gspca_dev, 0x29, 0x53); + reg_w(gspca_dev, 0x2a, 0x0e); + reg_w(gspca_dev, 0xff, 0x01); + reg_w(gspca_dev, 0x3e, 0x20); + reg_w(gspca_dev, 0x78, 0x04); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ + reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_7=LED */ } static void setautogain(struct gspca_dev *gspca_dev, int luma) @@ -491,11 +482,9 @@ static void setautogain(struct gspca_dev *gspca_dev, int luma) int luma_mean = 128; int luma_delta = 20; __u8 spring = 5; - __u8 Pxclk; int Gbright; - pac7311_reg_read(gspca_dev->dev, 0x02, &Pxclk); - Gbright = Pxclk; + Gbright = reg_r(gspca_dev, 0x02); PDEBUG(D_FRAM, "luma mean %d", luma); if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) { @@ -505,10 +494,10 @@ static void setautogain(struct gspca_dev *gspca_dev, int luma) else if (Gbright < 4) Gbright = 4; PDEBUG(D_FRAM, "gbright %d", Gbright); - pac7311_reg_write(gspca_dev->dev, 0xff, 0x04); - pac7311_reg_write(gspca_dev->dev, 0x0f, Gbright); + reg_w(gspca_dev, 0xff, 0x04); + reg_w(gspca_dev, 0x0f, Gbright); /* load registers to sensor (Bit 0, auto clear) */ - pac7311_reg_write(gspca_dev->dev, 0x11, 0x01); + reg_w(gspca_dev, 0x11, 0x01); } } @@ -623,11 +612,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, static void getbrightness(struct gspca_dev *gspca_dev) { -/* __u8 brightness = 0; - - pac7311_reg_read(gspca_dev->dev, 0x0008, &brightness); - spca50x->brightness = brightness; - return spca50x->brightness; */ +/* sd->brightness = reg_r(gspca_dev, 0x08); + return sd->brightness; */ /* PDEBUG(D_CONF, "Called pac7311_getbrightness: Not implemented yet"); */ } diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5d2313198807..ce8b28f504d3 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -384,64 +384,82 @@ static const __u8 tas5130_sensor_init[][8] = { {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, }; -static void reg_r(struct usb_device *dev, - __u16 value, __u8 *buffer) +/* get one byte in gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 value) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, /* index */ - buffer, 1, + gspca_dev->usb_buf, 1, 500); } -static void reg_w(struct usb_device *dev, - __u16 value, - const __u8 *buffer, - int len) +static void reg_w(struct gspca_dev *gspca_dev, + __u16 value, + const __u8 *buffer, + int len) { - __u8 tmpbuf[48]; - #ifdef CONFIG_VIDEO_ADV_DEBUG - if (len > sizeof tmpbuf) { + if (len > sizeof gspca_dev->usb_buf) { PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow"); return; } #endif + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0x08, /* request */ + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, + 0, /* index */ + gspca_dev->usb_buf, len, + 500); +} + +static void reg_w_big(struct gspca_dev *gspca_dev, + __u16 value, + const __u8 *buffer, + int len) +{ + __u8 *tmpbuf; + + tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, /* index */ tmpbuf, len, 500); + kfree(tmpbuf); } -static int i2c_w(struct usb_device *dev, const __u8 *buffer) +static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) { int retry = 60; - __u8 ByteReceive; /* is i2c ready */ - reg_w(dev, 0x08, buffer, 8); + reg_w(gspca_dev, 0x08, buffer, 8); while (retry--) { msleep(10); - reg_r(dev, 0x08, &ByteReceive); - if (ByteReceive == 4) + reg_r(gspca_dev, 0x08); + if (gspca_dev->usb_buf[0] == 4) return 0; } return -1; } -static void i2c_w_vector(struct usb_device *dev, +static void i2c_w_vector(struct gspca_dev *gspca_dev, const __u8 buffer[][8], int len) { for (;;) { - reg_w(dev, 0x08, *buffer, 8); + reg_w(gspca_dev, 0x08, *buffer, 8); len -= 8; if (len <= 0) break; @@ -460,7 +478,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; i2cOV6650[3] = sd->brightness; - if (i2c_w(gspca_dev->dev, i2cOV6650) < 0) + if (i2c_w(gspca_dev, i2cOV6650) < 0) goto err; break; } @@ -470,7 +488,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) /* change reg 0x06 */ i2cOV[3] = sd->brightness; - if (i2c_w(gspca_dev->dev, i2cOV) < 0) + if (i2c_w(gspca_dev, i2cOV) < 0) goto err; break; } @@ -480,11 +498,11 @@ static void setbrightness(struct gspca_dev *gspca_dev) i2c1[3] = sd->brightness >> 3; i2c1[2] = 0x0e; - if (i2c_w(gspca_dev->dev, i2c1) < 0) + if (i2c_w(gspca_dev, i2c1) < 0) goto err; i2c1[3] = 0x01; i2c1[2] = 0x13; - if (i2c_w(gspca_dev->dev, i2c1) < 0) + if (i2c_w(gspca_dev, i2c1) < 0) goto err; break; } @@ -500,18 +518,18 @@ static void setbrightness(struct gspca_dev *gspca_dev) /* change reg 0x10 */ i2cpexpo[4] = 0xff - sd->brightness; -/* if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0) +/* if(i2c_w(gspca_dev,i2cpexpo1) < 0) goto err; */ -/* if(i2c_w(gspca_dev->dev,i2cpdoit) < 0) +/* if(i2c_w(gspca_dev,i2cpdoit) < 0) goto err; */ - if (i2c_w(gspca_dev->dev, i2cpexpo) < 0) + if (i2c_w(gspca_dev, i2cpexpo) < 0) goto err; - if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) + if (i2c_w(gspca_dev, i2cpdoit) < 0) goto err; i2cp202[3] = sd->brightness >> 3; - if (i2c_w(gspca_dev->dev, i2cp202) < 0) + if (i2c_w(gspca_dev, i2cp202) < 0) goto err; - if (i2c_w(gspca_dev->dev, i2cpdoit) < 0) + if (i2c_w(gspca_dev, i2cpdoit) < 0) goto err; break; } @@ -522,7 +540,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) value = 0xff - sd->brightness; i2c[4] = value; PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]); - if (i2c_w(gspca_dev->dev, i2c) < 0) + if (i2c_w(gspca_dev, i2c) < 0) goto err; break; } @@ -551,14 +569,14 @@ static void setsensorgain(struct gspca_dev *gspca_dev) {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; i2c[4] = 255 - gain; - if (i2c_w(gspca_dev->dev, i2c) < 0) + if (i2c_w(gspca_dev, i2c) < 0) goto err; break; } case SENSOR_OV6650: { __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[3] = gain; - if (i2c_w(gspca_dev->dev, i2c) < 0) + if (i2c_w(gspca_dev, i2c) < 0) goto err; break; } @@ -578,10 +596,10 @@ static void setgain(struct gspca_dev *gspca_dev) /* red and blue gain */ rgb_value = gain << 4 | gain; - reg_w(gspca_dev->dev, 0x10, &rgb_value, 1); + reg_w(gspca_dev, 0x10, &rgb_value, 1); /* green gain */ rgb_value = gain; - reg_w(gspca_dev->dev, 0x11, &rgb_value, 1); + reg_w(gspca_dev, 0x11, &rgb_value, 1); if (sd->sensor_has_gain) setsensorgain(gspca_dev); @@ -604,7 +622,7 @@ static void setexposure(struct gspca_dev *gspca_dev) if (reg > 15) reg = 15; reg = (reg << 4) | 0x0b; - reg_w(gspca_dev->dev, 0x19, ®, 1); + reg_w(gspca_dev, 0x19, ®, 1); break; } case SENSOR_OV6650: { @@ -613,7 +631,7 @@ static void setexposure(struct gspca_dev *gspca_dev) if (i2c[3] > 15) i2c[3] = 15; i2c[3] |= 0xc0; - if (i2c_w(gspca_dev->dev, i2c) < 0) + if (i2c_w(gspca_dev, i2c) < 0) PDEBUG(D_ERR, "i2c error exposure"); break; } @@ -721,22 +739,20 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ - reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630); + reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); return 0; } /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - __u8 ByteReceive; - - reg_r(gspca_dev->dev, 0x00, &ByteReceive); - if (ByteReceive != 0x10) + reg_r(gspca_dev, 0x00); + if (gspca_dev->usb_buf[0] != 0x10) return -ENODEV; return 0; } -static void pas106_i2cinit(struct usb_device *dev) +static void pas106_i2cinit(struct gspca_dev *gspca_dev) { int i; const __u8 *data; @@ -747,7 +763,7 @@ static void pas106_i2cinit(struct usb_device *dev) while (--i >= 0) { memcpy(&i2c1[2], data, 2); /* copy 2 bytes from the template */ - if (i2c_w(dev, i2c1) < 0) + if (i2c_w(gspca_dev, i2c1) < 0) PDEBUG(D_ERR, "i2c error pas106"); data += 2; } @@ -757,7 +773,6 @@ static void pas106_i2cinit(struct usb_device *dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int mode, l; const __u8 *sn9c10x; __u8 reg01, reg17; @@ -835,75 +850,75 @@ static void sd_start(struct gspca_dev *gspca_dev) } /* reg 0x01 bit 2 video transfert on */ - reg_w(dev, 0x01, ®01, 1); + reg_w(gspca_dev, 0x01, ®01, 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ - reg_w(dev, 0x17, ®17, 1); + reg_w(gspca_dev, 0x17, ®17, 1); /*fixme: for ov7630 102 - reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */ + reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */ /* Set the registers from the template */ - reg_w(dev, 0x01, sn9c10x, l); + reg_w_big(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { case SENSOR_HV7131R: - i2c_w_vector(dev, hv7131_sensor_init, + i2c_w_vector(gspca_dev, hv7131_sensor_init, sizeof hv7131_sensor_init); break; case SENSOR_OV6650: - i2c_w_vector(dev, ov6650_sensor_init, + i2c_w_vector(gspca_dev, ov6650_sensor_init, sizeof ov6650_sensor_init); break; case SENSOR_OV7630: - i2c_w_vector(dev, ov7630_sensor_init_com, + i2c_w_vector(gspca_dev, ov7630_sensor_init_com, sizeof ov7630_sensor_init_com); msleep(200); - i2c_w_vector(dev, ov7630_sensor_init, + i2c_w_vector(gspca_dev, ov7630_sensor_init, sizeof ov7630_sensor_init); break; case SENSOR_OV7630_3: - i2c_w_vector(dev, ov7630_sensor_init_com, + i2c_w_vector(gspca_dev, ov7630_sensor_init_com, sizeof ov7630_sensor_init_com); msleep(200); - i2c_w_vector(dev, ov7630_sensor_init_3, + i2c_w_vector(gspca_dev, ov7630_sensor_init_3, sizeof ov7630_sensor_init_3); break; case SENSOR_PAS106: - pas106_i2cinit(dev); + pas106_i2cinit(gspca_dev); break; case SENSOR_PAS202: - i2c_w_vector(dev, pas202_sensor_init, + i2c_w_vector(gspca_dev, pas202_sensor_init, sizeof pas202_sensor_init); break; case SENSOR_TAS5110: - i2c_w_vector(dev, tas5110_sensor_init, + i2c_w_vector(gspca_dev, tas5110_sensor_init, sizeof tas5110_sensor_init); break; default: /* case SENSOR_TAS5130CXX: */ - i2c_w_vector(dev, tas5130_sensor_init, + i2c_w_vector(gspca_dev, tas5130_sensor_init, sizeof tas5130_sensor_init); break; } /* H_size V_size 0x28, 0x1e maybe 640x480 */ - reg_w(dev, 0x15, reg15, 2); + reg_w(gspca_dev, 0x15, reg15, 2); /* compression register */ - reg_w(dev, 0x18, ®17_19[1], 1); + reg_w(gspca_dev, 0x18, ®17_19[1], 1); if (sd->sensor != SENSOR_OV7630_3) { /* H_start */ - reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1); + reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); /* V_START */ - reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1); + reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); } /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ - reg_w(dev, 0x17, ®17_19[0], 1); + reg_w(gspca_dev, 0x17, ®17_19[0], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ if (sd->sensor != SENSOR_OV7630_3) - reg_w(dev, 0x19, ®17_19[2], 1); + reg_w(gspca_dev, 0x19, ®17_19[2], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ - reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4); + reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); /* Enable video transfert */ - reg_w(dev, 0x01, &sn9c10x[0], 1); + reg_w(gspca_dev, 0x01, &sn9c10x[0], 1); /* Compression */ - reg_w(dev, 0x18, ®17_19[1], 2); + reg_w(gspca_dev, 0x18, ®17_19[1], 2); msleep(20); setgain(gspca_dev); @@ -919,7 +934,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) __u8 ByteSend; ByteSend = 0x09; /* 0X00 */ - reg_w(gspca_dev->dev, 0x01, &ByteSend, 1); + reg_w(gspca_dev, 0x01, &ByteSend, 1); } static void sd_stop0(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4cb1421b8807..30e840dca481 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); @@ -512,42 +512,40 @@ static const __u8 qtable4[] = { 0x29, 0x29, 0x29, 0x29 }; -static void reg_r(struct usb_device *dev, - __u16 value, - __u8 *buffer, int len) +/* read bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 value, int len) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, - buffer, len, + gspca_dev->usb_buf, len, 500); } -static void reg_w(struct usb_device *dev, +static void reg_w(struct gspca_dev *gspca_dev, __u16 value, const __u8 *buffer, int len) { - if (len < 16) { - __u8 tmpbuf[16]; - - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + if (len <= sizeof gspca_dev->usb_buf) { + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, - tmpbuf, len, + gspca_dev->usb_buf, len, 500); } else { __u8 *tmpbuf; tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0x08, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, 0, @@ -557,12 +555,11 @@ static void reg_w(struct usb_device *dev, } } -/* write 2 bytes */ +/* I2C write 2 bytes */ static void i2c_w2(struct gspca_dev *gspca_dev, const __u8 *buffer) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 mode[8]; /* is i2c ready */ @@ -574,22 +571,21 @@ static void i2c_w2(struct gspca_dev *gspca_dev, mode[5] = 0; mode[6] = 0; mode[7] = 0x10; - reg_w(dev, 0x08, mode, 8); + reg_w(gspca_dev, 0x08, mode, 8); } -/* write 8 bytes */ -static void i2c_w8(struct usb_device *dev, const __u8 *buffer) +/* I2C write 8 bytes */ +static void i2c_w8(struct gspca_dev *gspca_dev, + const __u8 *buffer) { - reg_w(dev, 0x08, buffer, 8); + reg_w(gspca_dev, 0x08, buffer, 8); msleep(1); } -/* read 5 bytes */ -static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, - __u8 *buffer) +/* read 5 bytes in gspca_dev->usb_buf */ +static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 mode[8]; mode[0] = sd->i2c_ctrl_reg | 0x10; @@ -600,40 +596,39 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg, mode[5] = 0; mode[6] = 0; mode[7] = 0x10; - i2c_w8(dev, mode); + i2c_w8(gspca_dev, mode); mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02; mode[2] = 0; - i2c_w8(dev, mode); - reg_r(dev, 0x0a, buffer, 5); + i2c_w8(gspca_dev, mode); + reg_r(gspca_dev, 0x0a, 5); } static int probesensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 reg02; static const __u8 datasend[] = { 2, 0 }; /* reg val1 val2 val3 val4 */ - __u8 datarecd[6]; i2c_w2(gspca_dev, datasend); /* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ msleep(10); reg02 = 0x66; - reg_w(dev, 0x02, ®02, 1); /* Gpio on */ + reg_w(gspca_dev, 0x02, ®02, 1); /* Gpio on */ msleep(10); - i2c_r5(gspca_dev, 0, datarecd); /* read sensor id */ - if (datarecd[0] == 0x02 - && datarecd[1] == 0x09 - && datarecd[2] == 0x01 - && datarecd[3] == 0x00 - && datarecd[4] == 0x00) { + i2c_r5(gspca_dev, 0); /* read sensor id */ + if (gspca_dev->usb_buf[0] == 0x02 + && gspca_dev->usb_buf[1] == 0x09 + && gspca_dev->usb_buf[2] == 0x01 + && gspca_dev->usb_buf[3] == 0x00 + && gspca_dev->usb_buf[4] == 0x00) { PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R"); sd->sensor = SENSOR_HV7131R; return SENSOR_HV7131R; } PDEBUG(D_PROBE, "Find Sensor %d %d %d", - datarecd[0], datarecd[1], datarecd[2]); + gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], + gspca_dev->usb_buf[2]); PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); return -ENODEV; } @@ -642,7 +637,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, const __u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 data; __u8 regF1; const __u8 *reg9a; @@ -655,14 +649,15 @@ static int configure_gpio(struct gspca_dev *gspca_dev, regF1 = 0x00; - reg_w(dev, 0xf1, ®F1, 1); + reg_w(gspca_dev, 0xf1, ®F1, 1); - reg_w(dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ + reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); + /*fixme:jfm was [1] en v1*/ /* configure gpio */ - reg_w(dev, 0x01, &sn9c1xx[1], 2); - reg_w(dev, 0x08, &sn9c1xx[8], 2); - reg_w(dev, 0x17, &sn9c1xx[0x17], 3); + reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); + reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); + reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 3); switch (sd->customid) { case SN9C325: reg9a = reg9a_sn9c325; @@ -674,37 +669,37 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg9a = reg9a_def; break; } - reg_w(dev, 0x9a, reg9a, 6); + reg_w(gspca_dev, 0x9a, reg9a, 6); data = 0x60; /*fixme:jfm 60 00 00 (3) */ - reg_w(dev, 0xd4, &data, 1); + reg_w(gspca_dev, 0xd4, &data, 1); - reg_w(dev, 0x03, &sn9c1xx[3], 0x0f); + reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); switch (sd->customid) { case SN9C120: /* from win trace */ data = 0x61; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); data = 0x20; - reg_w(dev, 0x17, &data, 1); + reg_w(gspca_dev, 0x17, &data, 1); data = 0x60; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); break; case SN9C325: data = 0x43; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); data = 0xae; - reg_w(dev, 0x17, &data, 1); + reg_w(gspca_dev, 0x17, &data, 1); data = 0x42; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); break; default: data = 0x43; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); data = 0x61; - reg_w(dev, 0x17, &data, 1); + reg_w(gspca_dev, 0x17, &data, 1); data = 0x42; - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &data, 1); } if (sd->sensor == SENSOR_HV7131R) { @@ -717,24 +712,22 @@ static int configure_gpio(struct gspca_dev *gspca_dev, static void hv7131R_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - struct usb_device *dev = gspca_dev->dev; static const __u8 SetSensorClk[] = /* 0x08 Mclk */ { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 }; while (hv7131r_sensor_init[i][0]) { - i2c_w8(dev, hv7131r_sensor_init[i]); + i2c_w8(gspca_dev, hv7131r_sensor_init[i]); i++; } - i2c_w8(dev, SetSensorClk); + i2c_w8(gspca_dev, SetSensorClk); } static void mi0360_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - struct usb_device *dev = gspca_dev->dev; while (mi0360_sensor_init[i][0]) { - i2c_w8(dev, mi0360_sensor_init[i]); + i2c_w8(gspca_dev, mi0360_sensor_init[i]); i++; } } @@ -742,21 +735,19 @@ static void mi0360_InitSensor(struct gspca_dev *gspca_dev) static void mo4000_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - struct usb_device *dev = gspca_dev->dev; while (mo4000_sensor_init[i][0]) { - i2c_w8(dev, mo4000_sensor_init[i]); + i2c_w8(gspca_dev, mo4000_sensor_init[i]); i++; } } static void ov7648_InitSensor(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; int i = 0; while (ov7648_sensor_init[i][0]) { - i2c_w8(dev, ov7648_sensor_init[i]); + i2c_w8(gspca_dev, ov7648_sensor_init[i]); i++; } } @@ -764,10 +755,9 @@ static void ov7648_InitSensor(struct gspca_dev *gspca_dev) static void ov7660_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; - struct usb_device *dev = gspca_dev->dev; while (ov7660_sensor_init[i][0]) { - i2c_w8(dev, ov7660_sensor_init[i]); + i2c_w8(gspca_dev, ov7660_sensor_init[i]); i++; } } @@ -1005,51 +995,52 @@ static int sd_config(struct gspca_dev *gspca_dev, static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; /* const __u8 *sn9c1xx; */ __u8 regF1; __u8 regGpio[] = { 0x29, 0x74 }; /* setup a selector by customid */ regF1 = 0x01; - reg_w(dev, 0xf1, ®F1, 1); - reg_r(dev, 0x00, ®F1, 1); /* -> regF1 = 0x00 */ - reg_w(dev, 0xf1, ®F1, 1); - reg_r(dev, 0x00, ®F1, 1); + reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ + regF1 = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_r(gspca_dev, 0x00, 1); + regF1 = gspca_dev->usb_buf[0]; switch (sd->customid) { case SN9C102P: if (regF1 != 0x11) return -ENODEV; - reg_w(dev, 0x02, ®Gpio[1], 1); + reg_w(gspca_dev, 0x02, ®Gpio[1], 1); break; case SN9C105: if (regF1 != 0x11) return -ENODEV; - reg_w(dev, 0x02, regGpio, 2); + reg_w(gspca_dev, 0x02, regGpio, 2); break; case SN9C110: if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x62; - reg_w(dev, 0x02, ®Gpio[1], 1); + reg_w(gspca_dev, 0x02, ®Gpio[1], 1); break; case SN9C120: if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x70; - reg_w(dev, 0x02, regGpio, 2); + reg_w(gspca_dev, 0x02, regGpio, 2); break; default: /* case SN9C325: */ if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x62; - reg_w(dev, 0x02, ®Gpio[1], 1); + reg_w(gspca_dev, 0x02, ®Gpio[1], 1); break; } regF1 = 0x01; - reg_w(dev, 0xf1, ®F1, 1); + reg_w(gspca_dev, 0xf1, ®F1, 1); return 0; } @@ -1073,7 +1064,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, Expodoit[3] = expo >> 16; Expodoit[4] = expo >> 8; Expodoit[5] = expo; - i2c_w8(gspca_dev->dev, Expodoit); + i2c_w8(gspca_dev, Expodoit); break; } case SENSOR_MI0360: { @@ -1086,9 +1077,9 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, expo = 0x0001; expoMi[3] = expo >> 8; expoMi[4] = expo; - i2c_w8(gspca_dev->dev, expoMi); - i2c_w8(gspca_dev->dev, doit); - i2c_w8(gspca_dev->dev, sensorgo); + i2c_w8(gspca_dev, expoMi); + i2c_w8(gspca_dev, doit); + i2c_w8(gspca_dev, sensorgo); break; } case SENSOR_MO4000: { @@ -1102,11 +1093,11 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev, else if (expo < 0x0001) expo = 0x0001; expoMof[3] = (expo & 0x03fc) >> 2; - i2c_w8(gspca_dev->dev, expoMof); + i2c_w8(gspca_dev, expoMof); expoMo10[3] = ((expo & 0x1c00) >> 10) | ((expo & 0x0003) << 4); - i2c_w8(gspca_dev->dev, expoMo10); - i2c_w8(gspca_dev->dev, gainMo); + i2c_w8(gspca_dev, expoMo10); + i2c_w8(gspca_dev, gainMo); PDEBUG(D_CONF, "set exposure %d", ((expoMo10[3] & 0x07) << 10) | (expoMof[3] << 2) @@ -1145,7 +1136,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) } k2 = sd->brightness >> 10; - reg_w(gspca_dev->dev, 0x96, &k2, 1); + reg_w(gspca_dev, 0x96, &k2, 1); } static void setcontrast(struct gspca_dev *gspca_dev) @@ -1160,7 +1151,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) contrast[2] = k2; contrast[0] = (k2 + 1) >> 1; contrast[4] = (k2 + 1) / 5; - reg_w(gspca_dev->dev, 0x84, contrast, 6); + reg_w(gspca_dev, 0x84, contrast, 6); } static void setcolors(struct gspca_dev *gspca_dev) @@ -1174,14 +1165,13 @@ static void setcolors(struct gspca_dev *gspca_dev) data = (colour + 32) & 0x7f; /* blue */ else data = (-colour + 32) & 0x7f; /* red */ - reg_w(gspca_dev->dev, 0x05, &data, 1); + reg_w(gspca_dev, 0x05, &data, 1); } /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int i; __u8 data; __u8 reg1; @@ -1203,45 +1193,45 @@ static void sd_start(struct gspca_dev *gspca_dev) /*fixme:jfm this sequence should appear at end of sd_start */ /* with data = 0x44; - reg_w(dev, 0x01, &data, 1); */ - reg_w(dev, 0x15, &sn9c1xx[0x15], 1); - reg_w(dev, 0x16, &sn9c1xx[0x16], 1); - reg_w(dev, 0x12, &sn9c1xx[0x12], 1); - reg_w(dev, 0x13, &sn9c1xx[0x13], 1); - reg_w(dev, 0x18, &sn9c1xx[0x18], 1); - reg_w(dev, 0xd2, &DC29[0], 1); - reg_w(dev, 0xd3, &DC29[1], 1); - reg_w(dev, 0xc6, &DC29[2], 1); - reg_w(dev, 0xc7, &DC29[3], 1); - reg_w(dev, 0xc8, &DC29[4], 1); - reg_w(dev, 0xc9, &DC29[5], 1); + reg_w(gspca_dev, 0x01, &data, 1); */ + reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1); + reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1); + reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1); + reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1); + reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); + reg_w(gspca_dev, 0xd2, &DC29[0], 1); + reg_w(gspca_dev, 0xd3, &DC29[1], 1); + reg_w(gspca_dev, 0xc6, &DC29[2], 1); + reg_w(gspca_dev, 0xc7, &DC29[3], 1); + reg_w(gspca_dev, 0xc8, &DC29[4], 1); + reg_w(gspca_dev, 0xc9, &DC29[5], 1); /*fixme:jfm end of ending sequence */ - reg_w(dev, 0x18, &sn9c1xx[0x18], 1); + reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); if (sd->customid == SN9C325) data = 0xae; else data = 0x60; - reg_w(dev, 0x17, &data, 1); - reg_w(dev, 0x05, &sn9c1xx[5], 1); - reg_w(dev, 0x07, &sn9c1xx[7], 1); - reg_w(dev, 0x06, &sn9c1xx[6], 1); - reg_w(dev, 0x14, &sn9c1xx[0x14], 1); + reg_w(gspca_dev, 0x17, &data, 1); + reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1); + reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1); + reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1); + reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1); if (sd->customid == SN9C325) { - reg_w(dev, 0x20, regsn20_sn9c325, 0x11); + reg_w(gspca_dev, 0x20, regsn20_sn9c325, 0x11); for (i = 0; i < 8; i++) - reg_w(dev, 0x84, reg84_sn9c325, 0x15); + reg_w(gspca_dev, 0x84, reg84_sn9c325, 0x15); data = 0x0a; - reg_w(dev, 0x9a, &data, 1); + reg_w(gspca_dev, 0x9a, &data, 1); data = 0x60; - reg_w(dev, 0x99, &data, 1); + reg_w(gspca_dev, 0x99, &data, 1); } else { - reg_w(dev, 0x20, regsn20, 0x11); + reg_w(gspca_dev, 0x20, regsn20, 0x11); for (i = 0; i < 8; i++) - reg_w(dev, 0x84, reg84, 0x15); + reg_w(gspca_dev, 0x84, reg84, 0x15); data = 0x08; - reg_w(dev, 0x9a, &data, 1); + reg_w(gspca_dev, 0x9a, &data, 1); data = 0x59; - reg_w(dev, 0x99, &data, 1); + reg_w(gspca_dev, 0x99, &data, 1); } mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; @@ -1294,38 +1284,38 @@ static void sd_start(struct gspca_dev *gspca_dev) } break; } - reg_w(dev, 0xc0, C0, 6); + reg_w(gspca_dev, 0xc0, C0, 6); switch (sd->customid) { case SN9C120: /*jfm ?? */ - reg_w(dev, 0xca, CA_sn9c120, 4); + reg_w(gspca_dev, 0xca, CA_sn9c120, 4); break; default: - reg_w(dev, 0xca, CA, 4); + reg_w(gspca_dev, 0xca, CA, 4); break; } switch (sd->customid) { case SN9C120: /*jfm ?? */ case SN9C325: - reg_w(dev, 0xce, CE_sn9c325, 4); + reg_w(gspca_dev, 0xce, CE_sn9c325, 4); break; default: - reg_w(dev, 0xce, CE, 4); + reg_w(gspca_dev, 0xce, CE, 4); /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */ break; } /* here change size mode 0 -> VGA; 1 -> CIF */ data = 0x40 | sn9c1xx[0x18] | (mode << 4); - reg_w(dev, 0x18, &data, 1); + reg_w(gspca_dev, 0x18, &data, 1); - reg_w(dev, 0x100, qtable4, 0x40); - reg_w(dev, 0x140, qtable4 + 0x40, 0x40); + reg_w(gspca_dev, 0x100, qtable4, 0x40); + reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); data = sn9c1xx[0x18] | (mode << 4); - reg_w(dev, 0x18, &data, 1); + reg_w(gspca_dev, 0x18, &data, 1); - reg_w(dev, 0x17, ®17, 1); - reg_w(dev, 0x01, ®1, 1); + reg_w(gspca_dev, 0x17, ®17, 1); + reg_w(gspca_dev, 0x01, ®1, 1); setbrightness(gspca_dev); setcontrast(gspca_dev); } @@ -1333,7 +1323,6 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; static const __u8 stophv7131[] = { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; static const __u8 stopmi0360[] = @@ -1345,11 +1334,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) data = 0x0b; switch (sd->sensor) { case SENSOR_HV7131R: - i2c_w8(dev, stophv7131); + i2c_w8(gspca_dev, stophv7131); data = 0x2b; break; case SENSOR_MI0360: - i2c_w8(dev, stopmi0360); + i2c_w8(gspca_dev, stopmi0360); data = 0x29; break; case SENSOR_MO4000: @@ -1362,12 +1351,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev) break; } sn9c1xx = sn_tb[(int) sd->sensor]; - reg_w(dev, 0x01, &sn9c1xx[1], 1); - reg_w(dev, 0x17, &sn9c1xx[0x17], 1); - reg_w(dev, 0x01, &sn9c1xx[1], 1); - reg_w(dev, 0x01, &data, 1); + reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); + reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1); + reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); + reg_w(gspca_dev, 0x01, &data, 1); regF1 = 0x01; - reg_w(dev, 0xf1, ®F1, 1); + reg_w(gspca_dev, 0xf1, ®F1, 1); } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -1463,33 +1452,35 @@ static unsigned int getexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; __u8 hexpo, mexpo, lexpo; - __u8 expo[6]; switch (sd->sensor) { case SENSOR_HV7131R: /* read sensor exposure */ - i2c_r5(gspca_dev, 0x25, expo); - return (expo[0] << 16) | (expo[1] << 8) | expo[2]; + i2c_r5(gspca_dev, 0x25); + return (gspca_dev->usb_buf[0] << 16) + | (gspca_dev->usb_buf[1] << 8) + | gspca_dev->usb_buf[2]; case SENSOR_MI0360: /* read sensor exposure */ - i2c_r5(gspca_dev, 0x09, expo); - return (expo[0] << 8) | expo[1]; + i2c_r5(gspca_dev, 0x09); + return (gspca_dev->usb_buf[0] << 8) + | gspca_dev->usb_buf[1]; case SENSOR_MO4000: - i2c_r5(gspca_dev, 0x0e, expo); - hexpo = 0; /* expo[1] & 0x07; */ - mexpo = 0x40; /* expo[2] &0xff; */ - lexpo = (expo[1] & 0x30) >> 4; + i2c_r5(gspca_dev, 0x0e); + hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */ + mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */ + lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4; PDEBUG(D_CONF, "exposure %d", (hexpo << 10) | (mexpo << 2) | lexpo); return (hexpo << 10) | (mexpo << 2) | lexpo; default: /* case SENSOR_OV7660: */ /* read sensor exposure */ - i2c_r5(gspca_dev, 0x04, expo); - hexpo = expo[3] & 0x2f; - lexpo = expo[0] & 0x02; - i2c_r5(gspca_dev, 0x08, expo); - mexpo = expo[2]; + i2c_r5(gspca_dev, 0x04); + hexpo = gspca_dev->usb_buf[3] & 0x2f; + lexpo = gspca_dev->usb_buf[0] & 0x02; + i2c_r5(gspca_dev, 0x08); + mexpo = gspca_dev->usb_buf[2]; return (hexpo << 10) | (mexpo << 2) | lexpo; } } diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index d00f0f76e0e3..156206118795 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); @@ -372,26 +372,27 @@ static const __u8 qtable_pocketdv[2][64] = { 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28} }; -static void reg_r(struct usb_device *dev, - __u16 index, - __u8 *buffer, __u16 length) +/* read 'len' bytes to gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 index, + __u16 length) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, 500); + index, gspca_dev->usb_buf, length, 500); } -static int reg_w(struct usb_device *dev, +static int reg_w(struct gspca_dev *gspca_dev, __u16 req, __u16 index, __u16 value) { int ret; PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value); - ret = usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + ret = usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); @@ -401,28 +402,27 @@ static int reg_w(struct usb_device *dev, } /* returns: negative is error, pos or zero is data */ -static int reg_r_12(struct usb_device *dev, +static int reg_r_12(struct gspca_dev *gspca_dev, __u16 req, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */ { int ret; - __u8 buf[2]; - buf[1] = 0; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + gspca_dev->usb_buf[1] = 0; + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - buf, length, + gspca_dev->usb_buf, length, 500); /* timeout */ if (ret < 0) { PDEBUG(D_ERR, "reg_r_12 err %d", ret); return -1; } - return (buf[1] << 8) + buf[0]; + return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } /* @@ -430,13 +430,13 @@ static int reg_r_12(struct usb_device *dev, * a reg_read call. * Returns: negative is error or timeout, zero is success. */ -static int reg_r_wait(struct usb_device *dev, +static int reg_r_wait(struct gspca_dev *gspca_dev, __u16 reg, __u16 index, __u16 value) { int ret, cnt = 20; while (--cnt > 0) { - ret = reg_r_12(dev, reg, index, 1); + ret = reg_r_12(gspca_dev, reg, index, 1); if (ret == value) return 0; msleep(50); @@ -447,11 +447,10 @@ static int reg_r_wait(struct usb_device *dev, static int write_vector(struct gspca_dev *gspca_dev, const __u16 data[][3]) { - struct usb_device *dev = gspca_dev->dev; int ret, i = 0; while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_w(dev, data[i][0], data[i][2], data[i][1]); + ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]); if (ret < 0) return ret; i++; @@ -465,19 +464,18 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, unsigned int cbase, const __u8 qtable[2][64]) { - struct usb_device *dev = gspca_dev->dev; int i, err; /* loop over y components */ for (i = 0; i < 64; i++) { - err = reg_w(dev, request, ybase + i, qtable[0][i]); + err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]); if (err < 0) return err; } /* loop over c components */ for (i = 0; i < 64; i++) { - err = reg_w(dev, request, cbase + i, qtable[1][i]); + err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]); if (err < 0) return err; } @@ -486,37 +484,33 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, static void spca500_ping310(struct gspca_dev *gspca_dev) { - __u8 Data[2]; - - reg_r(gspca_dev->dev, 0x0d04, Data, 2); + reg_r(gspca_dev, 0x0d04, 2); PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x", - Data[0], Data[1]); + gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); } static void spca500_clksmart310_init(struct gspca_dev *gspca_dev) { - __u8 Data[2]; - - reg_r(gspca_dev->dev, 0x0d05, Data, 2); + reg_r(gspca_dev, 0x0d05, 2); PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x", - Data[0], Data[1]); - reg_w(gspca_dev->dev, 0x00, 0x8167, 0x5a); + gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]); + reg_w(gspca_dev, 0x00, 0x8167, 0x5a); spca500_ping310(gspca_dev); - reg_w(gspca_dev->dev, 0x00, 0x8168, 0x22); - reg_w(gspca_dev->dev, 0x00, 0x816a, 0xc0); - reg_w(gspca_dev->dev, 0x00, 0x816b, 0x0b); - reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); - reg_w(gspca_dev->dev, 0x00, 0x8157, 0x5b); - reg_w(gspca_dev->dev, 0x00, 0x8158, 0x5b); - reg_w(gspca_dev->dev, 0x00, 0x813f, 0x03); - reg_w(gspca_dev->dev, 0x00, 0x8151, 0x4a); - reg_w(gspca_dev->dev, 0x00, 0x8153, 0x78); - reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x04); + reg_w(gspca_dev, 0x00, 0x8168, 0x22); + reg_w(gspca_dev, 0x00, 0x816a, 0xc0); + reg_w(gspca_dev, 0x00, 0x816b, 0x0b); + reg_w(gspca_dev, 0x00, 0x8169, 0x25); + reg_w(gspca_dev, 0x00, 0x8157, 0x5b); + reg_w(gspca_dev, 0x00, 0x8158, 0x5b); + reg_w(gspca_dev, 0x00, 0x813f, 0x03); + reg_w(gspca_dev, 0x00, 0x8151, 0x4a); + reg_w(gspca_dev, 0x00, 0x8153, 0x78); + reg_w(gspca_dev, 0x00, 0x0d01, 0x04); /* 00 for adjust shutter */ - reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); - reg_w(gspca_dev->dev, 0x00, 0x8169, 0x25); - reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x02); + reg_w(gspca_dev, 0x00, 0x0d02, 0x01); + reg_w(gspca_dev, 0x00, 0x8169, 0x25); + reg_w(gspca_dev, 0x00, 0x0d01, 0x02); } static void spca500_setmode(struct gspca_dev *gspca_dev, @@ -525,14 +519,14 @@ static void spca500_setmode(struct gspca_dev *gspca_dev, int mode; /* set x multiplier */ - reg_w(gspca_dev->dev, 0, 0x8001, xmult); + reg_w(gspca_dev, 0, 0x8001, xmult); /* set y multiplier */ - reg_w(gspca_dev->dev, 0, 0x8002, ymult); + reg_w(gspca_dev, 0, 0x8002, ymult); /* use compressed mode, VGA, with mode specific subsample */ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg_w(gspca_dev->dev, 0, 0x8003, mode << 4); + reg_w(gspca_dev, 0, 0x8003, mode << 4); } static int spca500_full_reset(struct gspca_dev *gspca_dev) @@ -540,18 +534,18 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev) int err; /* send the reset command */ - err = reg_w(gspca_dev->dev, 0xe0, 0x0001, 0x0000); + err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000); if (err < 0) return err; /* wait for the reset to complete */ - err = reg_r_wait(gspca_dev->dev, 0x06, 0x0000, 0x0000); + err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000); if (err < 0) return err; - err = reg_w(gspca_dev->dev, 0xe0, 0x0000, 0x0000); + err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000); if (err < 0) return err; - err = reg_r_wait(gspca_dev->dev, 0x06, 0, 0); + err = reg_r_wait(gspca_dev, 0x06, 0, 0); if (err < 0) { PDEBUG(D_ERR, "reg_r_wait() failed"); return err; @@ -568,15 +562,13 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev) /* up-port the same feature as in 2.4.x kernel */ static int spca500_synch310(struct gspca_dev *gspca_dev) { - __u8 Data; - if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) { PDEBUG(D_ERR, "Set packet size: set interface error"); goto error; } spca500_ping310(gspca_dev); - reg_r(gspca_dev->dev, 0x0d00, &Data, 1); + reg_r(gspca_dev, 0x0d00, 1); /* need alt setting here */ PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt); @@ -600,12 +592,12 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) /* some unknow command from Aiptek pocket dv and family300 */ - reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); - reg_w(gspca_dev->dev, 0x00, 0x0d03, 0x00); - reg_w(gspca_dev->dev, 0x00, 0x0d02, 0x01); + reg_w(gspca_dev, 0x00, 0x0d01, 0x01); + reg_w(gspca_dev, 0x00, 0x0d03, 0x00); + reg_w(gspca_dev, 0x00, 0x0d02, 0x01); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); @@ -613,22 +605,23 @@ static void spca500_reinit(struct gspca_dev *gspca_dev) PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed on init"); /* set qtable index */ - reg_w(gspca_dev->dev, 0x00, 0x8880, 2); + reg_w(gspca_dev, 0x00, 0x8880, 2); /* family cam Quicksmart stuff */ - reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ - reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); + reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev, 0x00, 0x870a, 0x04); /*Start init sequence or stream */ - - reg_w(gspca_dev->dev, 0, 0x8003, 0x00); + reg_w(gspca_dev, 0, 0x8003, 0x00); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); msleep(2000); - if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) { + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); + } } /* this function is called at probe time */ @@ -785,9 +778,10 @@ static void sd_start(struct gspca_dev *gspca_dev) } /* is there a sensor here ? */ - reg_r(gspca_dev->dev, 0x8a04, &Data, 1); - PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02X", Data); - PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02X, Ymult: 0x%02X", + reg_r(gspca_dev, 0x8a04, 1); + PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x", + gspca_dev->usb_buf[0]); + PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x", gspca_dev->curr_mode, xmult, ymult); /* setup qtable */ @@ -796,33 +790,34 @@ static void sd_start(struct gspca_dev *gspca_dev) spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); - reg_w(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); msleep(500); - if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); spca500_synch310(gspca_dev); write_vector(gspca_dev, spca500_visual_defaults); spca500_setmode(gspca_dev, xmult, ymult); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); PDEBUG(D_ERR, "failed to enable drop packet"); - reg_w(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); @@ -830,16 +825,17 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev, 0x00, 0x870a, 0x04); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); break; case CreativePCCam300: /* Creative PC-CAM 300 640x480 CCD */ case IntelPocketPCCamera: /* FIXME: Temporary fix for @@ -852,10 +848,10 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ - err = reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001); if (err < 0) PDEBUG(D_ERR, "failed to enable drop packet"); - reg_w(gspca_dev->dev, 0x00, 0x8880, 3); + reg_w(gspca_dev, 0x00, 0x8880, 3); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); @@ -863,16 +859,17 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); - reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); + reg_w(gspca_dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); /* write_vector(gspca_dev, spca500_visual_defaults); */ break; @@ -883,8 +880,8 @@ static void sd_start(struct gspca_dev *gspca_dev) if (err < 0) PDEBUG(D_ERR, "spca500_full_reset failed"); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); - reg_w(gspca_dev->dev, 0x00, 0x8880, 0); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x8880, 0); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_kodak_ez200); @@ -892,16 +889,17 @@ static void sd_start(struct gspca_dev *gspca_dev) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); spca500_setmode(gspca_dev, xmult, ymult); - reg_w(gspca_dev->dev, 0x20, 0x0001, 0x0004); + reg_w(gspca_dev, 0x20, 0x0001, 0x0004); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - if (reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44) != 0) + if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) PDEBUG(D_ERR, "reg_r_wait() failed"); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); /* write_vector(gspca_dev, spca500_visual_defaults); */ break; @@ -916,56 +914,58 @@ static void sd_start(struct gspca_dev *gspca_dev) case ToptroIndus: case AgfaCl20: spca500_reinit(gspca_dev); - reg_w(gspca_dev->dev, 0x00, 0x0d01, 0x01); + reg_w(gspca_dev, 0x00, 0x0d01, 0x01); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_pocketdv); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_w(gspca_dev->dev, 0x00, 0x8880, 2); + reg_w(gspca_dev, 0x00, 0x8880, 2); /* familycam Quicksmart pocketDV stuff */ - reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Set agc transfer: synced inbetween frames */ - reg_w(gspca_dev->dev, 0x00, 0x820f, 0x01); + reg_w(gspca_dev, 0x00, 0x820f, 0x01); /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); - reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); + reg_r_wait(gspca_dev, 0, 0x8000, 0x44); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); break; case LogitechTraveler: case LogitechClickSmart510: - reg_w(gspca_dev->dev, 0x02, 0x00, 0x00); + reg_w(gspca_dev, 0x02, 0x00, 0x00); /* enable drop packet */ - reg_w(gspca_dev->dev, 0x00, 0x850a, 0x0001); + reg_w(gspca_dev, 0x00, 0x850a, 0x0001); err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840, qtable_creative_pccam); if (err < 0) PDEBUG(D_ERR, "spca50x_setup_qtable failed"); - reg_w(gspca_dev->dev, 0x00, 0x8880, 3); - reg_w(gspca_dev->dev, 0x00, 0x800a, 0x00); + reg_w(gspca_dev, 0x00, 0x8880, 3); + reg_w(gspca_dev, 0x00, 0x800a, 0x00); /* Init SDRAM - needed for SDRAM access */ - reg_w(gspca_dev->dev, 0x00, 0x870a, 0x04); + reg_w(gspca_dev, 0x00, 0x870a, 0x04); spca500_setmode(gspca_dev, xmult, ymult); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - reg_r_wait(gspca_dev->dev, 0, 0x8000, 0x44); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); + reg_r_wait(gspca_dev, 0, 0x8000, 0x44); - reg_r(gspca_dev->dev, 0x816b, &Data, 1); - reg_w(gspca_dev->dev, 0x00, 0x816b, Data); + reg_r(gspca_dev, 0x816b, 1); + Data = gspca_dev->usb_buf[0]; + reg_w(gspca_dev, 0x00, 0x816b, Data); write_vector(gspca_dev, Clicksmart510_defaults); break; } @@ -973,14 +973,13 @@ static void sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { - __u8 data; - - reg_w(gspca_dev->dev, 0, 0x8003, 0x00); + reg_w(gspca_dev, 0, 0x8003, 0x00); /* switch to video camera mode */ - reg_w(gspca_dev->dev, 0x00, 0x8000, 0x0004); - reg_r(gspca_dev->dev, 0x8000, &data, 1); - PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", data); + reg_w(gspca_dev, 0x00, 0x8000, 0x0004); + reg_r(gspca_dev, 0x8000, 1); + PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x", + gspca_dev->usb_buf[0]); } static void sd_stop0(struct gspca_dev *gspca_dev) @@ -1043,7 +1042,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w(gspca_dev->dev, 0x00, 0x8167, + reg_w(gspca_dev, 0x00, 0x8167, (__u8) (sd->brightness - 128)); } @@ -1052,7 +1051,7 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret; - ret = reg_r_12(gspca_dev->dev, 0x00, 0x8167, 1); + ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1); if (ret >= 0) sd->brightness = ret + 128; } @@ -1061,7 +1060,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w(gspca_dev->dev, 0x00, 0x8168, sd->contrast); + reg_w(gspca_dev, 0x00, 0x8168, sd->contrast); } static void getcontrast(struct gspca_dev *gspca_dev) @@ -1069,7 +1068,7 @@ static void getcontrast(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret; - ret = reg_r_12(gspca_dev->dev, 0x0, 0x8168, 1); + ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1); if (ret >= 0) sd->contrast = ret; } @@ -1078,7 +1077,7 @@ static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - reg_w(gspca_dev->dev, 0x00, 0x8169, sd->colors); + reg_w(gspca_dev, 0x00, 0x8169, sd->colors); } static void getcolors(struct gspca_dev *gspca_dev) @@ -1086,7 +1085,7 @@ static void getcolors(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int ret; - ret = reg_r_12(gspca_dev->dev, 0x0, 0x8169, 1); + ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1); if (ret >= 0) sd->colors = ret; } diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 2064dc008af1..8cee6748d38f 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); @@ -1826,28 +1826,27 @@ static int reg_write(struct usb_device *dev, } /* returns: negative is error, pos or zero is data */ -static int reg_read(struct usb_device *dev, +static int reg_read(struct gspca_dev *gspca_dev, __u16 req, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */ { int ret; - __u8 buf[2]; - buf[1] = 0; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + gspca_dev->usb_buf[1] = 0; + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - buf, length, + gspca_dev->usb_buf, length, 500); /* timeout */ if (ret < 0) { PDEBUG(D_ERR, "reg_read err %d", ret); return -1; } - return (buf[1] << 8) + buf[0]; + return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, @@ -1883,7 +1882,7 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; __u16 brightness; - brightness = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x11, 2); + brightness = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x11, 2); sd->brightness = brightness << 1; } @@ -1913,8 +1912,8 @@ static void getcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - sd->colors = reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, 2); -/* sd->hue = (reg_read(gspca_dev->dev, SPCA501_REG_CCDSP, 0x13, */ + sd->colors = reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x0c, 2); +/* sd->hue = (reg_read(gspca_dev, SPCA501_REG_CCDSP, 0x13, */ /* 2) & 0xFF) << 8; */ } diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 5d28d23b8375..ddea6e140aa8 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -23,8 +23,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); @@ -593,29 +593,27 @@ static int reg_write(struct usb_device *dev, } /* returns: negative is error, pos or zero is data */ -static int reg_read(struct usb_device *dev, +static int reg_read(struct gspca_dev *gspca_dev, __u16 reg, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */ { int ret; - __u8 buf[4]; - buf[1] = 0; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + gspca_dev->usb_buf[1] = 0; + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), reg, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, (__u16) 0, /* value */ (__u16) index, - buf, - length, + gspca_dev->usb_buf, length, 500); /* timeout */ if (ret < 0) { PDEBUG(D_ERR, "reg_read err %d", ret); return -1; } - return (buf[1] << 8) + buf[0]; + return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, @@ -697,7 +695,7 @@ static int sd_open(struct gspca_dev *gspca_dev) write_vector(gspca_dev, spca505b_open_data_ccd); else write_vector(gspca_dev, spca505_open_data_ccd); - ret = reg_read(gspca_dev->dev, 6, 0x16, 2); + ret = reg_read(gspca_dev, 6, 0x16, 2); if (ret < 0) { PDEBUG(D_ERR|D_STREAM, @@ -874,8 +872,8 @@ static void getbrightness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; sd->brightness = 255 - - ((reg_read(gspca_dev->dev, 5, 0x01, 1) >> 2) - + (reg_read(gspca_dev->dev, 5, 0x0, 1) << 6)); + - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2) + + (reg_read(gspca_dev, 5, 0x0, 1) << 6)); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 2d249b00bdcd..143203c1fd9f 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -25,8 +25,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); @@ -153,17 +153,18 @@ static struct v4l2_pix_format vga_mode[] = { #define SAA7113_hue 0x0d /* defaults 0x00 */ #define SAA7113_I2C_BASE_WRITE 0x4a -static void reg_r(struct usb_device *dev, +/* read 'len' bytes to gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, __u16 req, __u16 index, - __u8 *buffer, __u16 length) + __u16 length) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, + index, gspca_dev->usb_buf, length, 500); } @@ -189,13 +190,12 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) { int retry = 60; - __u8 Data[2]; reg_w(gspca_dev->dev, 0x07, reg, 0x0001); reg_w(gspca_dev->dev, 0x07, valeur, 0x0000); while (retry--) { - reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); - if ((Data[0] | Data[1]) == 0x00) + reg_r(gspca_dev, 0x07, 0x0003, 2); + if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) break; } } @@ -203,21 +203,19 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur, static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg) { int retry = 60; - __u8 Data[2]; - __u8 value; reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004); reg_w(gspca_dev->dev, 0x07, reg, 0x0001); reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002); while (--retry) { - reg_r(gspca_dev->dev, 0x07, 0x0003, Data, 2); - if ((Data[0] | Data[1]) == 0x00) + reg_r(gspca_dev, 0x07, 0x0003, 2); + if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00) break; } if (retry == 0) return -1; - reg_r(gspca_dev->dev, 0x07, 0x0000, &value, 1); - return value; + reg_r(gspca_dev, 0x07, 0x0000, 1); + return gspca_dev->usb_buf[0]; } static void spca506_SetNormeInput(struct gspca_dev *gspca_dev, @@ -437,7 +435,6 @@ static void sd_start(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; __u16 norme; __u16 channel; - __u8 Data[2]; /**************************************/ reg_w(dev, 0x03, 0x00, 0x0004); @@ -555,8 +552,8 @@ static void sd_start(struct gspca_dev *gspca_dev) /* compress setting and size */ /* set i2c luma */ reg_w(dev, 0x02, 0x01, 0x0000); - reg_w(dev, 0x03, 0x12, 0x000); - reg_r(dev, 0x04, 0x0001, Data, 2); + reg_w(dev, 0x03, 0x12, 0x0000); + reg_r(gspca_dev, 0x04, 0x0001, 2); PDEBUG(D_STREAM, "webcam started"); spca506_GetNormeInput(gspca_dev, &norme, &channel); spca506_SetNormeInput(gspca_dev, norme, channel); diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 7f262f23841e..d8cd93866a4a 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); @@ -1433,26 +1433,26 @@ static int reg_write(struct usb_device *dev, /* read 1 byte */ /* returns: negative is error, pos or zero is data */ -static int reg_read(struct usb_device *dev, +static int reg_read(struct gspca_dev *gspca_dev, __u16 index) /* wIndex */ { int ret; - __u8 data; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* register */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - (__u16) 0, /* value */ + 0, /* value */ index, - &data, 1, + gspca_dev->usb_buf, 1, 500); /* timeout */ - PDEBUG(D_USBI, "reg read i:%04x --> %02x", index, data); + PDEBUG(D_USBI, "reg read i:%04x --> %02x", + index, gspca_dev->usb_buf[0]); if (ret < 0) { PDEBUG(D_ERR|D_USBI, "reg_read err %d", ret); return ret; } - return data; + return gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, @@ -1475,15 +1475,12 @@ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; struct cam *cam; - __u16 vendor; __u16 product; int data1, data2; - vendor = id->idVendor; product = id->idProduct; - switch (vendor) { + switch (id->idVendor) { case 0x0130: /* Clone webcam */ /* switch (product) { */ /* case 0x0130: */ @@ -1535,15 +1532,15 @@ static int sd_config(struct gspca_dev *gspca_dev, * prove that we can communicate with the device. This works, which * confirms at we are communicating properly and that the device * is a 508. */ - data1 = reg_read(dev, 0x8104); - data2 = reg_read(dev, 0x8105); + data1 = reg_read(gspca_dev, 0x8104); + data2 = reg_read(gspca_dev, 0x8105); PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1); - data1 = reg_read(dev, 0x8106); - data2 = reg_read(dev, 0x8107); + data1 = reg_read(gspca_dev, 0x8106); + data2 = reg_read(gspca_dev, 0x8107); PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1); - data1 = reg_read(dev, 0x8621); + data1 = reg_read(gspca_dev, 0x8621); PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; @@ -1711,7 +1708,7 @@ static void getbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - sd->brightness = reg_read(gspca_dev->dev, 0x8651); + sd->brightness = reg_read(gspca_dev, 0x8651); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index f0770ee595d8..b659bd0f788d 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); @@ -177,27 +177,28 @@ static void write_vector(struct gspca_dev *gspca_dev, } } -static void reg_r(struct usb_device *dev, - __u16 index, __u8 *buffer, __u16 length) +/* read 'len' bytes to gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 index, __u16 length) { - usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, 500); + index, gspca_dev->usb_buf, length, 500); } -static void reg_w_buf(struct usb_device *dev, +static void reg_w_buf(struct gspca_dev *gspca_dev, __u16 index, const __u8 *buffer, __u16 len) { - __u8 tmpbuf[8]; - - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, tmpbuf, len, 500); + index, gspca_dev->usb_buf, len, 500); } static void i2c_init(struct gspca_dev *gspca_dev, __u8 mode) @@ -211,7 +212,6 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) int retry = 60; __u8 DataLow; __u8 DataHight; - __u8 Data; DataLow = valeur; DataHight = valeur >> 8; @@ -219,8 +219,8 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 valeur, __u16 reg) reg_w_val(gspca_dev->dev, DataLow, 0x8805); reg_w_val(gspca_dev->dev, DataHight, 0x8800); while (retry--) { - reg_r(gspca_dev->dev, 0x8803, &Data, 1); - if (!Data) + reg_r(gspca_dev, 0x8803, 1); + if (!gspca_dev->usb_buf[0]) break; } } @@ -230,20 +230,21 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode) int retry = 60; __u8 value; __u8 vallsb; - __u8 Data; reg_w_val(gspca_dev->dev, 0x92, 0x8804); reg_w_val(gspca_dev->dev, reg, 0x8801); reg_w_val(gspca_dev->dev, (mode | 0x01), 0x8802); while (retry--) { - reg_r(gspca_dev->dev, 0x8803, &Data, 1); - if (!Data) + reg_r(gspca_dev, 0x8803, 1); + if (!gspca_dev->usb_buf) break; } if (retry == 0) return -1; - reg_r(gspca_dev->dev, 0x8800, &value, 1); - reg_r(gspca_dev->dev, 0x8805, &vallsb, 1); + reg_r(gspca_dev, 0x8800, 1); + value = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8805, 1); + vallsb = gspca_dev->usb_buf[0]; return ((int) value << 8) | vallsb; } @@ -541,7 +542,7 @@ static void sensor_mapwrite(struct gspca_dev *gspca_dev, while (sensormap[i][0]) { usbval[0] = sensormap[i][1]; usbval[1] = sensormap[i][1] >> 8; - reg_w_buf(gspca_dev->dev, sensormap[i][0], usbval, 2); + reg_w_buf(gspca_dev, sensormap[i][0], usbval, 2); i++; } } @@ -559,7 +560,6 @@ static int sd_config(struct gspca_dev *gspca_dev, const struct usb_device_id *id) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; struct cam *cam; __u16 vendor, product; __u8 data1, data2; @@ -568,11 +568,15 @@ static int sd_config(struct gspca_dev *gspca_dev, * prove that we can communicate with the device. This works, which * confirms at we are communicating properly and that the device * is a 561. */ - reg_r(dev, 0x8104, &data1, 1); - reg_r(dev, 0x8105, &data2, 1); + reg_r(gspca_dev, 0x8104, 1); + data1 = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8105, 1); + data2 = gspca_dev->usb_buf[0]; vendor = (data2 << 8) | data1; - reg_r(dev, 0x8106, &data1, 1); - reg_r(dev, 0x8107, &data2, 1); + reg_r(gspca_dev, 0x8106, 1); + data1 = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8107, 1); + data2 = gspca_dev->usb_buf[0]; product = (data2 << 8) | data1; if (vendor != id->idVendor || product != id->idProduct) { PDEBUG(D_PROBE, "Bad vendor / product from device"); @@ -656,8 +660,8 @@ static void setcontrast(struct gspca_dev *gspca_dev) Reg8391[0] = expotimes & 0xff; /* exposure */ Reg8391[1] = 0x18 | (expotimes >> 8); Reg8391[2] = sd->brightness; /* gain */ - reg_w_buf(dev, 0x8391, Reg8391, 8); - reg_w_buf(dev, 0x8390, Reg8391, 8); + reg_w_buf(gspca_dev, 0x8391, Reg8391, 8); + reg_w_buf(gspca_dev, 0x8390, Reg8391, 8); break; } } @@ -714,10 +718,11 @@ static void sd_start(struct gspca_dev *gspca_dev) * is sufficient to push raw frames at ~20fps */ reg_w_val(dev, 0x8500, mode); } /* -- qq@kuku.eu.org */ - reg_w_buf(dev, 0x8307, Reg8307, 2); - reg_w_val(dev, 0x8700, Clck); /* 0x8f 0x85 0x27 clock */ - reg_w_val(dev, 0x8112, 0x1e | 0x20); - reg_w_val(dev, 0x850b, 0x03); + reg_w_buf(gspca_dev, 0x8307, Reg8307, 2); + reg_w_val(gspca_dev->dev, 0x8700, Clck); + /* 0x8f 0x85 0x27 clock */ + reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20); + reg_w_val(gspca_dev->dev, 0x850b, 0x03); setcontrast(gspca_dev); break; } @@ -752,10 +757,14 @@ static void setautogain(struct gspca_dev *gspca_dev) switch (sd->chip_revision) { case Rev072A: - reg_r(gspca_dev->dev, 0x8621, &Gr, 1); - reg_r(gspca_dev->dev, 0x8622, &R, 1); - reg_r(gspca_dev->dev, 0x8623, &B, 1); - reg_r(gspca_dev->dev, 0x8624, &Gb, 1); + reg_r(gspca_dev, 0x8621, 1); + Gr = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8622, 1); + R = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8623, 1); + B = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8624, 1); + Gb = gspca_dev->usb_buf[0]; y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8; /* u= (128*B-(43*(Gr+Gb+R))) >> 8; */ /* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */ @@ -867,20 +876,19 @@ static void setbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 value; __u16 tot; switch (sd->chip_revision) { case Rev072A: tot = 0; - reg_r(gspca_dev->dev, 0x8611, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8612, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8613, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8614, &value, 1); - tot += value; + reg_r(gspca_dev, 0x8611, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8612, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8613, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8614, 1); + tot += gspca_dev->usb_buf[0]; sd->brightness = tot >> 2; break; default: @@ -893,20 +901,19 @@ static void getbrightness(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 value; __u16 tot; switch (sd->chip_revision) { case Rev072A: tot = 0; - reg_r(gspca_dev->dev, 0x8651, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8652, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8653, &value, 1); - tot += value; - reg_r(gspca_dev->dev, 0x8654, &value, 1); - tot += value; + reg_r(gspca_dev, 0x8651, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8652, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8653, 1); + tot += gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0x8654, 1); + tot += gspca_dev->usb_buf[0]; sd->contrast = tot << 6; break; default: diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index d676cd16aa74..c78ee0d3e59b 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -23,8 +23,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); @@ -127,7 +127,7 @@ static struct v4l2_pix_format vga_mode[] = { /* -- read a register -- */ static int reg_r(struct gspca_dev *gspca_dev, - __u16 index, __u8 *buf) + __u16 index) { struct usb_device *dev = gspca_dev->dev; int ret; @@ -137,11 +137,13 @@ static int reg_r(struct gspca_dev *gspca_dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x00, index, - buf, 1, + gspca_dev->usb_buf, 1, 500); - if (ret < 0) + if (ret < 0) { PDEBUG(D_ERR, "reg_r err %d", ret); - return ret; + return ret; + } + return gspca_dev->usb_buf[0]; } /* -- write a register -- */ @@ -164,58 +166,55 @@ static int reg_w(struct gspca_dev *gspca_dev, return ret; } -/* -- get a value -- */ +/* -- get a bulk value (4 bytes) -- */ static int rcv_val(struct gspca_dev *gspca_dev, - int ads, - int len) + int ads) { struct usb_device *dev = gspca_dev->dev; int alen, ret; - unsigned char bulk_buf[4]; reg_w(gspca_dev, 0x634, (ads >> 16) & 0xff); reg_w(gspca_dev, 0x635, (ads >> 8) & 0xff); reg_w(gspca_dev, 0x636, ads & 0xff); reg_w(gspca_dev, 0x637, 0); - reg_w(gspca_dev, 0x638, len & 0xff); - reg_w(gspca_dev, 0x639, len >> 8); + reg_w(gspca_dev, 0x638, 4); /* len & 0xff */ + reg_w(gspca_dev, 0x639, 0); /* len >> 8 */ reg_w(gspca_dev, 0x63a, 0); reg_w(gspca_dev, 0x63b, 0); reg_w(gspca_dev, 0x630, 5); - if (len > sizeof bulk_buf) - return -1; ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, 5), - bulk_buf, - len, + gspca_dev->usb_buf, + 4, /* length */ &alen, - 500); /* timeout in milliseconds */ + 500); /* timeout in milliseconds */ return ret; } -/* -- send a value -- */ +/* -- send a bulk value -- */ static int snd_val(struct gspca_dev *gspca_dev, int ads, unsigned int val) { struct usb_device *dev = gspca_dev->dev; int alen, ret; - __u8 value, seq; - unsigned char bulk_buf[4]; + __u8 seq = 0; if (ads == 0x003f08) { - ret = reg_r(gspca_dev, 0x0704, &value); + ret = reg_r(gspca_dev, 0x0704); if (ret < 0) goto ko; - ret = reg_r(gspca_dev, 0x0705, &seq); + ret = reg_r(gspca_dev, 0x0705); if (ret < 0) goto ko; - ret = reg_r(gspca_dev, 0x0650, &value); + seq = ret; /* keep the sequence number */ + ret = reg_r(gspca_dev, 0x0650); if (ret < 0) goto ko; reg_w(gspca_dev, 0x654, seq); - } else + } else { reg_w(gspca_dev, 0x654, (ads >> 16) & 0xff); + } reg_w(gspca_dev, 0x655, (ads >> 8) & 0xff); reg_w(gspca_dev, 0x656, ads & 0xff); reg_w(gspca_dev, 0x657, 0); @@ -224,13 +223,13 @@ static int snd_val(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x65a, 0); reg_w(gspca_dev, 0x65b, 0); reg_w(gspca_dev, 0x650, 5); - bulk_buf[0] = (val >> 24) & 0xff; - bulk_buf[1] = (val >> 16) & 0xff; - bulk_buf[2] = (val >> 8) & 0xff; - bulk_buf[3] = val & 0xff; + gspca_dev->usb_buf[0] = val >> 24; + gspca_dev->usb_buf[1] = val >> 16; + gspca_dev->usb_buf[2] = val >> 8; + gspca_dev->usb_buf[3] = val; ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, 6), - bulk_buf, + gspca_dev->usb_buf, 4, &alen, 500); /* timeout in milliseconds */ @@ -303,7 +302,7 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; - gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0]; + gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; sd->colors = COLOR_DEF; @@ -314,16 +313,15 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - __u8 value; int ret; /* check if the device responds */ usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1); - ret = reg_r(gspca_dev, 0x0740, &value); + ret = reg_r(gspca_dev, 0x0740); if (ret < 0) return ret; - if (value != 0xff) { - PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value); + if (ret != 0xff) { + PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", ret); return -1; } return 0; @@ -332,7 +330,6 @@ static int sd_open(struct gspca_dev *gspca_dev) /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { - __u8 dum; int ret, value; /* work on alternate 1 */ @@ -355,11 +352,11 @@ static void sd_start(struct gspca_dev *gspca_dev) gspca_dev->iface, gspca_dev->alt); goto out; } - ret = reg_r(gspca_dev, 0x0630, &dum); + ret = reg_r(gspca_dev, 0x0630); if (ret < 0) goto out; - rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ - ret = reg_r(gspca_dev, 0x0650, &dum); + rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ + ret = reg_r(gspca_dev, 0x0650); if (ret < 0) goto out; snd_val(gspca_dev, 0x000020, 0xffffffff); @@ -389,14 +386,13 @@ out: static void sd_stopN(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 value; set_par(gspca_dev, 0x02000000); set_par(gspca_dev, 0x02000000); usb_set_interface(dev, gspca_dev->iface, 1); - reg_r(gspca_dev, 0x0630, &value); - rcv_val(gspca_dev, 0x000020, 4); /* << (value ff ff ff ff) */ - reg_r(gspca_dev, 0x0650, &value); + reg_r(gspca_dev, 0x0630); + rcv_val(gspca_dev, 0x000020); /* << (value ff ff ff ff) */ + reg_r(gspca_dev, 0x0650); snd_val(gspca_dev, 0x000020, 0xffffffff); reg_w(gspca_dev, 0x0620, 0); reg_w(gspca_dev, 0x0630, 0); @@ -538,10 +534,10 @@ static int sd_querymenu(struct gspca_dev *gspca_dev, } /* sub-driver description */ -static struct sd_desc sd_desc = { +static const struct sd_desc sd_desc = { .name = MODULE_NAME, .ctrls = sd_ctrls, - .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0], + .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .open = sd_open, .start = sd_start, @@ -554,7 +550,7 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ #define DVNM(name) .driver_info = (kernel_ulong_t) name -static __devinitdata struct usb_device_id device_table[] = { +static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, {} }; diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index f66594a113a7..acd4a077198a 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); @@ -452,7 +452,7 @@ static const __u8 qtable_spca504_default[2][64] = { 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e} }; -static void spca5xxRegRead(struct usb_device *dev, +static void reg_r(struct usb_device *dev, __u16 req, __u16 index, __u8 *buffer, __u16 length) @@ -466,7 +466,7 @@ static void spca5xxRegRead(struct usb_device *dev, 500); } -static void spca5xxRegWrite(struct usb_device *dev, +static void reg_w(struct usb_device *dev, __u16 req, __u16 value, __u16 index, @@ -480,7 +480,8 @@ static void spca5xxRegWrite(struct usb_device *dev, 500); } -static int reg_write(struct usb_device *dev, +/* write req / index / value */ +static int reg_w_riv(struct usb_device *dev, __u16 req, __u16 index, __u16 value) { int ret; @@ -490,57 +491,56 @@ static int reg_write(struct usb_device *dev, req, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, index, NULL, 0, 500); - PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x", + PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d", req, index, value, ret); if (ret < 0) PDEBUG(D_ERR, "reg write: error %d", ret); return ret; } -static int reg_read_info(struct usb_device *dev, +/* read 1 byte */ +static int reg_r_1(struct gspca_dev *gspca_dev, __u16 value) /* wValue */ { int ret; - __u8 data; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0x20, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, value, 0, /* index */ - &data, 1, + gspca_dev->usb_buf, 1, 500); /* timeout */ if (ret < 0) { - PDEBUG(D_ERR, "reg_read_info err %d", ret); + PDEBUG(D_ERR, "reg_r_1 err %d", ret); return 0; } - return data; + return gspca_dev->usb_buf[0]; } -/* returns: negative is error, pos or zero is data */ -static int reg_read(struct usb_device *dev, +/* read 1 or 2 bytes - returns < 0 if error */ +static int reg_r_12(struct gspca_dev *gspca_dev, __u16 req, /* bRequest */ __u16 index, /* wIndex */ __u16 length) /* wLength (1 or 2 only) */ { int ret; - __u8 buf[2]; - buf[1] = 0; - ret = usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + gspca_dev->usb_buf[1] = 0; + ret = usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ index, - buf, length, + gspca_dev->usb_buf, length, 500); if (ret < 0) { PDEBUG(D_ERR, "reg_read err %d", ret); return -1; } - return (buf[1] << 8) + buf[0]; + return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]; } static int write_vector(struct gspca_dev *gspca_dev, @@ -550,7 +550,7 @@ static int write_vector(struct gspca_dev *gspca_dev, int ret, i = 0; while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) { - ret = reg_write(dev, data[i][0], data[i][2], data[i][1]); + ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]); if (ret < 0) { PDEBUG(D_ERR, "Register write failed for 0x%x,0x%x,0x%x", @@ -573,14 +573,14 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev, /* loop over y components */ for (i = 0; i < 64; i++) { - err = reg_write(dev, request, ybase + i, qtable[0][i]); + err = reg_w_riv(dev, request, ybase + i, qtable[0][i]); if (err < 0) return err; } /* loop over c components */ for (i = 0; i < 64; i++) { - err = reg_write(dev, request, cbase + i, qtable[1][i]); + err = reg_w_riv(dev, request, cbase + i, qtable[1][i]); if (err < 0) return err; } @@ -593,14 +593,14 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev, struct usb_device *dev = gspca_dev->dev; __u8 notdone; - reg_write(dev, req, idx, val); - notdone = reg_read(dev, 0x01, 0x0001, 1); - reg_write(dev, req, idx, val); + reg_w_riv(dev, req, idx, val); + notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); + reg_w_riv(dev, req, idx, val); PDEBUG(D_FRAM, "before wait 0x%x", notdone); msleep(200); - notdone = reg_read(dev, 0x01, 0x0001, 1); + notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1); PDEBUG(D_FRAM, "after wait 0x%x", notdone); } @@ -612,8 +612,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, __u8 status; __u8 endcode; - reg_write(dev, req, idx, val); - status = reg_read(dev, 0x01, 0x0001, 1); + reg_w_riv(dev, req, idx, val); + status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); endcode = stat; PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat); if (!count) @@ -622,8 +622,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, while (--count > 0) { msleep(10); /* gsmart mini2 write a each wait setting 1 ms is enought */ -/* reg_write(dev, req, idx, val); */ - status = reg_read(dev, 0x01, 0x0001, 1); +/* reg_w_riv(dev, req, idx, val); */ + status = reg_r_12(gspca_dev, 0x01, 0x0001, 1); if (status == endcode) { PDEBUG(D_FRAM, "status 0x%x after wait 0x%x", status, 200 - count); @@ -632,34 +632,31 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev, } } -static int spca504B_PollingDataReady(struct usb_device *dev) +static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev) { - __u8 DataReady; int count = 10; while (--count > 0) { - spca5xxRegRead(dev, 0x21, 0, &DataReady, 1); - if ((DataReady & 0x01) == 0) + reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1); + if ((gspca_dev->usb_buf[0] & 0x01) == 0) break; msleep(10); } - return DataReady; + return gspca_dev->usb_buf[0]; } static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 DataReady; int count = 50; while (--count > 0) { - spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); - - if (DataReady) { - DataReady = 0; - spca5xxRegWrite(dev, 0x21, 0, 1, &DataReady, 1); - spca5xxRegRead(dev, 0x21, 1, &DataReady, 1); - spca504B_PollingDataReady(dev); + reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); + if (gspca_dev->usb_buf[0] != 0) { + gspca_dev->usb_buf[0] = 0; + reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1); + reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1); + spca504B_PollingDataReady(gspca_dev); break; } msleep(10); @@ -669,14 +666,15 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev) static void spca50x_GetFirmware(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 FW[5]; - __u8 ProductInfo[64]; + __u8 *data; - spca5xxRegRead(dev, 0x20, 0, FW, 5); + data = kmalloc(64, GFP_KERNEL); + reg_r(dev, 0x20, 0, data, 5); PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ", - FW[0], FW[1], FW[2], FW[3], FW[4]); - spca5xxRegRead(dev, 0x23, 0, ProductInfo, 64); - spca5xxRegRead(dev, 0x23, 1, ProductInfo, 64); + data[0], data[1], data[2], data[3], data[4]); + reg_r(dev, 0x23, 0, data, 64); + reg_r(dev, 0x23, 1, data, 64); + kfree(data); } static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) @@ -691,32 +689,35 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) Type = 0; switch (sd->bridge) { case BRIDGE_SPCA533: - spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); + reg_w(dev, 0x31, 0, 0, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); - rc = spca504B_PollingDataReady(dev); + rc = spca504B_PollingDataReady(gspca_dev); spca50x_GetFirmware(gspca_dev); - Type = 2; - spca5xxRegWrite(dev, 0x24, 0, 8, &Type, 1); - spca5xxRegRead(dev, 0x24, 8, &Type, 1); + gspca_dev->usb_buf[0] = 2; /* type */ + reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1); + reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1); - spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); - spca5xxRegRead(dev, 0x25, 4, &Size, 1); - rc = spca504B_PollingDataReady(dev); + gspca_dev->usb_buf[0] = Size; + reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); + reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ + rc = spca504B_PollingDataReady(gspca_dev); /* Init the cam width height with some values get on init ? */ - spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); + reg_w(dev, 0x31, 0, 4, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); - rc = spca504B_PollingDataReady(dev); + rc = spca504B_PollingDataReady(gspca_dev); break; default: /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA536: */ + gspca_dev->usb_buf[0] = Size; + reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1); + reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */ Type = 6; - spca5xxRegWrite(dev, 0x25, 0, 4, &Size, 1); - spca5xxRegRead(dev, 0x25, 4, &Size, 1); - spca5xxRegWrite(dev, 0x27, 0, 0, &Type, 1); - spca5xxRegRead(dev, 0x27, 0, &Type, 1); - rc = spca504B_PollingDataReady(dev); + gspca_dev->usb_buf[0] = Type; + reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1); + reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */ + rc = spca504B_PollingDataReady(gspca_dev); break; case BRIDGE_SPCA504: Size += 3; @@ -733,21 +734,20 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev) break; case BRIDGE_SPCA504C: /* capture mode */ - reg_write(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x0); - reg_write(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); + reg_w_riv(dev, 0xa0, (0x0500 | (Size & 0x0f)), 0x00); + reg_w_riv(dev, 0x20, 0x01, 0x0500 | (Size & 0x0f)); break; } } static void spca504_wait_status(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; int cnt; cnt = 256; while (--cnt > 0) { /* With this we get the status, when return 0 it's all ok */ - if (reg_read(dev, 0x06, 0x00, 1) == 0) + if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0) return; msleep(10); } @@ -756,11 +756,11 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev) static void spca504B_setQtable(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; - __u8 Data = 3; - spca5xxRegWrite(dev, 0x26, 0, 0, &Data, 1); - spca5xxRegRead(dev, 0x26, 0, &Data, 1); - spca504B_PollingDataReady(dev); + gspca_dev->usb_buf[0] = 3; + reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1); + reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1); + spca504B_PollingDataReady(gspca_dev); } static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) @@ -777,24 +777,24 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev) default: /* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA504B: */ - spca5xxRegWrite(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ - spca5xxRegWrite(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ - spca5xxRegWrite(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ - spca5xxRegWrite(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ - spca5xxRegWrite(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ - spca5xxRegWrite(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ + reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */ + reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */ + reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */ + reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */ + reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */ + reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */ break; case BRIDGE_SPCA536: - spca5xxRegWrite(dev, 0, 0, 0x20f0, NULL, 0); - spca5xxRegWrite(dev, 0, 0x21, 0x20f1, NULL, 0); - spca5xxRegWrite(dev, 0, 0x40, 0x20f5, NULL, 0); - spca5xxRegWrite(dev, 0, 1, 0x20f4, NULL, 0); - spca5xxRegWrite(dev, 0, 0x40, 0x20f6, NULL, 0); - spca5xxRegWrite(dev, 0, 0, 0x2089, NULL, 0); + reg_w(dev, 0, 0, 0x20f0, NULL, 0); + reg_w(dev, 0, 0x21, 0x20f1, NULL, 0); + reg_w(dev, 0, 0x40, 0x20f5, NULL, 0); + reg_w(dev, 0, 1, 0x20f4, NULL, 0); + reg_w(dev, 0, 0x40, 0x20f6, NULL, 0); + reg_w(dev, 0, 0, 0x2089, NULL, 0); break; } if (pollreg) - spca504B_PollingDataReady(dev); + spca504B_PollingDataReady(gspca_dev); } /* this function is called at probe time */ @@ -872,7 +872,8 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x504a: /* try to get the firmware as some cam answer 2.0.1.2.2 * and should be a spca504b then overwrite that setting */ - spca5xxRegRead(dev, 0x20, 0, &fw, 1); + reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); + fw = gspca_dev->usb_buf[0]; if (fw == 1) { sd->subtype = AiptekMiniPenCam13; sd->bridge = BRIDGE_SPCA504; @@ -1048,38 +1049,37 @@ static int sd_open(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; int rc; - __u8 Data; __u8 i; __u8 info[6]; int err_code; switch (sd->bridge) { case BRIDGE_SPCA504B: - spca5xxRegWrite(dev, 0x1d, 0, 0, NULL, 0); - spca5xxRegWrite(dev, 0, 1, 0x2306, NULL, 0); - spca5xxRegWrite(dev, 0, 0, 0x0d04, NULL, 0); - spca5xxRegWrite(dev, 0, 0, 0x2000, NULL, 0); - spca5xxRegWrite(dev, 0, 0x13, 0x2301, NULL, 0); - spca5xxRegWrite(dev, 0, 0, 0x2306, NULL, 0); + reg_w(dev, 0x1d, 0, 0, NULL, 0); + reg_w(dev, 0, 1, 0x2306, NULL, 0); + reg_w(dev, 0, 0, 0x0d04, NULL, 0); + reg_w(dev, 0, 0, 0x2000, NULL, 0); + reg_w(dev, 0, 0x13, 0x2301, NULL, 0); + reg_w(dev, 0, 0, 0x2306, NULL, 0); /* fall thru */ case BRIDGE_SPCA533: - rc = spca504B_PollingDataReady(dev); + rc = spca504B_PollingDataReady(gspca_dev); spca50x_GetFirmware(gspca_dev); break; case BRIDGE_SPCA536: spca50x_GetFirmware(gspca_dev); - spca5xxRegRead(dev, 0x00, 0x5002, &Data, 1); - Data = 0; - spca5xxRegWrite(dev, 0x24, 0, 0, &Data, 1); - spca5xxRegRead(dev, 0x24, 0, &Data, 1); - rc = spca504B_PollingDataReady(dev); - spca5xxRegWrite(dev, 0x34, 0, 0, NULL, 0); + reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1); + gspca_dev->usb_buf[0] = 0; + reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1); + reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1); + rc = spca504B_PollingDataReady(gspca_dev); + reg_w(dev, 0x34, 0, 0, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); break; case BRIDGE_SPCA504C: /* pccam600 */ PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)"); - reg_write(dev, 0xe0, 0x0000, 0x0000); - reg_write(dev, 0xe0, 0x0000, 0x0001); /* reset */ + reg_w_riv(dev, 0xe0, 0x0000, 0x0000); + reg_w_riv(dev, 0xe0, 0x0000, 0x0001); /* reset */ spca504_wait_status(gspca_dev); if (sd->subtype == LogitechClickSmart420) write_vector(gspca_dev, @@ -1100,7 +1100,7 @@ static int sd_open(struct gspca_dev *gspca_dev) if (sd->subtype == AiptekMiniPenCam13) { /*****************************/ for (i = 0; i < 6; i++) - info[i] = reg_read_info(dev, i); + info[i] = reg_r_1(gspca_dev, i); PDEBUG(D_STREAM, "Read info: %d %d %d %d %d %d." " Should be 1,0,2,2,0,0", @@ -1126,14 +1126,14 @@ static int sd_open(struct gspca_dev *gspca_dev) 6, 0, 0x86, 1); */ /* spca504A_acknowledged_command (gspca_dev, 0x24, 0, 0, 0x9D, 1); */ - reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ - reg_write(dev, 0x0, 0x2310, 0x5); + reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ + reg_w_riv(dev, 0x0, 0x2310, 0x05); spca504A_acknowledged_command(gspca_dev, 0x01, 0x0f, 0, 0xff, 0); } /* setup qtable */ - reg_write(dev, 0, 0x2000, 0); - reg_write(dev, 0, 0x2883, 1); + reg_w_riv(dev, 0, 0x2000, 0); + reg_w_riv(dev, 0, 0x2883, 1); err_code = spca50x_setup_qtable(gspca_dev, 0x00, 0x2800, 0x2840, @@ -1166,20 +1166,20 @@ static void sd_start(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA536: */ if (sd->subtype == MegapixV4 || sd->subtype == LogitechClickSmart820) { - spca5xxRegWrite(dev, 0xf0, 0, 0, NULL, 0); + reg_w(dev, 0xf0, 0, 0, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); - spca5xxRegRead(dev, 0xf0, 4, NULL, 0); + reg_r(dev, 0xf0, 4, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); } else { - spca5xxRegWrite(dev, 0x31, 0, 4, NULL, 0); + reg_w(dev, 0x31, 0, 4, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); - rc = spca504B_PollingDataReady(dev); + rc = spca504B_PollingDataReady(gspca_dev); } break; case BRIDGE_SPCA504: if (sd->subtype == AiptekMiniPenCam13) { for (i = 0; i < 6; i++) - info[i] = reg_read_info(dev, i); + info[i] = reg_r_1(gspca_dev, i); PDEBUG(D_STREAM, "Read info: %d %d %d %d %d %d." " Should be 1,0,2,2,0,0", @@ -1197,7 +1197,7 @@ static void sd_start(struct gspca_dev *gspca_dev) } else { spca504_acknowledged_command(gspca_dev, 0x24, 8, 3); for (i = 0; i < 6; i++) - info[i] = reg_read_info(dev, i); + info[i] = reg_r_1(gspca_dev, i); PDEBUG(D_STREAM, "Read info: %d %d %d %d %d %d." " Should be 1,0,2,2,0,0", @@ -1207,8 +1207,8 @@ static void sd_start(struct gspca_dev *gspca_dev) spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); } spca504B_SetSizeType(gspca_dev); - reg_write(dev, 0x0, 0x270c, 0x5); /* L92 sno1t.txt */ - reg_write(dev, 0x0, 0x2310, 0x5); + reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */ + reg_w_riv(dev, 0x0, 0x2310, 0x05); break; case BRIDGE_SPCA504C: if (sd->subtype == LogitechClickSmart420) { @@ -1217,13 +1217,13 @@ static void sd_start(struct gspca_dev *gspca_dev) } else { write_vector(gspca_dev, spca504_pccam600_init_data); } - enable = (sd->autogain ? 0x4 : 0x1); - reg_write(dev, 0x0c, 0x0000, enable); /* auto exposure */ - reg_write(dev, 0xb0, 0x0000, enable); /* auto whiteness */ + enable = (sd->autogain ? 0x04 : 0x01); + reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */ + reg_w_riv(dev, 0xb0, 0x0000, enable); /* auto whiteness */ /* set default exposure compensation and whiteness balance */ - reg_write(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ - reg_write(dev, 0x30, 0x0002, 1600); + reg_w_riv(dev, 0x30, 0x0001, 800); /* ~ 20 fps */ + reg_w_riv(dev, 0x30, 0x0002, 1600); spca504B_SetSizeType(gspca_dev); break; } @@ -1240,13 +1240,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA533: */ /* case BRIDGE_SPCA536: */ /* case BRIDGE_SPCA504B: */ - spca5xxRegWrite(dev, 0x31, 0, 0, NULL, 0); + reg_w(dev, 0x31, 0, 0, NULL, 0); spca504B_WaitCmdStatus(gspca_dev); - spca504B_PollingDataReady(dev); + spca504B_PollingDataReady(gspca_dev); break; case BRIDGE_SPCA504: case BRIDGE_SPCA504C: - reg_write(dev, 0x00, 0x2000, 0x0000); + reg_w_riv(dev, 0x00, 0x2000, 0x0000); if (sd->subtype == AiptekMiniPenCam13) { /* spca504a aiptek */ @@ -1258,7 +1258,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev) 0x0f, 0x00, 0xff, 1); } else { spca504_acknowledged_command(gspca_dev, 0x24, 0, 0); - reg_write(dev, 0x01, 0x000f, 0x0); + reg_w_riv(dev, 0x01, 0x000f, 0x00); } break; } @@ -1383,10 +1383,10 @@ static void setbrightness(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - reg_write(dev, 0x0, 0x21a7, sd->brightness); + reg_w_riv(dev, 0x0, 0x21a7, sd->brightness); break; case BRIDGE_SPCA536: - reg_write(dev, 0x0, 0x20f0, sd->brightness); + reg_w_riv(dev, 0x0, 0x20f0, sd->brightness); break; } } @@ -1394,7 +1394,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) static void getbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u16 brightness = 0; switch (sd->bridge) { @@ -1403,10 +1402,10 @@ static void getbrightness(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - brightness = reg_read(dev, 0x0, 0x21a7, 2); + brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2); break; case BRIDGE_SPCA536: - brightness = reg_read(dev, 0x0, 0x20f0, 2); + brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2); break; } sd->brightness = ((brightness & 0xff) - 128) % 255; @@ -1423,10 +1422,10 @@ static void setcontrast(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - reg_write(dev, 0x0, 0x21a8, sd->contrast); + reg_w_riv(dev, 0x0, 0x21a8, sd->contrast); break; case BRIDGE_SPCA536: - reg_write(dev, 0x0, 0x20f1, sd->contrast); + reg_w_riv(dev, 0x0, 0x20f1, sd->contrast); break; } } @@ -1434,7 +1433,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) static void getcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; switch (sd->bridge) { default: @@ -1442,10 +1440,10 @@ static void getcontrast(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - sd->contrast = reg_read(dev, 0x0, 0x21a8, 2); + sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2); break; case BRIDGE_SPCA536: - sd->contrast = reg_read(dev, 0x0, 0x20f1, 2); + sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2); break; } } @@ -1461,10 +1459,10 @@ static void setcolors(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - reg_write(dev, 0x0, 0x21ae, sd->colors); + reg_w_riv(dev, 0x0, 0x21ae, sd->colors); break; case BRIDGE_SPCA536: - reg_write(dev, 0x0, 0x20f6, sd->colors); + reg_w_riv(dev, 0x0, 0x20f6, sd->colors); break; } } @@ -1472,7 +1470,6 @@ static void setcolors(struct gspca_dev *gspca_dev) static void getcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; switch (sd->bridge) { default: @@ -1480,10 +1477,10 @@ static void getcolors(struct gspca_dev *gspca_dev) /* case BRIDGE_SPCA504B: */ /* case BRIDGE_SPCA504: */ /* case BRIDGE_SPCA504C: */ - sd->colors = reg_read(dev, 0x0, 0x21ae, 2) >> 1; + sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1; break; case BRIDGE_SPCA536: - sd->colors = reg_read(dev, 0x0, 0x20f6, 2) >> 1; + sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1; break; } } diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 299f84584e82..00f47e463a05 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -26,8 +26,8 @@ #define MODULE_NAME "t613" #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; #define MAX_GAMMA 0x10 /* 0 to 15 */ @@ -365,48 +365,49 @@ static const __u8 tas5130a_sensor_init[][8] = { {}, }; -static void t16RegRead(struct usb_device *dev, - __u16 index, __u8 *buffer, __u16 length) +/* read 1 byte */ +static int reg_r_1(struct gspca_dev *gspca_dev, + __u16 index) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0, /* request */ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, 500); + index, + gspca_dev->usb_buf, 1, 500); + return gspca_dev->usb_buf[0]; } -static void t16RegWrite(struct usb_device *dev, +static void reg_w(struct gspca_dev *gspca_dev, __u16 value, __u16 index, const __u8 *buffer, __u16 len) { if (buffer == NULL) { - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, index, NULL, 0, 500); return; } - if (len < 16) { - __u8 tmpbuf[16]; - - memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + if (len <= sizeof gspca_dev->usb_buf) { + memcpy(gspca_dev->usb_buf, buffer, len); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, index, - tmpbuf, len, 500); + gspca_dev->usb_buf, len, 500); } else { __u8 *tmpbuf; tmpbuf = kmalloc(len, GFP_KERNEL); memcpy(tmpbuf, buffer, len); - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), 0, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, value, index, @@ -443,8 +444,6 @@ static int sd_config(struct gspca_dev *gspca_dev, static int init_default_parameters(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - /* some of this registers are not really neded, because * they are overriden by setbrigthness, setcontrast, etc, * but wont hurt anyway, and can help someone with similar webcam @@ -509,49 +508,49 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) static const __u8 nset10[6] = { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 }; - t16RegWrite(dev, 0x01, 0x0000, n1, 0x06); - t16RegWrite(dev, 0x01, 0x0000, nset, 0x06); - t16RegRead(dev, 0x0063, &test_byte, 1); - t16RegWrite(dev, 0x01, 0x0000, n2, 0x02); + reg_w(gspca_dev, 0x01, 0x0000, n1, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset, 0x06); + reg_r_1(gspca_dev, 0x0063); + reg_w(gspca_dev, 0x01, 0x0000, n2, 0x02); while (read_indexs[i] != 0x00) { - t16RegRead(dev, read_indexs[i], &test_byte, 1); - PDEBUG(D_CONF, "Reg 0x%x => 0x%x", read_indexs[i], + test_byte = reg_r_1(gspca_dev, read_indexs[i]); + PDEBUG(D_CONF, "Reg 0x%02x => 0x%02x", read_indexs[i], test_byte); i++; } - t16RegWrite(dev, 0x01, 0x0000, n3, 0x06); - t16RegWrite(dev, 0x01, 0x0000, n4, 0x46); - t16RegRead(dev, 0x0080, &test_byte, 1); - t16RegWrite(dev, 0x00, 0x2c80, NULL, 0); - t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); - t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); - t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); - t16RegWrite(dev, 0x00, 0x3880, NULL, 0); - t16RegWrite(dev, 0x00, 0x3880, NULL, 0); - t16RegWrite(dev, 0x00, 0x338e, NULL, 0); - t16RegWrite(dev, 0x01, 0x0000, nset5, 0x04); - t16RegWrite(dev, 0x00, 0x00a9, NULL, 0); - t16RegWrite(dev, 0x01, 0x0000, nset6, 0x22); - t16RegWrite(dev, 0x00, 0x86bb, NULL, 0); - t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); - - t16RegWrite(dev, 0x01, 0x0000, missing, 0x08); - - t16RegWrite(dev, 0x00, 0x2087, NULL, 0); - t16RegWrite(dev, 0x00, 0x2088, NULL, 0); - t16RegWrite(dev, 0x00, 0x2089, NULL, 0); - - t16RegWrite(dev, 0x01, 0x0000, nset7, 0x04); - t16RegWrite(dev, 0x01, 0x0000, nset10, 0x06); - t16RegWrite(dev, 0x01, 0x0000, nset8, 0x06); - t16RegWrite(dev, 0x01, 0x0000, nset9, 0x04); - - t16RegWrite(dev, 0x00, 0x2880, NULL, 0); - t16RegWrite(dev, 0x01, 0x0000, nset2, 0x14); - t16RegWrite(dev, 0x01, 0x0000, nset3, 0x12); - t16RegWrite(dev, 0x01, 0x0000, nset4, 0x12); + reg_w(gspca_dev, 0x01, 0x0000, n3, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, n4, 0x46); + reg_r_1(gspca_dev, 0x0080); + reg_w(gspca_dev, 0x00, 0x2c80, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); + reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); + reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); + reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); + reg_w(gspca_dev, 0x00, 0x3880, NULL, 0); + reg_w(gspca_dev, 0x00, 0x338e, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset5, 0x04); + reg_w(gspca_dev, 0x00, 0x00a9, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset6, 0x22); + reg_w(gspca_dev, 0x00, 0x86bb, NULL, 0); + reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); + + reg_w(gspca_dev, 0x01, 0x0000, missing, 0x08); + + reg_w(gspca_dev, 0x00, 0x2087, NULL, 0); + reg_w(gspca_dev, 0x00, 0x2088, NULL, 0); + reg_w(gspca_dev, 0x00, 0x2089, NULL, 0); + + reg_w(gspca_dev, 0x01, 0x0000, nset7, 0x04); + reg_w(gspca_dev, 0x01, 0x0000, nset10, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset8, 0x06); + reg_w(gspca_dev, 0x01, 0x0000, nset9, 0x04); + + reg_w(gspca_dev, 0x00, 0x2880, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, nset2, 0x14); + reg_w(gspca_dev, 0x01, 0x0000, nset3, 0x12); + reg_w(gspca_dev, 0x01, 0x0000, nset4, 0x12); return 0; } @@ -559,7 +558,6 @@ static int init_default_parameters(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; unsigned int brightness; __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x80 }; brightness = sd->brightness; @@ -571,13 +569,12 @@ static void setbrightness(struct gspca_dev *gspca_dev) set6[3] = 0x00 + ((brightness - 7) * 0xa); } - t16RegWrite(dev, 0x01, 0x0000, set6, 4); + reg_w(gspca_dev, 0x01, 0x0000, set6, 4); } static void setflip(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 flipcmd[8] = { 0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09 }; @@ -585,15 +582,14 @@ static void setflip(struct gspca_dev *gspca_dev) if (sd->mirror == 1) flipcmd[3] = 0x01; - t16RegWrite(dev, 0x01, 0x0000, flipcmd, 8); + reg_w(gspca_dev, 0x01, 0x0000, flipcmd, 8); } static void seteffect(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; - t16RegWrite(dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); + reg_w(gspca_dev, 0x01, 0x0000, effects_table[sd->effect], 0x06); if (sd->effect == 1 || sd->effect == 5) { PDEBUG(D_CONF, "This effect have been disabled for webcam \"safety\""); @@ -601,15 +597,14 @@ static void seteffect(struct gspca_dev *gspca_dev) } if (sd->effect == 1 || sd->effect == 4) - t16RegWrite(dev, 0x00, 0x4aa6, NULL, 0); + reg_w(gspca_dev, 0x00, 0x4aa6, NULL, 0); else - t16RegWrite(dev, 0x00, 0xfaa6, NULL, 0); + reg_w(gspca_dev, 0x00, 0xfaa6, NULL, 0); } static void setwhitebalance(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 white_balance[8] = { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 }; @@ -617,25 +612,23 @@ static void setwhitebalance(struct gspca_dev *gspca_dev) if (sd->whitebalance == 1) white_balance[7] = 0x3c; - t16RegWrite(dev, 0x01, 0x0000, white_balance, 8); + reg_w(gspca_dev, 0x01, 0x0000, white_balance, 8); } static void setlightfreq(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 }; if (sd->freq == 2) /* 60hz */ freq[1] = 0x00; - t16RegWrite(dev, 0x1, 0x0000, freq, 0x4); + reg_w(gspca_dev, 0x1, 0x0000, freq, 0x4); } static void setcontrast(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; unsigned int contrast = sd->contrast; __u16 reg_to_write = 0x00; @@ -644,17 +637,16 @@ static void setcontrast(struct gspca_dev *gspca_dev) else reg_to_write = (0x00a9 + ((contrast - 7) * 0x200)); - t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } static void setcolors(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u16 reg_to_write; reg_to_write = 0xc0bb + sd->colors * 0x100; - t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } static void setgamma(struct gspca_dev *gspca_dev) @@ -664,12 +656,11 @@ static void setgamma(struct gspca_dev *gspca_dev) static void setsharpness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; __u16 reg_to_write; reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness; - t16RegWrite(dev, 0x00, reg_to_write, NULL, 0); + reg_w(gspca_dev, 0x00, reg_to_write, NULL, 0); } static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) @@ -837,13 +828,12 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val) static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; sd->autogain = val; if (val != 0) - t16RegWrite(dev, 0x00, 0xf48e, NULL, 0); + reg_w(gspca_dev, 0x00, 0xf48e, NULL, 0); else - t16RegWrite(dev, 0x00, 0xb48e, NULL, 0); + reg_w(gspca_dev, 0x00, 0xb48e, NULL, 0); return 0; } @@ -857,9 +847,7 @@ static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val) static void sd_start(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; int mode; - __u8 test_byte; static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 }; __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 }; @@ -886,21 +874,21 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } - t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); - t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); - t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); - t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[0], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[1], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[2], 0x8); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); /* just in case and to keep sync with logs (for mine) */ - t16RegWrite(dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); - t16RegWrite(dev, 0x00, 0x3c80, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, tas5130a_sensor_init[3], 0x8); + reg_w(gspca_dev, 0x00, 0x3c80, NULL, 0); /* just in case and to keep sync with logs (for mine) */ - t16RegWrite(dev, 0x01, 0x0000, t1, 4); - t16RegWrite(dev, 0x01, 0x0000, t2, 6); - t16RegRead(dev, 0x0012, &test_byte, 0x01); - t16RegWrite(dev, 0x01, 0x0000, t3, 0x10); - t16RegWrite(dev, 0x00, 0x0013, NULL, 0); - t16RegWrite(dev, 0x01, 0x0000, t4, 0x4); + reg_w(gspca_dev, 0x01, 0x0000, t1, 4); + reg_w(gspca_dev, 0x01, 0x0000, t2, 6); + reg_r_1(gspca_dev, 0x0012); + reg_w(gspca_dev, 0x01, 0x0000, t3, 0x10); + reg_w(gspca_dev, 0x00, 0x0013, NULL, 0); + reg_w(gspca_dev, 0x01, 0x0000, t4, 0x4); /* restart on each start, just in case, sometimes regs goes wrong * when using controls from app */ setbrightness(gspca_dev); diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index f9bffd67991e..0b793899095f 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -22,8 +22,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("TV8532 USB Camera Driver"); @@ -168,63 +168,74 @@ static const __u32 tv_8532_eeprom_data[] = { 0x0c0509f1, 0 }; -static void reg_r(struct usb_device *dev, - __u16 index, __u8 *buffer) +static int reg_r(struct gspca_dev *gspca_dev, + __u16 index) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), TV8532_REQ_RegRead, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, sizeof(__u8), + index, gspca_dev->usb_buf, 1, 500); + return gspca_dev->usb_buf[0]; } -static void reg_w(struct usb_device *dev, - __u16 index, __u8 *buffer, __u16 length) +/* write 1 byte */ +static void reg_w_1(struct gspca_dev *gspca_dev, + __u16 index, __u8 value) { - usb_control_msg(dev, - usb_sndctrlpipe(dev, 0), + gspca_dev->usb_buf[0] = value; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), TV8532_REQ_RegWrite, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, /* value */ - index, buffer, length, 500); + index, gspca_dev->usb_buf, 1, 500); +} + +/* write 2 bytes */ +static void reg_w_2(struct gspca_dev *gspca_dev, + __u16 index, __u8 val1, __u8 val2) +{ + gspca_dev->usb_buf[0] = val1; + gspca_dev->usb_buf[1] = val2; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + TV8532_REQ_RegWrite, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, /* value */ + index, gspca_dev->usb_buf, 2, 500); } static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev) { int i = 0; - __u8 reg, data0, data1, data2, datacmd; - struct usb_device *dev = gspca_dev->dev; + __u8 reg, data0, data1, data2; - datacmd = 0xb0;; - reg_w(dev, TV8532_GPIO, &datacmd, 1); - datacmd = TV8532_CMD_EEprom_Open; - reg_w(dev, TV8532_CTRL, &datacmd, 1); + reg_w_1(gspca_dev, TV8532_GPIO, 0xb0); + reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open); /* msleep(1); */ while (tv_8532_eeprom_data[i]) { reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24; - reg_w(dev, TV8532_EEprom_Add, ®, 1); + reg_w_1(gspca_dev, TV8532_EEprom_Add, reg); /* msleep(1); */ data0 = (tv_8532_eeprom_data[i] & 0x000000ff); - reg_w(dev, TV8532_EEprom_DataL, &data0, 1); + reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0); /* msleep(1); */ - data1 = (tv_8532_eeprom_data[i] & 0x0000FF00) >> 8; - reg_w(dev, TV8532_EEprom_DataM, &data1, 1); + data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8; + reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1); /* msleep(1); */ - data2 = (tv_8532_eeprom_data[i] & 0x00FF0000) >> 16; - reg_w(dev, TV8532_EEprom_DataH, &data2, 1); + data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16; + reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2); /* msleep(1); */ - datacmd = 0; - reg_w(dev, TV8532_EEprom_Write, &datacmd, 1); + reg_w_1(gspca_dev, TV8532_EEprom_Write, 0); /* msleep(10); */ i++; } - datacmd = i; - reg_w(dev, TV8532_EEprom_TableLength, &datacmd, 1); + reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i); /* msleep(1); */ - datacmd = TV8532_CMD_EEprom_Close; - reg_w(dev, TV8532_CTRL, &datacmd, 1); + reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close); msleep(10); } @@ -250,154 +261,121 @@ static int sd_config(struct gspca_dev *gspca_dev, static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; __u8 data; -/* __u16 vid, pid; */ - reg_r(dev, 0x0001, &data); + data = reg_r(gspca_dev, 0x0001); PDEBUG(D_USBI, "register 0x01-> %x", data); - reg_r(dev, 0x0002, &data); + data = reg_r(gspca_dev, 0x0002); PDEBUG(D_USBI, "register 0x02-> %x", data); - reg_r(dev, TV8532_ADWIDTH_L, &data); - reg_r(dev, TV8532_ADWIDTH_H, &data); - reg_r(dev, TV8532_QUANT_COMP, &data); - reg_r(dev, TV8532_MODE_PACKET, &data); - reg_r(dev, TV8532_SETCLK, &data); - reg_r(dev, TV8532_POINT_L, &data); - reg_r(dev, TV8532_POINT_H, &data); - reg_r(dev, TV8532_POINTB_L, &data); - reg_r(dev, TV8532_POINTB_H, &data); - reg_r(dev, TV8532_BUDGET_L, &data); - reg_r(dev, TV8532_BUDGET_H, &data); - reg_r(dev, TV8532_VID_L, &data); - reg_r(dev, TV8532_VID_H, &data); - reg_r(dev, TV8532_PID_L, &data); - reg_r(dev, TV8532_PID_H, &data); - reg_r(dev, TV8532_DeviceID, &data); - reg_r(dev, TV8532_AD_COLBEGIN_L, &data); - reg_r(dev, TV8532_AD_COLBEGIN_H, &data); - reg_r(dev, TV8532_AD_ROWBEGIN_L, &data); - reg_r(dev, TV8532_AD_ROWBEGIN_H, &data); + reg_r(gspca_dev, TV8532_ADWIDTH_L); + reg_r(gspca_dev, TV8532_ADWIDTH_H); + reg_r(gspca_dev, TV8532_QUANT_COMP); + reg_r(gspca_dev, TV8532_MODE_PACKET); + reg_r(gspca_dev, TV8532_SETCLK); + reg_r(gspca_dev, TV8532_POINT_L); + reg_r(gspca_dev, TV8532_POINT_H); + reg_r(gspca_dev, TV8532_POINTB_L); + reg_r(gspca_dev, TV8532_POINTB_H); + reg_r(gspca_dev, TV8532_BUDGET_L); + reg_r(gspca_dev, TV8532_BUDGET_H); + reg_r(gspca_dev, TV8532_VID_L); + reg_r(gspca_dev, TV8532_VID_H); + reg_r(gspca_dev, TV8532_PID_L); + reg_r(gspca_dev, TV8532_PID_H); + reg_r(gspca_dev, TV8532_DeviceID); + reg_r(gspca_dev, TV8532_AD_COLBEGIN_L); + reg_r(gspca_dev, TV8532_AD_COLBEGIN_H); + reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L); + reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H); } static void tv_8532_setReg(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 data; - __u8 value[2] = { 0, 0 }; - - data = ADCBEGINL; - reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ - data = ADCBEGINH; /* also digital gain */ - reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); - data = TV8532_CMD_UPDATE; - reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ - - data = 0x0a; - reg_w(dev, TV8532_GPIO_OE, &data, 1); + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, + ADCBEGINL); /* 0x10 */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, + ADCBEGINH); /* also digital gain */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ + + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a); /******************************************************/ - data = ADHEIGHL; - reg_w(dev, TV8532_ADHEIGHT_L, &data, 1); /* 0e */ - data = ADHEIGHH; - reg_w(dev, TV8532_ADHEIGHT_H, &data, 1); /* 0f */ - value[0] = EXPOL; - value[1] = EXPOH; /* 350d 0x014c; */ - reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ - data = ADCBEGINL; - reg_w(dev, TV8532_AD_COLBEGIN_L, &data, 1); /* 0x10 */ - data = ADCBEGINH; /* also digital gain */ - reg_w(dev, TV8532_AD_COLBEGIN_H, &data, 1); - data = ADRBEGINL; - reg_w(dev, TV8532_AD_ROWBEGIN_L, &data, 1); /* 0x14 */ - - data = 0x00; - reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ - data = 0x02; - reg_w(dev, TV8532_AD_BITCTRL, &data, 1); /* 0x94 */ - - - data = TV8532_CMD_EEprom_Close; - reg_w(dev, TV8532_CTRL, &data, 1); /* 0x01 */ - - data = 0x00; - reg_w(dev, TV8532_AD_SLOPE, &data, 1); /* 0x91 */ - data = TV8532_CMD_UPDATE; - reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */ + reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */ + reg_w_2(gspca_dev, TV8532_EXPOSURE, + EXPOL, EXPOH); /* 350d 0x014c; 1c */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L, + ADCBEGINL); /* 0x10 */ + reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H, + ADCBEGINH); /* also digital gain */ + reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L, + ADRBEGINL); /* 0x14 */ + + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */ + + reg_w_1(gspca_dev, TV8532_CTRL, + TV8532_CMD_EEprom_Close); /* 0x01 */ + + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ } static void tv_8532_PollReg(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 data; int i; /* strange polling from tgc */ for (i = 0; i < 10; i++) { - data = TESTCLK; /* 0x48; //0x08; */ - reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ - data = TV8532_CMD_UPDATE; - reg_w(dev, TV8532_PART_CTRL, &data, 1); - data = 0x01; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ } } /* this function is called at open time */ static int sd_open(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 data; - __u8 dataStart; - __u8 value[2]; - - data = 0x32; - reg_w(dev, TV8532_AD_SLOPE, &data, 1); - data = 0; - reg_w(dev, TV8532_AD_BITCTRL, &data, 1); + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); tv_8532ReadRegisters(gspca_dev); - data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, 1); - value[0] = ADHEIGHL; - value[1] = ADHEIGHH; /* 401d 0x0169; */ - reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ - value[0] = EXPOL; - value[1] = EXPOH; /* 350d 0x014c; */ - reg_w(dev, TV8532_EXPOSURE, value, 2); /* 1c */ - data = ADWIDTHL; /* 0x20; */ - reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ - data = ADWIDTHH; - reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL, + ADHEIGHH); /* 401d 0x0169; 0e */ + reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL, + EXPOH); /* 350d 0x014c; 1c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ /*******************************************************************/ - data = TESTCOMP; /* 0x72 compressed mode */ - reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ - data = TESTLINE; /* 0x84; // CIF | 4 packet */ - reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + reg_w_1(gspca_dev, TV8532_QUANT_COMP, + TESTCOMP); /* 0x72 compressed mode 0x28 */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ /************************************************/ - data = TESTCLK; /* 0x48; //0x08; */ - reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ - data = TESTPTL; /* 0x38; */ - reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ - data = TESTPTH; /* 0x04; */ - reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ - dataStart = TESTPTBL; /* 0x04; */ - reg_w(dev, TV8532_POINTB_L, &dataStart, 1); /* 0x2f */ - data = TESTPTBH; /* 0x04; */ - reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ - data = TV8532_CMD_UPDATE; - reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_POINT_L, + TESTPTL); /* 0x38; 0x2d */ + reg_w_1(gspca_dev, TV8532_POINT_H, + TESTPTH); /* 0x04; 0x2e */ + reg_w_1(gspca_dev, TV8532_POINTB_L, + TESTPTBL); /* 0x04; 0x2f */ + reg_w_1(gspca_dev, TV8532_POINTB_H, + TESTPTBH); /* 0x04; 0x30 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ /*************************************************/ - data = 0x01; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ msleep(200); - data = 0x00; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ - data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, 1); + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); /*************************************************/ tv_8532_setReg(gspca_dev); /*************************************************/ @@ -408,94 +386,72 @@ static int sd_open(struct gspca_dev *gspca_dev) static void setbrightness(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 value[2]; - __u8 data; int brightness = sd->brightness; - value[1] = (brightness >> 8) & 0xff; - value[0] = (brightness) & 0xff; - reg_w(gspca_dev->dev, TV8532_EXPOSURE, value, 2); /* 1c */ - data = TV8532_CMD_UPDATE; - reg_w(gspca_dev->dev, TV8532_PART_CTRL, &data, 1); + reg_w_2(gspca_dev, TV8532_EXPOSURE, + brightness >> 8, brightness); /* 1c */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE); } /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 data; - __u8 value[2]; - - data = 0x32; - reg_w(dev, TV8532_AD_SLOPE, &data, 1); - data = 0; - reg_w(dev, TV8532_AD_BITCTRL, &data, 1); + reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32); + reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00); tv_8532ReadRegisters(gspca_dev); - data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, 1); - value[0] = ADHEIGHL; - value[1] = ADHEIGHH; /* 401d 0x0169; */ - reg_w(dev, TV8532_ADHEIGHT_L, value, 2); /* 0e */ -/* value[0] = EXPOL; value[1] =EXPOH; * 350d 0x014c; */ -/* reg_w(dev,TV8532_REQ_RegWrite,0,TV8532_EXPOSURE,value,2); * 1c */ + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); + reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, + ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */ +/* reg_w_2(gspca_dev, TV8532_EXPOSURE, + EXPOL, EXPOH); * 350d 0x014c; 1c */ setbrightness(gspca_dev); - data = ADWIDTHL; /* 0x20; */ - reg_w(dev, TV8532_ADWIDTH_L, &data, 1); /* 0x0c */ - data = ADWIDTHH; - reg_w(dev, TV8532_ADWIDTH_H, &data, 1); /* 0x0d */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */ + reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */ /************************************************/ - data = TESTCOMP; /* 0x72 compressed mode */ - reg_w(dev, TV8532_QUANT_COMP, &data, 1); /* 0x28 */ + reg_w_1(gspca_dev, TV8532_QUANT_COMP, + TESTCOMP); /* 0x72 compressed mode 0x28 */ if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) { /* 176x144 */ - data = QCIFLINE; /* 0x84; // CIF | 4 packet */ - reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */ } else { /* 352x288 */ - data = TESTLINE; /* 0x84; // CIF | 4 packet */ - reg_w(dev, TV8532_MODE_PACKET, &data, 1); /* 0x29 */ + reg_w_1(gspca_dev, TV8532_MODE_PACKET, + TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */ } /************************************************/ - data = TESTCLK; /* 0x48; //0x08; */ - reg_w(dev, TV8532_SETCLK, &data, 1); /* 0x2c */ - data = TESTPTL; /* 0x38; */ - reg_w(dev, TV8532_POINT_L, &data, 1); /* 0x2d */ - data = TESTPTH; /* 0x04; */ - reg_w(dev, TV8532_POINT_H, &data, 1); /* 0x2e */ - data = TESTPTBL; /* 0x04; */ - reg_w(dev, TV8532_POINTB_L, &data, 1); /* 0x2f */ - data = TESTPTBH; /* 0x04; */ - reg_w(dev, TV8532_POINTB_H, &data, 1); /* 0x30 */ - data = TV8532_CMD_UPDATE; - reg_w(dev, TV8532_PART_CTRL, &data, 1); /* 0x00<-0x84 */ + reg_w_1(gspca_dev, TV8532_SETCLK, + TESTCLK); /* 0x48; //0x08; 0x2c */ + reg_w_1(gspca_dev, TV8532_POINT_L, + TESTPTL); /* 0x38; 0x2d */ + reg_w_1(gspca_dev, TV8532_POINT_H, + TESTPTH); /* 0x04; 0x2e */ + reg_w_1(gspca_dev, TV8532_POINTB_L, + TESTPTBL); /* 0x04; 0x2f */ + reg_w_1(gspca_dev, TV8532_POINTB_H, + TESTPTBH); /* 0x04; 0x30 */ + reg_w_1(gspca_dev, TV8532_PART_CTRL, + TV8532_CMD_UPDATE); /* 0x00<-0x84 */ /************************************************/ - data = 0x01; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */ msleep(200); - data = 0x00; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ - data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, 1); + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); /************************************************/ tv_8532_setReg(gspca_dev); /************************************************/ tv_8532_PollReg(gspca_dev); - data = 0x00; - reg_w(dev, TV8532_UDP_UPDATE, &data, 1); /* 0x31 */ + reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */ } static void sd_stopN(struct gspca_dev *gspca_dev) { - struct usb_device *dev = gspca_dev->dev; - __u8 data; - - data = 0x0b; - reg_w(dev, TV8532_GPIO_OE, &data, 1); + reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b); } static void sd_stop0(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 668e024aaa8f..dd7c1389f38d 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -1227,17 +1227,18 @@ static const struct sensor_info sensor_info_data[] = { {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01}, }; -static void reg_r(struct usb_device *dev, - __u16 req, - __u16 index, - __u8 *buffer, __u16 length) +/* read 'len' bytes in gspca_dev->usb_buf */ +static void reg_r(struct gspca_dev *gspca_dev, + __u16 req, + __u16 index, + __u16 len) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), req, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 1, /* value */ - index, buffer, length, + index, gspca_dev->usb_buf, len, 500); } @@ -1254,55 +1255,55 @@ static void reg_w(struct usb_device *dev, 500); } -static void vc032x_read_sensor_register(struct usb_device *dev, +static void read_sensor_register(struct gspca_dev *gspca_dev, __u16 address, __u16 *value) { + struct usb_device *dev = gspca_dev->dev; __u8 ldata, mdata, hdata; - __u8 tmpvalue = 0; int retry = 50; - ldata = 0; - mdata = 0; - hdata = 0; + *value = 0; - reg_r(dev, 0xa1, 0xb33f, &tmpvalue, 1); + reg_r(gspca_dev, 0xa1, 0xb33f, 1); /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */ - if (!(tmpvalue & 0x02)) { - PDEBUG(D_ERR, "I2c Bus Busy Wait %d", tmpvalue & 0x02); + if (!(gspca_dev->usb_buf[0] & 0x02)) { + PDEBUG(D_ERR, "I2c Bus Busy Wait %d", + gspca_dev->usb_buf[0] & 0x02); return; } reg_w(dev, 0xa0, address, 0xb33a); reg_w(dev, 0xa0, 0x02, 0xb339); - tmpvalue = 0; - reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); - while (retry-- && tmpvalue) { - reg_r(dev, 0xa1, 0xb33b, &tmpvalue, 1); + reg_r(gspca_dev, 0xa1, 0xb33b, 1); + while (retry-- && gspca_dev->usb_buf[0]) { + reg_r(gspca_dev, 0xa1, 0xb33b, 1); /* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */ msleep(1); } - reg_r(dev, 0xa1, 0xb33e, &hdata, 1); - reg_r(dev, 0xa1, 0xb33d, &mdata, 1); - reg_r(dev, 0xa1, 0xb33c, &ldata, 1); + reg_r(gspca_dev, 0xa1, 0xb33e, 1); + hdata = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0xa1, 0xb33d, 1); + mdata = gspca_dev->usb_buf[0]; + reg_r(gspca_dev, 0xa1, 0xb33c, 1); + ldata = gspca_dev->usb_buf[0]; PDEBUG(D_PROBE, "Read Sensor h (0x%02X) m (0x%02X) l (0x%02X)", hdata, mdata, ldata); - tmpvalue = 0; - reg_r(dev, 0xa1, 0xb334, &tmpvalue, 1); - if (tmpvalue == 0x02) + reg_r(gspca_dev, 0xa1, 0xb334, 1); + if (gspca_dev->usb_buf[0] == 0x02) *value = (ldata << 8) + mdata; else *value = ldata; } + static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) { struct usb_device *dev = gspca_dev->dev; int i; - __u8 data; __u16 value; const struct sensor_info *ptsensor_info; - reg_r(dev, 0xa1, 0xbfcf, &data, 1); - PDEBUG(D_PROBE, "check sensor header %d", data); + reg_r(gspca_dev, 0xa1, 0xbfcf, 1); + PDEBUG(D_PROBE, "check sensor header %d", gspca_dev->usb_buf[0]); for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) { ptsensor_info = &sensor_info_data[i]; reg_w(dev, 0xa0, 0x02, 0xb334); @@ -1315,7 +1316,7 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) "check sensor VC032X -> %d Add -> ox%02X!", i, ptsensor_info->I2cAdd); */ reg_w(dev, 0xa0, ptsensor_info->op, 0xb301); - vc032x_read_sensor_register(dev, ptsensor_info->IdAdd, &value); + read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value); if (value == ptsensor_info->VpId) { /* PDEBUG(D_PROBE, "find sensor VC032X -> ox%04X!", ptsensor_info->VpId); */ @@ -1325,14 +1326,14 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev) return -1; } -static __u8 i2c_write(struct usb_device *dev, +static __u8 i2c_write(struct gspca_dev *gspca_dev, __u8 reg, const __u8 *val, __u8 size) { - __u8 retbyte; + struct usb_device *dev = gspca_dev->dev; if (size > 3 || size < 1) return -EINVAL; - reg_r(dev, 0xa1, 0xb33f, &retbyte, 1); + reg_r(gspca_dev, 0xa1, 0xb33f, 1); reg_w(dev, 0xa0, size, 0xb334); reg_w(dev, 0xa0, reg, 0xb33a); switch (size) { @@ -1353,8 +1354,8 @@ static __u8 i2c_write(struct usb_device *dev, return -EINVAL; } reg_w(dev, 0xa0, 0x01, 0xb339); - reg_r(dev, 0xa1, 0xb33b, &retbyte, 1); - return retbyte == 0; + reg_r(gspca_dev, 0xa1, 0xb33b, 1); + return gspca_dev->usb_buf[0] == 0; } static void put_tab_to_reg(struct gspca_dev *gspca_dev, @@ -1382,10 +1383,10 @@ static void usb_exchange(struct gspca_dev *gspca_dev, ((data[i][0])<<8) | data[i][1]); break; case 0xaa: /* i2c op */ - i2c_write(dev, data[i][1], &data[i][2], 1); + i2c_write(gspca_dev, data[i][1], &data[i][2], 1); break; case 0xbb: /* i2c op */ - i2c_write(dev, data[i][0], &data[i][1], 2); + i2c_write(gspca_dev, data[i][0], &data[i][1], 2); break; case 0xdd: msleep(data[i][2] + 10); @@ -1417,7 +1418,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; struct cam *cam; - __u8 tmp2[4]; int sensor; __u16 product; @@ -1488,10 +1488,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->lightfreq = FREQ_DEF; if (sd->bridge == BRIDGE_VC0321) { - reg_r(dev, 0x8a, 0, tmp2, 3); + reg_r(gspca_dev, 0x8a, 0, 3); reg_w(dev, 0x87, 0x00, 0x0f0f); - reg_r(dev, 0x8b, 0, tmp2, 3); + reg_r(gspca_dev, 0x8b, 0, 3); reg_w(dev, 0x88, 0x00, 0x0202); } return 0; @@ -1525,7 +1525,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; -/* __u8 tmp2; */ const __u8 *GammaT = NULL; const __u8 *MatrixT = NULL; int mode; @@ -1627,7 +1626,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824); */ /* Only works for HV7131R ?? - reg_r (gspca_dev->dev, 0xa1, 0xb881, &tmp2, 1); + reg_r (gspca_dev, 0xa1, 0xb881, 1); reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881); reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801); */ diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index bac45a193653..548c4c8c3f33 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) -static const char version[] = "2.1.5"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) +static const char version[] = "2.1.7"; MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); @@ -6214,23 +6214,27 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { {} }; -static void reg_r_i(struct usb_device *dev, - __u16 index, __u8 *buffer) +static int reg_r_i(struct gspca_dev *gspca_dev, + __u16 index) { - usb_control_msg(dev, - usb_rcvctrlpipe(dev, 0), + usb_control_msg(gspca_dev->dev, + usb_rcvctrlpipe(gspca_dev->dev, 0), 0xa1, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x01, /* value */ - index, buffer, 1, + index, gspca_dev->usb_buf, 1, 500); + return gspca_dev->usb_buf[0]; } -static void reg_r(struct usb_device *dev, - __u16 index, __u8 *buffer) +static int reg_r(struct gspca_dev *gspca_dev, + __u16 index) { - reg_r_i(dev, index, buffer); - PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, *buffer); + int ret; + + ret = reg_r_i(gspca_dev, index); + PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret); + return ret; } static void reg_w_i(struct usb_device *dev, @@ -6253,55 +6257,54 @@ static void reg_w(struct usb_device *dev, reg_w_i(dev, value, index); } -static __u16 i2c_read(struct usb_device *dev, __u8 reg) +static __u16 i2c_read(struct gspca_dev *gspca_dev, + __u8 reg) { __u8 retbyte; __u8 retval[2]; - reg_w_i(dev, reg, 0x92); - reg_w_i(dev, 0x02, 0x90); /* <- read command */ + reg_w_i(gspca_dev->dev, reg, 0x92); + reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */ msleep(25); - reg_r_i(dev, 0x0091, &retbyte); /* read status */ - reg_r_i(dev, 0x0095, &retval[0]); /* read Lowbyte */ - reg_r_i(dev, 0x0096, &retval[1]); /* read Hightbyte */ + retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ + retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ + retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */ PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x", reg, retbyte, retval[1], retval[0]); return (retval[1] << 8) | retval[0]; } -static __u8 i2c_write(struct usb_device *dev, +static __u8 i2c_write(struct gspca_dev *gspca_dev, __u8 reg, __u8 valL, __u8 valH) { __u8 retbyte; - reg_w_i(dev, reg, 0x92); - reg_w_i(dev, valL, 0x93); - reg_w_i(dev, valH, 0x94); - reg_w_i(dev, 0x01, 0x90); /* <- write command */ + reg_w_i(gspca_dev->dev, reg, 0x92); + reg_w_i(gspca_dev->dev, valL, 0x93); + reg_w_i(gspca_dev->dev, valH, 0x94); + reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ msleep(5); - reg_r_i(dev, 0x0091, &retbyte); /* read status */ + retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)", reg, valH, valL, retbyte); return retbyte; } -static void usb_exchange(struct usb_device *dev, +static void usb_exchange(struct gspca_dev *gspca_dev, const struct usb_action *action) { - __u8 buffread; - while (action->req) { switch (action->req) { case 0xa0: /* write register */ - reg_w(dev, action->val, action->idx); + reg_w(gspca_dev->dev, action->val, action->idx); break; case 0xa1: /* read status */ - reg_r(dev, action->idx, &buffread); + reg_r(gspca_dev, action->idx); break; case 0xaa: - i2c_write(dev, + i2c_write(gspca_dev, action->val, /* reg */ action->idx & 0xff, /* valL */ action->idx >> 8); /* valH */ @@ -6376,7 +6379,6 @@ static void setsharpness(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; int sharpness; - __u8 retbyte; static const __u8 sharpness_tb[][2] = { {0x02, 0x03}, {0x04, 0x07}, @@ -6386,9 +6388,9 @@ static void setsharpness(struct gspca_dev *gspca_dev) sharpness = sd->sharpness; reg_w(dev, sharpness_tb[sharpness][0], 0x01c6); - reg_r(dev, 0x01c8, &retbyte); - reg_r(dev, 0x01c9, &retbyte); - reg_r(dev, 0x01ca, &retbyte); + reg_r(gspca_dev, 0x01c8); + reg_r(gspca_dev, 0x01c9); + reg_r(gspca_dev, 0x01ca); reg_w(dev, sharpness_tb[sharpness][1], 0x01cb); } @@ -6398,7 +6400,7 @@ static void setcontrast(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; const __u8 *Tgamma, *Tgradient; int g, i, k; - static const __u8 kgamma_tb[16] = /* delta for contrast */ + static const __u8 kgamma_tb[16] = /* delta for contrast */ {0x15, 0x0d, 0x0a, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; static const __u8 kgrad_tb[16] = @@ -6623,7 +6625,7 @@ static int setlightfreq(struct gspca_dev *gspca_dev) i++; /* 640x480 */ zc3_freq = freq_tb[(int) sd->sensor][i]; if (zc3_freq != NULL) { - usb_exchange(gspca_dev->dev, zc3_freq); + usb_exchange(gspca_dev, zc3_freq); switch (sd->sensor) { case SENSOR_GC0305: if (mode /* if 320x240 */ @@ -6687,44 +6689,45 @@ static void start_2wr_probe(struct usb_device *dev, int sensor) /* msleep(2); */ } -static int sif_probe(struct usb_device *dev) +static int sif_probe(struct gspca_dev *gspca_dev) { __u16 checkword; - start_2wr_probe(dev, 0x0f); /* PAS106 */ - reg_w(dev, 0x08, 0x008d); + start_2wr_probe(gspca_dev->dev, 0x0f); /* PAS106 */ + reg_w(gspca_dev->dev, 0x08, 0x008d); msleep(150); - checkword = ((i2c_read(dev, 0x00) & 0x0f) << 4) - | ((i2c_read(dev, 0x01) & 0xf0) >> 4); + checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4) + | ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4); PDEBUG(D_PROBE, "probe sif 0x%04x", checkword); if (checkword == 0x0007) { - send_unknown(dev, SENSOR_PAS106); + send_unknown(gspca_dev->dev, SENSOR_PAS106); return 0x0f; /* PAS106 */ } return -1; } -static int vga_2wr_probe(struct usb_device *dev) +static int vga_2wr_probe(struct gspca_dev *gspca_dev) { + struct usb_device *dev = gspca_dev->dev; __u8 retbyte; __u16 checkword; start_2wr_probe(dev, 0x00); /* HV7131B */ - i2c_write(dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(dev, 0x01); + i2c_write(gspca_dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) return 0x00; /* HV7131B */ start_2wr_probe(dev, 0x04); /* CS2102 */ - i2c_write(dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(dev, 0x01); + i2c_write(gspca_dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) return 0x04; /* CS2102 */ start_2wr_probe(dev, 0x06); /* OmniVision */ reg_w(dev, 0x08, 0x8d); - i2c_write(dev, 0x11, 0xaa, 0x00); - retbyte = i2c_read(dev, 0x11); + i2c_write(gspca_dev, 0x11, 0xaa, 0x00); + retbyte = i2c_read(gspca_dev, 0x11); if (retbyte != 0) { /* (should have returned 0xaa) --> Omnivision? */ /* reg_r 0x10 -> 0x06 --> */ @@ -6732,45 +6735,45 @@ static int vga_2wr_probe(struct usb_device *dev) } start_2wr_probe(dev, 0x08); /* HDCS2020 */ - i2c_write(dev, 0x15, 0xaa, 0x00); - retbyte = i2c_read(dev, 0x15); + i2c_write(gspca_dev, 0x15, 0xaa, 0x00); + retbyte = i2c_read(gspca_dev, 0x15); if (retbyte != 0) return 0x08; /* HDCS2020 */ start_2wr_probe(dev, 0x0a); /* PB0330 */ - i2c_write(dev, 0x07, 0xaa, 0xaa); - retbyte = i2c_read(dev, 0x07); + i2c_write(gspca_dev, 0x07, 0xaa, 0xaa); + retbyte = i2c_read(gspca_dev, 0x07); if (retbyte != 0) return 0x0a; /* PB0330 */ - retbyte = i2c_read(dev, 0x03); + retbyte = i2c_read(gspca_dev, 0x03); if (retbyte != 0) return 0x0a; /* PB0330 ?? */ - retbyte = i2c_read(dev, 0x04); + retbyte = i2c_read(gspca_dev, 0x04); if (retbyte != 0) return 0x0a; /* PB0330 ?? */ start_2wr_probe(dev, 0x0c); /* ICM105A */ - i2c_write(dev, 0x01, 0x11, 0x00); - retbyte = i2c_read(dev, 0x01); + i2c_write(gspca_dev, 0x01, 0x11, 0x00); + retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) return 0x0c; /* ICM105A */ start_2wr_probe(dev, 0x0e); /* PAS202BCB */ reg_w(dev, 0x08, 0x8d); - i2c_write(dev, 0x03, 0xaa, 0x00); + i2c_write(gspca_dev, 0x03, 0xaa, 0x00); msleep(500); - retbyte = i2c_read(dev, 0x03); + retbyte = i2c_read(gspca_dev, 0x03); if (retbyte != 0) return 0x0e; /* PAS202BCB */ start_2wr_probe(dev, 0x02); /* ?? */ - i2c_write(dev, 0x01, 0xaa, 0x00); - retbyte = i2c_read(dev, 0x01); + i2c_write(gspca_dev, 0x01, 0xaa, 0x00); + retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) return 0x02; /* ?? */ ov_check: - reg_r(dev, 0x0010, &retbyte); /* ?? */ - reg_r(dev, 0x0010, &retbyte); + reg_r(gspca_dev, 0x0010); /* ?? */ + reg_r(gspca_dev, 0x0010); reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x01, 0x0001); @@ -6779,10 +6782,10 @@ ov_check: reg_w(dev, 0x08, 0x008d); msleep(500); reg_w(dev, 0x01, 0x0012); - i2c_write(dev, 0x12, 0x80, 0x00); /* sensor reset */ - retbyte = i2c_read(dev, 0x0a); + i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */ + retbyte = i2c_read(gspca_dev, 0x0a); checkword = retbyte << 8; - retbyte = i2c_read(dev, 0x0b); + retbyte = i2c_read(gspca_dev, 0x0b); checkword |= retbyte; PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword); switch (checkword) { @@ -6821,7 +6824,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ reg_w(dev, 0x02, 0x0010); - reg_r(dev, 0x10, &retbyte); + reg_r(gspca_dev, 0x10); reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x00, 0x0010); reg_w(dev, 0x01, 0x0001); @@ -6829,23 +6832,23 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - retbyte = i2c_read(dev, 0x14); + retbyte = i2c_read(gspca_dev, 0x14); if (retbyte != 0) return 0x11; /* HV7131R */ - retbyte = i2c_read(dev, 0x15); + retbyte = i2c_read(gspca_dev, 0x15); if (retbyte != 0) return 0x11; /* HV7131R */ - retbyte = i2c_read(dev, 0x16); + retbyte = i2c_read(gspca_dev, 0x16); if (retbyte != 0) return 0x11; /* HV7131R */ reg_w(dev, 0x02, 0x0010); - reg_r(dev, 0x000b, &retbyte); + retbyte = reg_r(gspca_dev, 0x000b); checkword = retbyte << 8; - reg_r(dev, 0x000a, &retbyte); + retbyte = reg_r(gspca_dev, 0x000a); checkword |= retbyte; PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); - reg_r(dev, 0x0010, &retbyte); + reg_r(gspca_dev, 0x0010); /* this is tested only once anyway */ i = 0; while (chipset_revision_sensor[i].revision) { @@ -6863,7 +6866,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x0a, 0x0010); reg_w(dev, 0x03, 0x0012); reg_w(dev, 0x01, 0x0012); - retbyte = i2c_read(dev, 0x00); + retbyte = i2c_read(gspca_dev, 0x00); if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); return 0x0a; /* ?? */ @@ -6876,7 +6879,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x03, 0x0012); msleep(2); reg_w(dev, 0x01, 0x0012); - retbyte = i2c_read(dev, 0x00); + retbyte = i2c_read(gspca_dev, 0x00); if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); send_unknown(dev, SENSOR_GC0305); @@ -6890,8 +6893,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x06, 0x0010); reg_w(dev, 0x01, 0x0012); reg_w(dev, 0x05, 0x0012); - if (i2c_read(dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ - && i2c_read(dev, 0x1d) == 0xa2) { + if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */ + && i2c_read(gspca_dev, 0x1d) == 0xa2) { send_unknown(dev, SENSOR_OV7620); return 0x06; /* OmniVision confirm ? */ } @@ -6905,13 +6908,13 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /* msleep(150); */ reg_w(dev, 0x01, 0x12); reg_w(dev, 0x05, 0x12); - retbyte = i2c_read(dev, 0x00); /* ID 0 */ + retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */ checkword = retbyte << 8; - retbyte = i2c_read(dev, 0x01); /* ID 1 */ + retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */ checkword |= retbyte; PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); if (checkword == 0x2030) { - retbyte = i2c_read(dev, 0x02); /* revision number */ + retbyte = i2c_read(gspca_dev, 0x02); /* revision number */ PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte); send_unknown(dev, SENSOR_PO2030); return checkword; @@ -6925,7 +6928,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) reg_w(dev, 0x01, 0x12); reg_w(dev, 0x05, 0x01); reg_w(dev, 0xd3, 0x8b); - retbyte = i2c_read(dev, 0x01); + retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); return 0x0a; /* ?? */ @@ -6936,7 +6939,6 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) static int zcxx_probeSensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - struct usb_device *dev = gspca_dev->dev; int sensor, sensor2; switch (sd->sensor) { @@ -6944,7 +6946,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) case SENSOR_TAS5130C_VF0250: return -1; /* don't probe */ } - sensor = vga_2wr_probe(dev); + sensor = vga_2wr_probe(gspca_dev); if (sensor >= 0) { if (sensor < 0x7600) return sensor; @@ -6956,7 +6958,7 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) return sensor; return sensor2; } - return sif_probe(dev); + return sif_probe(gspca_dev); } /* this function is called at probe time */ @@ -6966,7 +6968,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; int sensor; - __u8 bsensor; int vga = 1; /* 1: vga, 0: sif */ static const __u8 gamma[SENSOR_MAX] = { 5, /* SENSOR_CS2102 0 */ @@ -7122,7 +7123,7 @@ static int sd_config(struct gspca_dev *gspca_dev, reg_w(gspca_dev->dev, 0x02, 0x0010); else reg_w(gspca_dev->dev, sensor & 0x0f, 0x0010); - reg_r(gspca_dev->dev, 0x0010, &bsensor); + reg_r(gspca_dev, 0x0010); } cam = &gspca_dev->cam; @@ -7163,7 +7164,6 @@ static void sd_start(struct gspca_dev *gspca_dev) struct usb_device *dev = gspca_dev->dev; const struct usb_action *zc3_init; int mode; - __u8 retbyte; static const struct usb_action *init_tb[SENSOR_MAX][2] = { {cs2102_InitialScale, cs2102_Initial}, /* 0 */ {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */ @@ -7194,7 +7194,7 @@ static void sd_start(struct gspca_dev *gspca_dev) zcxx_probeSensor(gspca_dev); break; case SENSOR_PAS106: - usb_exchange(dev, pas106b_Initial_com); + usb_exchange(gspca_dev, pas106b_Initial_com); break; case SENSOR_PB0330: if (mode) { @@ -7210,14 +7210,14 @@ static void sd_start(struct gspca_dev *gspca_dev) } break; } - usb_exchange(dev, zc3_init); + usb_exchange(gspca_dev, zc3_init); switch (sd->sensor) { case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: msleep(100); /* ?? */ - reg_r(dev, 0x0002, &retbyte); /* --> 0x40 */ + reg_r(gspca_dev, 0x0002); /* --> 0x40 */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ reg_w(dev, 0x15, 0x01ae); reg_w(dev, 0x0d, 0x003a); @@ -7230,11 +7230,11 @@ static void sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); switch (sd->sensor) { case SENSOR_OV7620: - reg_r(dev, 0x0008, &retbyte); + reg_r(gspca_dev, 0x0008); reg_w(dev, 0x00, 0x0008); break; case SENSOR_GC0305: - reg_r(dev, 0x0008, &retbyte); + reg_r(gspca_dev, 0x0008); /* fall thru */ case SENSOR_PO2030: reg_w(dev, 0x03, 0x0008); @@ -7259,7 +7259,7 @@ static void sd_start(struct gspca_dev *gspca_dev) setmatrix(gspca_dev); /* one more time? */ switch (sd->sensor) { case SENSOR_OV7620: - reg_r(dev, 0x0180, &retbyte); /* from win */ + reg_r(gspca_dev, 0x0180); /* from win */ reg_w(dev, 0x00, 0x0180); break; default: @@ -7277,7 +7277,7 @@ static void sd_start(struct gspca_dev *gspca_dev) break; case SENSOR_PO2030: reg_w(dev, 0x40, 0x0117); /* (from win traces) */ - reg_r(dev, 0x0180, &retbyte); + reg_r(gspca_dev, 0x0180); break; } @@ -7289,22 +7289,23 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(dev, 0x15, 0x01ae); reg_w(dev, 0x40, 0x0180); reg_w(dev, 0x40, 0x0117); - reg_r(dev, 0x0180, &retbyte); + reg_r(gspca_dev, 0x0180); sd->autogain = 1; setautogain(gspca_dev); break; case SENSOR_OV7620: - i2c_read(dev, 0x13); /*fixme: returns 0xa3 */ - i2c_write(dev, 0x13, 0xa3, 0x00); /*fixme: same to send? */ + i2c_read(gspca_dev, 0x13); /*fixme: returns 0xa3 */ + i2c_write(gspca_dev, 0x13, 0xa3, 0x00); + /*fixme: returned value to send? */ reg_w(dev, 0x40, 0x0117); /* (from win traces) */ - reg_r(dev, 0x0180, &retbyte); + reg_r(gspca_dev, 0x0180); setautogain(gspca_dev); msleep(500); break; case SENSOR_PO2030: msleep(500); - reg_r(dev, 0x0008, &retbyte); - reg_r(dev, 0x0007, &retbyte); + reg_r(gspca_dev, 0x0008); + reg_r(gspca_dev, 0x0007); reg_w(dev, 0x00, 0x0007); /* (from win traces) */ reg_w(dev, 0x02, 0x0008); break; -- cgit v1.2.3 From 4b972d29bbccc86877221164c7f39d52694d4a81 Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Mon, 14 Jul 2008 09:50:26 -0300 Subject: V4L/DVB (8353): gspca: 640x480 for bridge sn9c103 / sensor ov7630. sonixb: 640x480 mode for sn9c103 - ov7630. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index ce8b28f504d3..cfa62aef4700 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -278,8 +278,14 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ }; -static const __u8 ov7630_sensor_init_3[][8] = { - {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ +static const __u8 ov7630_sensor_init_3[][5][8] = { + { {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ + {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16}, + {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ + {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d}, + }, + { {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16}, {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16}, {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ @@ -287,6 +293,7 @@ static const __u8 ov7630_sensor_init_3[][8] = { * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */ /* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */ {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d}, + } }; static const __u8 initPas106[] = { @@ -730,6 +737,11 @@ static int sd_config(struct gspca_dev *gspca_dev, if (!sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + if (sd->sensor == SENSOR_OV7630_3) { + /* We only have 320x240 & 640x480 */ + cam->cam_mode++; + cam->nmodes--; + } } else { cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); @@ -877,8 +889,8 @@ static void sd_start(struct gspca_dev *gspca_dev) i2c_w_vector(gspca_dev, ov7630_sensor_init_com, sizeof ov7630_sensor_init_com); msleep(200); - i2c_w_vector(gspca_dev, ov7630_sensor_init_3, - sizeof ov7630_sensor_init_3); + i2c_w_vector(gspca_dev, ov7630_sensor_init_3[mode], + sizeof ov7630_sensor_init_3[mode]); break; case SENSOR_PAS106: pas106_i2cinit(gspca_dev); -- cgit v1.2.3 From ad5ef80dd79851ea683e2d30ca4ebdc0c043a675 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 14 Jul 2008 10:11:42 -0300 Subject: V4L/DVB (8354): gspca: Better gain for bridge sn9c10x - sensor ov6650. sonixb: Better gain for ov6650. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index cfa62aef4700..6c97c8356d7f 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -39,8 +39,8 @@ struct sd { sensor, so we use a per cam copy */ atomic_t avg_lum; - unsigned short gain; - unsigned short exposure; + unsigned char gain; + unsigned char exposure; unsigned char brightness; unsigned char autogain; unsigned char autogain_ignore_frames; @@ -73,7 +73,7 @@ struct sd { ignore atleast the 2 next frames for the new settings to come into effect before doing any other adjustments */ #define AUTOGAIN_IGNORE_FRAMES 3 -#define AUTOGAIN_DEADZONE 500 +#define AUTOGAIN_DEADZONE 1000 #define DESIRED_AVG_LUM 7000 /* V4L2 controls supported by the driver */ @@ -107,10 +107,10 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Gain", .minimum = 0, - .maximum = 511, + .maximum = 255, .step = 1, -#define GAIN_DEF 255 -#define GAIN_KNEE 400 +#define GAIN_DEF 127 +#define GAIN_KNEE 200 .default_value = GAIN_DEF, }, .set = sd_setgain, @@ -122,9 +122,9 @@ static struct ctrl sd_ctrls[] = { .type = V4L2_CTRL_TYPE_INTEGER, .name = "Exposure", #define EXPOSURE_DEF 0 -#define EXPOSURE_KNEE 353 /* 10 fps */ +#define EXPOSURE_KNEE 176 /* 10 fps */ .minimum = 0, - .maximum = 511, + .maximum = 255, .step = 1, .default_value = EXPOSURE_DEF, .flags = 0, @@ -563,11 +563,6 @@ err: static void setsensorgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - unsigned short gain; - - gain = (sd->gain + 1) >> 1; - if (gain > 255) - gain = 255; switch (sd->sensor) { @@ -575,14 +570,15 @@ static void setsensorgain(struct gspca_dev *gspca_dev) __u8 i2c[] = {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; - i2c[4] = 255 - gain; + i2c[4] = 255 - sd->gain; if (i2c_w(gspca_dev, i2c) < 0) goto err; break; } case SENSOR_OV6650: { __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[3] = gain; + + i2c[3] = sd->gain >> 3; if (i2c_w(gspca_dev, i2c) < 0) goto err; break; @@ -599,7 +595,7 @@ static void setgain(struct gspca_dev *gspca_dev) __u8 gain; __u8 rgb_value; - gain = sd->gain >> 5; + gain = sd->gain >> 4; /* red and blue gain */ rgb_value = gain << 4 | gain; @@ -616,7 +612,7 @@ static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; /* translate 0 - 255 to a number of fps in a 30 - 1 scale */ - int fps = 30 - sd->exposure * 29 / 511; + int fps = 30 - sd->exposure * 29 / 255; switch (sd->sensor) { case SENSOR_TAS5110: { -- cgit v1.2.3 From 3647fea840c94c04f35215cb75b48613c0af310e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 15 Jul 2008 05:36:30 -0300 Subject: V4L/DVB (8356): gspca: 352x288 mode fix and source clean-up for Sonix bridges. sonixb: Bad initialization of sensor for 352x288 mode. (from Hans de Goede) sonixj: Clean-up source. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 4 +- drivers/media/video/gspca/gspca.c | 2 +- drivers/media/video/gspca/sonixb.c | 7 +- drivers/media/video/gspca/sonixj.c | 148 ++++++++++++++---------------------- 4 files changed, 65 insertions(+), 96 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 6e68cdeb29d3..24f55a0cc027 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -199,11 +199,11 @@ vc032x 0ac8:c002 Sony embedded vimicro spca508 0af9:0010 Hama USB Sightcam 100 spca508 0af9:0011 Hama USB Sightcam 100 sonixb 0c45:6001 Genius VideoCAM NB -sonixb 0c45:6005 Sweex Tas5110 +sonixb 0c45:6005 Microdia Sweex Mini Webcam sonixb 0c45:6007 Sonix sn9c101 + Tas5110D sonixb 0c45:6009 spcaCam@120 sonixb 0c45:600d spcaCam@120 -sonixb 0c45:6011 MAX Webcam (Microdia - OV6650 - SN9C101G) +sonixb 0c45:6011 Microdia PC Camera (SN9C102) sonixb 0c45:6019 Generic Sonix OV7630 sonixb 0c45:6024 Generic Sonix Tas5130c sonixb 0c45:6025 Xcam Shanga diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 242f0fb68d6e..16e367cec760 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -168,7 +168,7 @@ static void isoc_irq(struct urb *urb { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; - PDEBUG(D_PACK, "isoc irq mmap"); + PDEBUG(D_PACK, "isoc irq"); if (!gspca_dev->streaming) return; fill_frame(gspca_dev, urb); diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 6c97c8356d7f..c0ce21fe85f7 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -244,7 +244,7 @@ static const __u8 initOv7630_3[] = { 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */ 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */ - 0x16, 0x12, /* H & V sizes r15 .. r16 */ + 0x28, 0x1e, /* H & V sizes r15 .. r16 */ 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */ 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */ 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ @@ -785,7 +785,6 @@ static void sd_start(struct gspca_dev *gspca_dev) const __u8 *sn9c10x; __u8 reg01, reg17; __u8 reg17_19[3]; - static const __u8 reg15[2] = { 0x28, 0x1e }; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; switch (sd->sensor) { @@ -905,8 +904,8 @@ static void sd_start(struct gspca_dev *gspca_dev) sizeof tas5130_sensor_init); break; } - /* H_size V_size 0x28, 0x1e maybe 640x480 */ - reg_w(gspca_dev, 0x15, reg15, 2); + /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */ + reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); /* compression register */ reg_w(gspca_dev, 0x18, ®17_19[1], 1); if (sd->sensor != SENSOR_OV7630_3) { diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 30e840dca481..93d4746ff95a 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -47,20 +47,19 @@ struct sd { #define AG_CNT_START 13 char qindex; + unsigned char bridge; +#define BRIDGE_SN9C102P 0 +#define BRIDGE_SN9C105 1 +#define BRIDGE_SN9C110 2 +#define BRIDGE_SN9C120 3 +#define BRIDGE_SN9C325 4 char sensor; /* Type of image sensor chip */ #define SENSOR_HV7131R 0 #define SENSOR_MI0360 1 #define SENSOR_MO4000 2 #define SENSOR_OV7648 3 #define SENSOR_OV7660 4 - unsigned char customid; -#define SN9C102P 0 -#define SN9C105 1 -#define SN9C110 2 -#define SN9C120 3 -#define SN9C325 4 unsigned char i2c_base; - unsigned char i2c_ctrl_reg; }; /* V4L2 controls supported by the driver */ @@ -563,7 +562,7 @@ static void i2c_w2(struct gspca_dev *gspca_dev, __u8 mode[8]; /* is i2c ready */ - mode[0] = sd->i2c_ctrl_reg | (2 << 4); + mode[0] = 0x81 | (2 << 4); mode[1] = sd->i2c_base; mode[2] = buffer[0]; mode[3] = buffer[1]; @@ -588,7 +587,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) struct sd *sd = (struct sd *) gspca_dev; __u8 mode[8]; - mode[0] = sd->i2c_ctrl_reg | 0x10; + mode[0] = 0x81 | 0x10; mode[1] = sd->i2c_base; mode[2] = reg; mode[3] = 0; @@ -597,7 +596,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) mode[6] = 0; mode[7] = 0x10; i2c_w8(gspca_dev, mode); - mode[0] = sd->i2c_ctrl_reg | (5 << 4) | 0x02; + mode[0] = 0x81 | (5 << 4) | 0x02; mode[2] = 0; i2c_w8(gspca_dev, mode); reg_r(gspca_dev, 0x0a, 5); @@ -658,11 +657,11 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 3); - switch (sd->customid) { - case SN9C325: + switch (sd->bridge) { + case BRIDGE_SN9C325: reg9a = reg9a_sn9c325; break; - case SN9C120: + case BRIDGE_SN9C120: reg9a = reg9a_sn9c120; break; default: @@ -676,8 +675,8 @@ static int configure_gpio(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); - switch (sd->customid) { - case SN9C120: /* from win trace */ + switch (sd->bridge) { + case BRIDGE_SN9C120: /* from win trace */ data = 0x61; reg_w(gspca_dev, 0x01, &data, 1); data = 0x20; @@ -685,7 +684,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev, data = 0x60; reg_w(gspca_dev, 0x01, &data, 1); break; - case SN9C325: + case BRIDGE_SN9C325: data = 0x43; reg_w(gspca_dev, 0x01, &data, 1); data = 0xae; @@ -778,9 +777,8 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x0458: /* Genius */ /* switch (product) { case 0x7025: */ - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_MI0360; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x5d; /* break; } */ @@ -789,9 +787,8 @@ static int sd_config(struct gspca_dev *gspca_dev, /* switch (product) { case 0x00f5: case 0x00f7: */ - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_OV7660; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; /* break; } */ @@ -801,9 +798,8 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x0327: case 0x0328: case 0x0330: */ - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_MI0360; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x5d; /* break; } */ @@ -811,161 +807,135 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x0c45: /* Sonix */ switch (product) { case 0x6040: - sd->customid = SN9C102P; + sd->bridge = BRIDGE_SN9C102P; sd->sensor = SENSOR_MI0360; /* from BW600.inf */ /* sd->sensor = SENSOR_HV7131R; * gspcav1 value */ - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x11; break; /* case 0x607a: * from BW600.inf - sd->customid = SN9C102P; + sd->bridge = BRIDGE_SN9C102P; sd->sensor = SENSOR_OV7648; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x607c: - sd->customid = SN9C102P; + sd->bridge = BRIDGE_SN9C102P; sd->sensor = SENSOR_HV7131R; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x11; break; /* case 0x607e: * from BW600.inf - sd->customid = SN9C102P; + sd->bridge = BRIDGE_SN9C102P; sd->sensor = SENSOR_OV7630; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x60c0: - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_MI0360; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x5d; break; /* case 0x60c8: * from BW600.inf - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_OM6801; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ /* case 0x60cc: * from BW600.inf - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_HV7131GP; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x60ec: - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_MO4000; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; /* case 0x60ef: * from BW600.inf - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_ICM105C; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ /* case 0x60fa: * from BW600.inf - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_OV7648; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x60fb: - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_OV7660; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; case 0x60fc: - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_HV7131R; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x11; break; /* case 0x60fe: * from BW600.inf - sd->customid = SN9C105; + sd->bridge = BRIDGE_SN9C105; sd->sensor = SENSOR_OV7630; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ /* case 0x6108: * from BW600.inf - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_OM6801; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ /* case 0x6122: * from BW600.inf - sd->customid = SN9C110; + sd->bridge = BRIDGE_SN9C110; sd->sensor = SENSOR_ICM105C; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x612a: -/* sd->customid = SN9C110; * in BW600.inf */ - sd->customid = SN9C325; +/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ + sd->bridge = BRIDGE_SN9C325; sd->sensor = SENSOR_OV7648; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; /* case 0x6123: * from BW600.inf - sd->customid = SN9C110; + sd->bridge = BRIDGE_SN9C110; sd->sensor = SENSOR_SanyoCCD; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x612c: - sd->customid = SN9C110; + sd->bridge = BRIDGE_SN9C110; sd->sensor = SENSOR_MO4000; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; /* case 0x612e: * from BW600.inf - sd->customid = SN9C110; + sd->bridge = BRIDGE_SN9C110; sd->sensor = SENSOR_OV7630; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ /* case 0x612f: * from BW600.inf - sd->customid = SN9C110; + sd->bridge = BRIDGE_SN9C110; sd->sensor = SENSOR_ICM105C; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x6130: - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_MI0360; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x5d; break; case 0x6138: - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_MO4000; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; /* case 0x613a: * from BW600.inf - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_OV7648; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ case 0x613b: - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_OV7660; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x21; break; case 0x613c: - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_HV7131R; - sd->i2c_ctrl_reg = 0x81; sd->i2c_base = 0x11; break; /* case 0x613e: * from BW600.inf - sd->customid = SN9C120; + sd->bridge = BRIDGE_SN9C120; sd->sensor = SENSOR_OV7630; - sd->i2c_ctrl_reg = 0x??; sd->i2c_base = 0x??; break; */ } @@ -999,7 +969,7 @@ static int sd_open(struct gspca_dev *gspca_dev) __u8 regF1; __u8 regGpio[] = { 0x29, 0x74 }; - /* setup a selector by customid */ + /* setup a selector by bridge */ regF1 = 0x01; reg_w(gspca_dev, 0xf1, ®F1, 1); reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ @@ -1007,31 +977,31 @@ static int sd_open(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xf1, ®F1, 1); reg_r(gspca_dev, 0x00, 1); regF1 = gspca_dev->usb_buf[0]; - switch (sd->customid) { - case SN9C102P: + switch (sd->bridge) { + case BRIDGE_SN9C102P: if (regF1 != 0x11) return -ENODEV; reg_w(gspca_dev, 0x02, ®Gpio[1], 1); break; - case SN9C105: + case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; reg_w(gspca_dev, 0x02, regGpio, 2); break; - case SN9C110: + case BRIDGE_SN9C110: if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x62; reg_w(gspca_dev, 0x02, ®Gpio[1], 1); break; - case SN9C120: + case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x70; reg_w(gspca_dev, 0x02, regGpio, 2); break; default: -/* case SN9C325: */ +/* case BRIDGE_SN9C325: */ if (regF1 != 0x12) return -ENODEV; regGpio[1] = 0x62; @@ -1207,7 +1177,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xc9, &DC29[5], 1); /*fixme:jfm end of ending sequence */ reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); - if (sd->customid == SN9C325) + if (sd->bridge == BRIDGE_SN9C325) data = 0xae; else data = 0x60; @@ -1216,7 +1186,7 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1); reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1); reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1); - if (sd->customid == SN9C325) { + if (sd->bridge == BRIDGE_SN9C325) { reg_w(gspca_dev, 0x20, regsn20_sn9c325, 0x11); for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84_sn9c325, 0x15); @@ -1285,17 +1255,17 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } reg_w(gspca_dev, 0xc0, C0, 6); - switch (sd->customid) { - case SN9C120: /*jfm ?? */ + switch (sd->bridge) { + case BRIDGE_SN9C120: /*jfm ?? */ reg_w(gspca_dev, 0xca, CA_sn9c120, 4); break; default: reg_w(gspca_dev, 0xca, CA, 4); break; } - switch (sd->customid) { - case SN9C120: /*jfm ?? */ - case SN9C325: + switch (sd->bridge) { + case BRIDGE_SN9C120: /*jfm ?? */ + case BRIDGE_SN9C325: reg_w(gspca_dev, 0xce, CE_sn9c325, 4); break; default: -- cgit v1.2.3 From f4d520258d229f093bec6937ec3d632eb95600b4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 15 Jul 2008 09:36:42 -0300 Subject: V4L/DVB (8357): gspca: Perfect exposure for sn9c10x, sensor ov6650. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 54 ++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index c0ce21fe85f7..7303df0dc16b 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -121,8 +121,8 @@ static struct ctrl sd_ctrls[] = { .id = V4L2_CID_EXPOSURE, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Exposure", -#define EXPOSURE_DEF 0 -#define EXPOSURE_KNEE 176 /* 10 fps */ +#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */ +#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */ .minimum = 0, .maximum = 255, .step = 1, @@ -611,8 +611,6 @@ static void setgain(struct gspca_dev *gspca_dev) static void setexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - /* translate 0 - 255 to a number of fps in a 30 - 1 scale */ - int fps = 30 - sd->exposure * 29 / 255; switch (sd->sensor) { case SENSOR_TAS5110: { @@ -621,19 +619,53 @@ static void setexposure(struct gspca_dev *gspca_dev) /* register 19's high nibble contains the sn9c10x clock divider The high nibble configures the no fps according to the formula: 60 / high_nibble. With a maximum of 30 fps */ - reg = 60 / fps; - if (reg > 15) + reg = 120 * sd->exposure / 1000; + if (reg < 2) + reg = 2; + else if (reg > 15) reg = 15; reg = (reg << 4) | 0x0b; reg_w(gspca_dev, 0x19, ®, 1); break; } case SENSOR_OV6650: { - __u8 i2c[] = {0xa0, 0x60, 0x11, 0xc0, 0x00, 0x00, 0x00, 0x10}; - i2c[3] = 30 / fps - 1; - if (i2c[3] > 15) - i2c[3] = 15; - i2c[3] |= 0xc0; + /* The ov6650 has 2 registers which both influence exposure, + first there is register 11, whose low nibble sets the no fps + according to: fps = 30 / (low_nibble + 1) + + The fps configures the maximum exposure setting, but it is + possible to use less exposure then what the fps maximum + allows by setting register 10. register 10 configures the + actual exposure as quotient of the full exposure, with 0 + being no exposure at all (not very usefull) and reg10_max + being max exposure possible at that framerate. + + The code maps our 0 - 510 ms exposure ctrl to these 2 + registers, trying to keep fps as high as possible. + */ + __u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; + int reg10, reg11; + /* No clear idea why, but setting reg10 above this value + results in no change */ + const int reg10_max = 0x4d; + + reg11 = (60 * sd->exposure + 999) / 1000; + if (reg11 < 1) + reg11 = 1; + else if (reg11 > 16) + reg11 = 16; + + /* frame exposure time in ms = 1000 * reg11 / 30 -> + reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ + reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); + if (reg10 < 1) /* 0 is a valid value, but is very _black_ */ + reg10 = 1; + else if (reg10 > reg10_max) + reg10 = reg10_max; + + /* Write reg 10 and reg11 low nibble */ + i2c[3] = reg10; + i2c[4] |= reg11 - 1; if (i2c_w(gspca_dev, i2c) < 0) PDEBUG(D_ERR, "i2c error exposure"); break; -- cgit v1.2.3 From 568788a771ee88cc6b5e311a207c09731a6e47f0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 15 Jul 2008 11:46:06 -0300 Subject: V4L/DVB (8358): gspca: Better initialization of sn9c120 - ov7660. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 125 +++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 40 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 93d4746ff95a..3e68b9926956 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -151,36 +151,36 @@ static struct v4l2_pix_format vga_mode[] = { /*Data from sn9c102p+hv71331r */ static const __u8 sn_hv7131[] = { - 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ - 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ + 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11, /* rega regb regc regd rege regf reg10 reg11 */ - 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, + 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */ /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00, /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_mi0360[] = { - 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */ - 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, + 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d, /* rega regb regc regd rege regf reg10 reg11 */ - 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00, /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const __u8 sn_mo4000[] = { - 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */ - 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81, /* reg9 rega regb regc regd rege regf reg10 reg11*/ - 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, + 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00, /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b, 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7, 0xd3, 0xdf, 0xea, 0xf5 }; @@ -197,7 +197,7 @@ static const __u8 sn_ov7660[] = { /* reg9 rega regb regc regd rege regf reg10 reg11*/ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/ - 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20, 0x07, 0x00, 0x00, + 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00, /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; @@ -215,6 +215,10 @@ static const __u8 regsn20[] = { 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99, 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff }; +static const __u8 regsn20_sn9c120[] = { + 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90, + 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff +}; static const __u8 regsn20_sn9c325[] = { 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4, 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5 @@ -226,6 +230,21 @@ static const __u8 reg84[] = { /* 0x00, 0x00, 0x00, 0x00, 0x00 */ 0xf7, 0x0f, 0x0a, 0x00, 0x00 }; +static const __u8 reg84_sn9c120_1[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00 +}; +static const __u8 reg84_sn9c120_2[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x02, 0x3b +}; +static const __u8 reg84_sn9c120_3[] = { + 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f, + 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f, + 0xf5, 0x0f, 0x0c, 0x02, 0x3b +}; static const __u8 reg84_sn9c325[] = { 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f, 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f, @@ -345,17 +364,15 @@ static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, /* Outformat ?? rawRGB */ {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ -/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, - * GAIN BLUE RED VREF */ - {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, + {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10}, +/* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */ /* GAIN BLUE RED VREF */ {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10}, /* COM 1 BAVE GEAVE AECHH */ {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */ {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */ -/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, - * AECH CLKRC COM7 COM8 */ - {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, + {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10}, +/* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */ /* AECH CLKRC COM7 COM8 */ {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */ {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10}, @@ -364,9 +381,8 @@ static const __u8 ov7660_sensor_init[][8] = { {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */ {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10}, /* BOS GBOS GROS ROS (BGGR offset) */ -/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, - * AEW AEB VPT BBIAS */ - {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, + {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, +/* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */ /* AEW AEB VPT BBIAS */ {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10}, /* GbBIAS RSVD EXHCH EXHCL */ @@ -416,14 +432,15 @@ static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */ {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, - {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, -/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, */ +/* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */ + {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10}, + {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, /****** (some exchanges in the win trace) ******/ {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */ {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */ {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, -/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, */ + {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, /****** (some exchanges in the win trace) ******/ /**********startsensor KO if changed !!****/ {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10}, @@ -649,14 +666,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev, regF1 = 0x00; reg_w(gspca_dev, 0xf1, ®F1, 1); - - reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); - /*fixme:jfm was [1] en v1*/ + reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ /* configure gpio */ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); - reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 3); + reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm was 3 */ switch (sd->bridge) { case BRIDGE_SN9C325: reg9a = reg9a_sn9c325; @@ -808,8 +823,9 @@ static int sd_config(struct gspca_dev *gspca_dev, switch (product) { case 0x6040: sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_MI0360; /* from BW600.inf */ -/* sd->sensor = SENSOR_HV7131R; * gspcav1 value */ +/* sd->sensor = SENSOR_MI0360; * from BW600.inf */ +/*fixme: MI0360 base=5d ? */ + sd->sensor = SENSOR_HV7131R; /* gspcav1 value */ sd->i2c_base = 0x11; break; /* case 0x607a: * from BW600.inf @@ -883,10 +899,11 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->i2c_base = 0x??; break; */ case 0x612a: -/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ +/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ sd->bridge = BRIDGE_SN9C325; sd->sensor = SENSOR_OV7648; sd->i2c_base = 0x21; +/*fixme: sensor_init has base = 00 et 6e!*/ break; /* case 0x6123: * from BW600.inf sd->bridge = BRIDGE_SN9C110; @@ -1177,31 +1194,59 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0xc9, &DC29[5], 1); /*fixme:jfm end of ending sequence */ reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); - if (sd->bridge == BRIDGE_SN9C325) + switch (sd->bridge) { + case BRIDGE_SN9C325: data = 0xae; - else + break; + case BRIDGE_SN9C120: + data = 0xa0; + break; + default: data = 0x60; + break; + } reg_w(gspca_dev, 0x17, &data, 1); reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1); reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1); reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1); reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1); - if (sd->bridge == BRIDGE_SN9C325) { - reg_w(gspca_dev, 0x20, regsn20_sn9c325, 0x11); + switch (sd->bridge) { + case BRIDGE_SN9C325: + reg_w(gspca_dev, 0x20, regsn20_sn9c325, + sizeof regsn20_sn9c325); for (i = 0; i < 8; i++) - reg_w(gspca_dev, 0x84, reg84_sn9c325, 0x15); + reg_w(gspca_dev, 0x84, reg84_sn9c325, + sizeof reg84_sn9c325); data = 0x0a; reg_w(gspca_dev, 0x9a, &data, 1); data = 0x60; reg_w(gspca_dev, 0x99, &data, 1); - } else { - reg_w(gspca_dev, 0x20, regsn20, 0x11); + break; + case BRIDGE_SN9C120: + reg_w(gspca_dev, 0x20, regsn20_sn9c120, + sizeof regsn20_sn9c120); + for (i = 0; i < 2; i++) + reg_w(gspca_dev, 0x84, reg84_sn9c120_1, + sizeof reg84_sn9c120_1); + for (i = 0; i < 6; i++) + reg_w(gspca_dev, 0x84, reg84_sn9c120_2, + sizeof reg84_sn9c120_2); + reg_w(gspca_dev, 0x84, reg84_sn9c120_3, + sizeof reg84_sn9c120_3); + data = 0x05; + reg_w(gspca_dev, 0x9a, &data, 1); + data = 0x5b; + reg_w(gspca_dev, 0x99, &data, 1); + break; + default: + reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); for (i = 0; i < 8; i++) - reg_w(gspca_dev, 0x84, reg84, 0x15); + reg_w(gspca_dev, 0x84, reg84, sizeof reg84); data = 0x08; reg_w(gspca_dev, 0x9a, &data, 1); data = 0x59; reg_w(gspca_dev, 0x99, &data, 1); + break; } mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; -- cgit v1.2.3 From 9a97a2abe44781a13cd2ffc95069a8fd2678da68 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 15 Jul 2008 14:23:08 -0300 Subject: V4L/DVB (8359): gspca: Adds register aliases for zc03xx registers Thanks to http://zc0302.sourceforge.net/zc0302.php, we have some hints about what each zc3xx register means. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Jean-Francois Moine --- drivers/media/video/gspca/zc3xx-reg.h | 261 ++ drivers/media/video/gspca/zc3xx.c | 8167 +++++++++++++++++---------------- 2 files changed, 4354 insertions(+), 4074 deletions(-) create mode 100644 drivers/media/video/gspca/zc3xx-reg.h (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h new file mode 100644 index 000000000000..f52e09c2cc19 --- /dev/null +++ b/drivers/media/video/gspca/zc3xx-reg.h @@ -0,0 +1,261 @@ +/* + * zc030x registers + * + * Copyright (c) 2008 Mauro Carvalho Chehab + * + * The register aliases used here came from this driver: + * http://zc0302.sourceforge.net/zc0302.php + * + * This code is placed under the terms of the GNU General Public License v2 + */ + +/* Define the register map */ +#define ZC3XX_R000_SYSTEMCONTROL 0x0000 +#define ZC3XX_R001_SYSTEMOPERATING 0x0001 + +/* Picture size */ +#define ZC3XX_R002_CLOCKSELECT 0x0002 +#define ZC3XX_R003_FRAMEWIDTHHIGH 0x0003 +#define ZC3XX_R004_FRAMEWIDTHLOW 0x0004 +#define ZC3XX_R005_FRAMEHEIGHTHIGH 0x0005 +#define ZC3XX_R006_FRAMEHEIGHTLOW 0x0006 + +/* JPEG control */ +#define ZC3XX_R008_CLOCKSETTING 0x0008 + +/* Test mode */ +#define ZC3XX_R00B_TESTMODECONTROL 0x000b + +/* Frame retreiving */ +#define ZC3XX_R00C_LASTACQTIME 0x000c +#define ZC3XX_R00D_MONITORRES 0x000d +#define ZC3XX_R00E_TIMESTAMPHIGH 0x000e +#define ZC3XX_R00F_TIMESTAMPLOW 0x000f +#define ZC3XX_R018_FRAMELOST 0x0018 +#define ZC3XX_R019_AUTOADJUSTFPS 0x0019 +#define ZC3XX_R01A_LASTFRAMESTATE 0x001a +#define ZC3XX_R025_DATACOUNTER 0x0025 + +/* Stream and sensor specific */ +#define ZC3XX_R010_CMOSSENSORSELECT 0x0010 +#define ZC3XX_R011_VIDEOSTATUS 0x0011 +#define ZC3XX_R012_VIDEOCONTROLFUNC 0x0012 + +/* Horizontal and vertical synchros */ +#define ZC3XX_R01D_HSYNC_0 0x001d +#define ZC3XX_R01E_HSYNC_1 0x001e +#define ZC3XX_R01F_HSYNC_2 0x001f +#define ZC3XX_R020_HSYNC_3 0x0020 + +/* Target picture size in byte */ +#define ZC3XX_R022_TARGETPICTSIZE_0 0x0022 +#define ZC3XX_R023_TARGETPICTSIZE_1 0x0023 +#define ZC3XX_R024_TARGETPICTSIZE_2 0x0024 + +/* Audio registers */ +#define ZC3XX_R030_AUDIOADC 0x0030 +#define ZC3XX_R031_AUDIOSTREAMSTATUS 0x0031 +#define ZC3XX_R032_AUDIOSTATUS 0x0032 + +/* Sensor interface */ +#define ZC3XX_R080_HBLANKHIGH 0x0080 +#define ZC3XX_R081_HBLANKLOW 0x0081 +#define ZC3XX_R082_RESETLEVELADDR 0x0082 +#define ZC3XX_R083_RGAINADDR 0x0083 +#define ZC3XX_R084_GGAINADDR 0x0084 +#define ZC3XX_R085_BGAINADDR 0x0085 +#define ZC3XX_R086_EXPTIMEHIGH 0x0086 +#define ZC3XX_R087_EXPTIMEMID 0x0087 +#define ZC3XX_R088_EXPTIMELOW 0x0088 +#define ZC3XX_R089_RESETBLACKHIGH 0x0089 +#define ZC3XX_R08A_RESETWHITEHIGH 0x008a +#define ZC3XX_R08B_I2CDEVICEADDR 0x008b +#define ZC3XX_R08C_I2CIDLEANDNACK 0x008c +#define ZC3XX_R08D_COMPABILITYMODE 0x008d +#define ZC3XX_R08E_COMPABILITYMODE2 0x008e + +/* I2C control */ +#define ZC3XX_R090_I2CCOMMAND 0x0090 +#define ZC3XX_R091_I2CSTATUS 0x0091 +#define ZC3XX_R092_I2CADDRESSSELECT 0x0092 +#define ZC3XX_R093_I2CSETVALUE 0x0093 +#define ZC3XX_R094_I2CWRITEACK 0x0094 +#define ZC3XX_R095_I2CREAD 0x0095 +#define ZC3XX_R096_I2CREADACK 0x0096 + +/* Window inside the sensor array */ +#define ZC3XX_R097_WINYSTARTHIGH 0x0097 +#define ZC3XX_R098_WINYSTARTLOW 0x0098 +#define ZC3XX_R099_WINXSTARTHIGH 0x0099 +#define ZC3XX_R09A_WINXSTARTLOW 0x009a +#define ZC3XX_R09B_WINHEIGHTHIGH 0x009b +#define ZC3XX_R09C_WINHEIGHTLOW 0x009c +#define ZC3XX_R09D_WINWIDTHHIGH 0x009d +#define ZC3XX_R09E_WINWIDTHLOW 0x009e +#define ZC3XX_R119_FIRSTYHIGH 0x0119 +#define ZC3XX_R11A_FIRSTYLOW 0x011a +#define ZC3XX_R11B_FIRSTXHIGH 0x011b +#define ZC3XX_R11C_FIRSTXLOW 0x011c + +/* Max sensor array size */ +#define ZC3XX_R09F_MAXXHIGH 0x009f +#define ZC3XX_R0A0_MAXXLOW 0x00a0 +#define ZC3XX_R0A1_MAXYHIGH 0x00a1 +#define ZC3XX_R0A2_MAXYLOW 0x00a2 +#define ZC3XX_R0A3_EXPOSURETIMEHIGH 0x00a3 +#define ZC3XX_R0A4_EXPOSURETIMELOW 0x00a4 +#define ZC3XX_R0A5_EXPOSUREGAIN 0x00a5 +#define ZC3XX_R0A6_EXPOSUREBLACKLVL 0x00a6 + +/* Other registers */ +#define ZC3XX_R100_OPERATIONMODE 0x0100 +#define ZC3XX_R101_SENSORCORRECTION 0x0101 + +/* Gains */ +#define ZC3XX_R116_RGAIN 0x0116 +#define ZC3XX_R117_GGAIN 0x0117 +#define ZC3XX_R118_BGAIN 0x0118 +#define ZC3XX_R11D_GLOBALGAIN 0x011d +#define ZC3XX_R1A8_DIGITALGAIN 0x01a8 +#define ZC3XX_R1A9_DIGITALLIMITDIFF 0x01a9 +#define ZC3XX_R1AA_DIGITALGAINSTEP 0x01aa + +/* Auto correction */ +#define ZC3XX_R180_AUTOCORRECTENABLE 0x0180 +#define ZC3XX_R181_WINXSTART 0x0181 +#define ZC3XX_R182_WINXWIDTH 0x0182 +#define ZC3XX_R183_WINXCENTER 0x0183 +#define ZC3XX_R184_WINYSTART 0x0184 +#define ZC3XX_R185_WINYWIDTH 0x0185 +#define ZC3XX_R186_WINYCENTER 0x0186 + +/* Gain range */ +#define ZC3XX_R187_MAXGAIN 0x0187 +#define ZC3XX_R188_MINGAIN 0x0188 + +/* Auto exposure and white balance */ +#define ZC3XX_R189_AWBSTATUS 0x0189 +#define ZC3XX_R18A_AWBFREEZE 0x018a +#define ZC3XX_R18B_AESTATUS 0x018b +#define ZC3XX_R18C_AEFREEZE 0x018c +#define ZC3XX_R18F_AEUNFREEZE 0x018f +#define ZC3XX_R190_EXPOSURELIMITHIGH 0x0190 +#define ZC3XX_R191_EXPOSURELIMITMID 0x0191 +#define ZC3XX_R192_EXPOSURELIMITLOW 0x0192 +#define ZC3XX_R195_ANTIFLICKERHIGH 0x0195 +#define ZC3XX_R196_ANTIFLICKERMID 0x0196 +#define ZC3XX_R197_ANTIFLICKERLOW 0x0197 + +/* What is this ? */ +#define ZC3XX_R18D_YTARGET 0x018d +#define ZC3XX_R18E_RESETLVL 0x018e + +/* Color */ +#define ZC3XX_R1A0_REDMEANAFTERAGC 0x01a0 +#define ZC3XX_R1A1_GREENMEANAFTERAGC 0x01a1 +#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2 +#define ZC3XX_R1A3_REDMEANAFTERAWB 0x01a3 +#define ZC3XX_R1A4_GREENMEANAFTERAWB 0x01a4 +#define ZC3XX_R1A5_BLUEMEANAFTERAWB 0x01a5 +#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6 +#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7 + +#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2 + +/* Matrixes */ + +/* Color matrix is like : + R' = R * RGB00 + G * RGB01 + B * RGB02 + RGB03 + G' = R * RGB10 + G * RGB11 + B * RGB22 + RGB13 + B' = R * RGB20 + G * RGB21 + B * RGB12 + RGB23 + */ +#define ZC3XX_R10A_RGB00 0x010a +#define ZC3XX_R10B_RGB01 0x010b +#define ZC3XX_R10C_RGB02 0x010c +#define ZC3XX_R113_RGB03 0x0113 +#define ZC3XX_R10D_RGB10 0x010d +#define ZC3XX_R10E_RGB11 0x010e +#define ZC3XX_R10F_RGB12 0x010f +#define ZC3XX_R114_RGB13 0x0114 +#define ZC3XX_R110_RGB20 0x0110 +#define ZC3XX_R111_RGB21 0x0111 +#define ZC3XX_R112_RGB22 0x0112 +#define ZC3XX_R115_RGB23 0x0115 + +/* Gamma matrix */ +#define ZC3XX_R120_GAMMA00 0x0120 +#define ZC3XX_R121_GAMMA01 0x0121 +#define ZC3XX_R122_GAMMA02 0x0122 +#define ZC3XX_R123_GAMMA03 0x0123 +#define ZC3XX_R124_GAMMA04 0x0124 +#define ZC3XX_R125_GAMMA05 0x0125 +#define ZC3XX_R126_GAMMA06 0x0126 +#define ZC3XX_R127_GAMMA07 0x0127 +#define ZC3XX_R128_GAMMA08 0x0128 +#define ZC3XX_R129_GAMMA09 0x0129 +#define ZC3XX_R12A_GAMMA0A 0x012a +#define ZC3XX_R12B_GAMMA0B 0x012b +#define ZC3XX_R12C_GAMMA0C 0x012c +#define ZC3XX_R12D_GAMMA0D 0x012d +#define ZC3XX_R12E_GAMMA0E 0x012e +#define ZC3XX_R12F_GAMMA0F 0x012f +#define ZC3XX_R130_GAMMA10 0x0130 +#define ZC3XX_R131_GAMMA11 0x0131 +#define ZC3XX_R132_GAMMA12 0x0132 +#define ZC3XX_R133_GAMMA13 0x0133 +#define ZC3XX_R134_GAMMA14 0x0134 +#define ZC3XX_R135_GAMMA15 0x0135 +#define ZC3XX_R136_GAMMA16 0x0136 +#define ZC3XX_R137_GAMMA17 0x0137 +#define ZC3XX_R138_GAMMA18 0x0138 +#define ZC3XX_R139_GAMMA19 0x0139 +#define ZC3XX_R13A_GAMMA1A 0x013a +#define ZC3XX_R13B_GAMMA1B 0x013b +#define ZC3XX_R13C_GAMMA1C 0x013c +#define ZC3XX_R13D_GAMMA1D 0x013d +#define ZC3XX_R13E_GAMMA1E 0x013e +#define ZC3XX_R13F_GAMMA1F 0x013f + +/* Luminance gamma */ +#define ZC3XX_R140_YGAMMA00 0x0140 +#define ZC3XX_R141_YGAMMA01 0x0141 +#define ZC3XX_R142_YGAMMA02 0x0142 +#define ZC3XX_R143_YGAMMA03 0x0143 +#define ZC3XX_R144_YGAMMA04 0x0144 +#define ZC3XX_R145_YGAMMA05 0x0145 +#define ZC3XX_R146_YGAMMA06 0x0146 +#define ZC3XX_R147_YGAMMA07 0x0147 +#define ZC3XX_R148_YGAMMA08 0x0148 +#define ZC3XX_R149_YGAMMA09 0x0149 +#define ZC3XX_R14A_YGAMMA0A 0x014a +#define ZC3XX_R14B_YGAMMA0B 0x014b +#define ZC3XX_R14C_YGAMMA0C 0x014c +#define ZC3XX_R14D_YGAMMA0D 0x014d +#define ZC3XX_R14E_YGAMMA0E 0x014e +#define ZC3XX_R14F_YGAMMA0F 0x014f +#define ZC3XX_R150_YGAMMA10 0x0150 +#define ZC3XX_R151_YGAMMA11 0x0151 + +#define ZC3XX_R1C5_SHARPNESSMODE 0x01c5 +#define ZC3XX_R1C6_SHARPNESS00 0x01c6 +#define ZC3XX_R1C7_SHARPNESS01 0x01c7 +#define ZC3XX_R1C8_SHARPNESS02 0x01c8 +#define ZC3XX_R1C9_SHARPNESS03 0x01c9 +#define ZC3XX_R1CA_SHARPNESS04 0x01ca +#define ZC3XX_R1CB_SHARPNESS05 0x01cb + +/* Synchronization */ +#define ZC3XX_R190_SYNC00LOW 0x0190 +#define ZC3XX_R191_SYNC00MID 0x0191 +#define ZC3XX_R192_SYNC00HIGH 0x0192 +#define ZC3XX_R195_SYNC01LOW 0x0195 +#define ZC3XX_R196_SYNC01MID 0x0196 +#define ZC3XX_R197_SYNC01HIGH 0x0197 + +/* Dead pixels */ +#define ZC3XX_R250_DEADPIXELSMODE 0x0250 + +/* EEPROM */ +#define ZC3XX_R300_EEPROMCONFIG 0x0300 +#define ZC3XX_R301_EEPROMACCESS 0x0301 +#define ZC3XX_R302_EEPROMSTATUS 0x0302 diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 548c4c8c3f33..b761b11c5c6a 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -35,6 +35,7 @@ MODULE_LICENSE("GPL"); static int force_sensor = -1; #include "jpeg.h" +#include "zc3xx-reg.h" /* specific webcam descriptor */ struct sd { @@ -209,30 +210,30 @@ struct usb_action { static const struct usb_action cs2102_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x00, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x20, 0x0080}, - {0xa0, 0x21, 0x0081}, - {0xa0, 0x30, 0x0083}, - {0xa0, 0x31, 0x0084}, - {0xa0, 0x32, 0x0085}, - {0xa0, 0x23, 0x0086}, - {0xa0, 0x24, 0x0087}, - {0xa0, 0x25, 0x0088}, - {0xa0, 0xb3, 0x008b}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, + {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, + {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, + {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, + {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, + {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, + {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xaa, 0x02, 0x0008}, {0xaa, 0x03, 0x0000}, {0xaa, 0x11, 0x0000}, @@ -245,124 +246,124 @@ static const struct usb_action cs2102_Initial[] = { {0xaa, 0x30, 0x0030}, {0xaa, 0x31, 0x0030}, {0xaa, 0x32, 0x0030}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x10, 0x01ae}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x68, 0x018d}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x68, ZC3XX_R18D_YTARGET}, {0xa0, 0x00, 0x01ad}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x24, 0x0120}, /* gamma 5 */ - {0xa0, 0x44, 0x0121}, - {0xa0, 0x64, 0x0122}, - {0xa0, 0x84, 0x0123}, - {0xa0, 0x9d, 0x0124}, - {0xa0, 0xb2, 0x0125}, - {0xa0, 0xc4, 0x0126}, - {0xa0, 0xd3, 0x0127}, - {0xa0, 0xe0, 0x0128}, - {0xa0, 0xeb, 0x0129}, - {0xa0, 0xf4, 0x012a}, - {0xa0, 0xfb, 0x012b}, - {0xa0, 0xff, 0x012c}, - {0xa0, 0xff, 0x012d}, - {0xa0, 0xff, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x18, 0x0130}, - {0xa0, 0x20, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0e, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x00, 0x013c}, - {0xa0, 0x00, 0x013d}, - {0xa0, 0x00, 0x013e}, - {0xa0, 0x01, 0x013f}, - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ + {0xa0, 0x44, ZC3XX_R121_GAMMA01}, + {0xa0, 0x64, ZC3XX_R122_GAMMA02}, + {0xa0, 0x84, ZC3XX_R123_GAMMA03}, + {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, + {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, + {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, + {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, + {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, + {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, + {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x18, ZC3XX_R130_GAMMA10}, + {0xa0, 0x20, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x23, 0x0001}, {0xaa, 0x24, 0x0055}, {0xaa, 0x25, 0x00cc}, {0xaa, 0x21, 0x003f}, - {0xa0, 0x02, 0x0190}, - {0xa0, 0xab, 0x0191}, - {0xa0, 0x98, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x30, 0x0196}, - {0xa0, 0xd4, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x39, 0x001d}, - {0xa0, 0x70, 0x001e}, - {0xa0, 0xb0, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x02, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0xab, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x98, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x30, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0xd4, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x39, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x70, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xb0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action cs2102_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x00, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x20, 0x0080}, - {0xa0, 0x21, 0x0081}, - {0xa0, 0x30, 0x0083}, - {0xa0, 0x31, 0x0084}, - {0xa0, 0x32, 0x0085}, - {0xa0, 0x23, 0x0086}, - {0xa0, 0x24, 0x0087}, - {0xa0, 0x25, 0x0088}, - {0xa0, 0xb3, 0x008b}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x20, ZC3XX_R080_HBLANKHIGH}, + {0xa0, 0x21, ZC3XX_R081_HBLANKLOW}, + {0xa0, 0x30, ZC3XX_R083_RGAINADDR}, + {0xa0, 0x31, ZC3XX_R084_GGAINADDR}, + {0xa0, 0x32, ZC3XX_R085_BGAINADDR}, + {0xa0, 0x23, ZC3XX_R086_EXPTIMEHIGH}, + {0xa0, 0x24, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x25, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0xb3, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xaa, 0x02, 0x0008}, {0xaa, 0x03, 0x0000}, {0xaa, 0x11, 0x0001}, @@ -375,98 +376,98 @@ static const struct usb_action cs2102_InitialScale[] = { {0xaa, 0x30, 0x0030}, {0xaa, 0x31, 0x0030}, {0xaa, 0x32, 0x0030}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x68, 0x018d}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x68, ZC3XX_R18D_YTARGET}, {0xa0, 0x00, 0x01ad}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x24, 0x0120}, /* gamma 5 */ - {0xa0, 0x44, 0x0121}, - {0xa0, 0x64, 0x0122}, - {0xa0, 0x84, 0x0123}, - {0xa0, 0x9d, 0x0124}, - {0xa0, 0xb2, 0x0125}, - {0xa0, 0xc4, 0x0126}, - {0xa0, 0xd3, 0x0127}, - {0xa0, 0xe0, 0x0128}, - {0xa0, 0xeb, 0x0129}, - {0xa0, 0xf4, 0x012a}, - {0xa0, 0xfb, 0x012b}, - {0xa0, 0xff, 0x012c}, - {0xa0, 0xff, 0x012d}, - {0xa0, 0xff, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x18, 0x0130}, - {0xa0, 0x20, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0e, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x00, 0x013c}, - {0xa0, 0x00, 0x013d}, - {0xa0, 0x00, 0x013e}, - {0xa0, 0x01, 0x013f}, - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x24, ZC3XX_R120_GAMMA00}, /* gamma 5 */ + {0xa0, 0x44, ZC3XX_R121_GAMMA01}, + {0xa0, 0x64, ZC3XX_R122_GAMMA02}, + {0xa0, 0x84, ZC3XX_R123_GAMMA03}, + {0xa0, 0x9d, ZC3XX_R124_GAMMA04}, + {0xa0, 0xb2, ZC3XX_R125_GAMMA05}, + {0xa0, 0xc4, ZC3XX_R126_GAMMA06}, + {0xa0, 0xd3, ZC3XX_R127_GAMMA07}, + {0xa0, 0xe0, ZC3XX_R128_GAMMA08}, + {0xa0, 0xeb, ZC3XX_R129_GAMMA09}, + {0xa0, 0xf4, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xfb, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x18, ZC3XX_R130_GAMMA10}, + {0xa0, 0x20, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0e, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x23, 0x0000}, {0xaa, 0x24, 0x00aa}, {0xaa, 0x25, 0x00e6}, {0xaa, 0x21, 0x003f}, - {0xa0, 0x01, 0x0190}, - {0xa0, 0x55, 0x0191}, - {0xa0, 0xcc, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x18, 0x0196}, - {0xa0, 0x6a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x3f, 0x001d}, - {0xa0, 0xa5, 0x001e}, - {0xa0, 0xf0, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x01, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x55, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xcc, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x18, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x6a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x3f, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xa5, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf0, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action cs2102_50HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x008c}, /* 00,0f,8c,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x00ac}, /* 00,04,ac,aa */ @@ -475,23 +476,23 @@ static const struct usb_action cs2102_50HZ[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x00ac}, /* 00,1d,ac,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x42, 0x0197}, /* 01,97,42,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0x8c, 0x001d}, /* 00,1d,8c,cc */ - {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ - {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x42, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,42,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0x8c, ZC3XX_R01D_HSYNC_0}, /* 00,1d,8c,cc */ + {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ + {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ {} }; static const struct usb_action cs2102_50HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0093}, /* 00,0f,93,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x00a1}, /* 00,04,a1,aa */ @@ -500,23 +501,23 @@ static const struct usb_action cs2102_50HZScale[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x00a1}, /* 00,1d,a1,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xf7, 0x0192}, /* 01,92,f7,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0x93, 0x001d}, /* 00,1d,93,cc */ - {0xa0, 0xb0, 0x001e}, /* 00,1e,b0,cc */ - {0xa0, 0xd0, 0x001f}, /* 00,1f,d0,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xf7, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f7,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0x93, ZC3XX_R01D_HSYNC_0}, /* 00,1d,93,cc */ + {0xa0, 0xb0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,b0,cc */ + {0xa0, 0xd0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,d0,cc */ {} }; static const struct usb_action cs2102_60HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x005d}, /* 00,0f,5d,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x00aa}, /* 00,04,aa,aa */ @@ -525,23 +526,23 @@ static const struct usb_action cs2102_60HZ[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x00aa}, /* 00,1d,aa,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xe4, 0x0192}, /* 01,92,e4,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x3a, 0x0197}, /* 01,97,3a,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0x5d, 0x001d}, /* 00,1d,5d,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xe4, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e4,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3a,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0x5d, ZC3XX_R01D_HSYNC_0}, /* 00,1d,5d,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ {0xa0, 0xd0, 0x00c8}, /* 00,c8,d0,cc */ {} }; static const struct usb_action cs2102_60HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x00b7}, /* 00,0f,b7,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x00be}, /* 00,04,be,aa */ @@ -550,23 +551,23 @@ static const struct usb_action cs2102_60HZScale[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x00be}, /* 00,1d,be,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xfc, 0x0192}, /* 01,92,fc,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x69, 0x0197}, /* 01,97,69,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0xb7, 0x001d}, /* 00,1d,b7,cc */ - {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ - {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xfc, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,fc,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x69, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,69,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0xb7, ZC3XX_R01D_HSYNC_0}, /* 00,1d,b7,cc */ + {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ + {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ {} }; static const struct usb_action cs2102_NoFliker[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ @@ -575,23 +576,23 @@ static const struct usb_action cs2102_NoFliker[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ {} }; static const struct usb_action cs2102_NoFlikerScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0f, 0x0059}, /* 00,0f,59,aa */ {0xaa, 0x03, 0x0005}, /* 00,03,05,aa */ {0xaa, 0x04, 0x0080}, /* 00,04,80,aa */ @@ -600,878 +601,878 @@ static const struct usb_action cs2102_NoFlikerScale[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa */ {0xaa, 0x1c, 0x0005}, /* 00,1c,05,aa */ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x3f, 0x0191}, /* 01,91,3f,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0x59, 0x001d}, /* 00,1d,59,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x3f, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,3f,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0x59, ZC3XX_R01D_HSYNC_0}, /* 00,1d,59,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ {} }; /* CS2102_KOCOM */ static const struct usb_action cs2102K_Initial[] = { - {0xa0, 0x11, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x55, 0x008b}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0a, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0b, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0c, 0x0092}, - {0xa0, 0x7c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0d, 0x0092}, - {0xa0, 0xa3, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x03, 0x0092}, - {0xa0, 0xfb, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x05, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x06, 0x0092}, - {0xa0, 0x03, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x09, 0x0092}, - {0xa0, 0x08, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0e, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0f, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x10, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x11, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x12, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x15, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x16, 0x0092}, - {0xa0, 0x0c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x17, 0x0092}, - {0xa0, 0x0c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0xb7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x78, 0x018d}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x20, 0x0087}, - {0xa0, 0x21, 0x0088}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x01, 0x00a3}, - {0xa0, 0x22, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xee, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x3a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x0c, 0x01a9}, - {0xa0, 0x28, 0x01aa}, - {0xa0, 0x04, 0x001d}, - {0xa0, 0x0f, 0x001e}, - {0xa0, 0x19, 0x001f}, - {0xa0, 0x1f, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x5c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x5c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x96, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x96, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, {} }; static const struct usb_action cs2102K_InitialScale[] = { - {0xa0, 0x11, 0x0002}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x55, 0x008b}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0a, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0b, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0c, 0x0092}, - {0xa0, 0x7b, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0d, 0x0092}, - {0xa0, 0xa3, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x03, 0x0092}, - {0xa0, 0xfb, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x05, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x06, 0x0092}, - {0xa0, 0x03, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x09, 0x0092}, - {0xa0, 0x08, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0e, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0f, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x10, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x11, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x12, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x15, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x16, 0x0092}, - {0xa0, 0x0c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x17, 0x0092}, - {0xa0, 0x0c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0xf7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x78, 0x018d}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x20, 0x0087}, - {0xa0, 0x21, 0x0088}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0a, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0b, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0c, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0d, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xa3, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0e, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x01, 0x00a3}, - {0xa0, 0x22, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xee, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x3a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x0c, 0x01a9}, - {0xa0, 0x28, 0x01aa}, - {0xa0, 0x04, 0x001d}, - {0xa0, 0x0f, 0x001e}, - {0xa0, 0x19, 0x001f}, - {0xa0, 0x1f, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x55, 0x008b}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0A, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0B, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0C, 0x0092}, - {0xa0, 0x7b, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0D, 0x0092}, - {0xa0, 0xA3, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x03, 0x0092}, - {0xa0, 0xfb, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x05, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x06, 0x0092}, - {0xa0, 0x03, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x09, 0x0092}, - {0xa0, 0x08, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0E, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x0f, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x10, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x11, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x12, 0x0092}, - {0xa0, 0x18, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x15, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x16, 0x0092}, - {0xa0, 0x0c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x17, 0x0092}, - {0xa0, 0x0C, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0xf7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x78, 0x018d}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x20, 0x0087}, - {0xa0, 0x21, 0x0088}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa0, 0x00, 0x01ad}, {0xa0, 0x01, 0x01b1}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x22, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x01, 0x00a3}, - {0xa0, 0x22, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xee, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x3a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x0c, 0x01a9}, - {0xa0, 0x28, 0x01aa}, - {0xa0, 0x04, 0x001d}, - {0xa0, 0x0f, 0x001e}, - {0xa0, 0x19, 0x001f}, - {0xa0, 0x1f, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x4c, 0x0118}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x5c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x5c, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x96, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x96, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0xd0, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0xd0, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x02, 0x0008}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x0a, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x0a, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x44, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x44, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x21, 0x0092}, - {0xa0, 0x7e, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x13, 0x0092}, - {0xa0, 0x7e, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x14, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x18, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x04, 0x01a7}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x19, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x1f, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x4c, ZC3XX_R118_BGAIN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x5c, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x96, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xd0, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x0a, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x44, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7e, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {} }; static const struct usb_action gc0305_Initial[] = { /* 640x480 */ - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x04, 0x0002}, /* 00,02,04,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xe6, 0x009c}, /* 00,9c,e6,cc */ - {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ {0xaa, 0x13, 0x0002}, /* 00,13,02,aa */ {0xaa, 0x15, 0x0003}, /* 00,15,03,aa */ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ @@ -1481,9 +1482,9 @@ static const struct usb_action gc0305_Initial[] = { /* 640x480 */ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ - {0xa0, 0x82, 0x0086}, /* 00,86,82,cc */ - {0xa0, 0x83, 0x0087}, /* 00,87,83,cc */ - {0xa0, 0x84, 0x0088}, /* 00,88,84,cc */ + {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ + {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ + {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ @@ -1499,43 +1500,43 @@ static const struct usb_action gc0305_Initial[] = { /* 640x480 */ {0xaa, 0x19, 0x0086}, /* 00,19,86,aa */ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ - {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x76, 0x0189}, /* 01,89,76,cc */ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ - {0xa0, 0x85, 0x018d}, /* 01,8d,85,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ + {0xa0, 0x85, ZC3XX_R18D_YTARGET}, /* 01,8d,85,cc */ {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ - {0xa0, 0x52, 0x0116}, /* 01,16,52,cc */ - {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ - {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ - {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ + {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ + {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ + {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ + {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ {} }; static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc */ - {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc */ {0xaa, 0x13, 0x0000}, /* 00,13,00,aa */ {0xaa, 0x15, 0x0001}, /* 00,15,01,aa */ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ @@ -1545,9 +1546,9 @@ static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xaa, 0x1d, 0x0080}, /* 00,1d,80,aa */ {0xaa, 0x1f, 0x0008}, /* 00,1f,08,aa */ {0xaa, 0x21, 0x0012}, /* 00,21,12,aa */ - {0xa0, 0x82, 0x0086}, /* 00,86,82,cc */ - {0xa0, 0x83, 0x0087}, /* 00,87,83,cc */ - {0xa0, 0x84, 0x0088}, /* 00,88,84,cc */ + {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc */ + {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc */ + {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc */ {0xaa, 0x05, 0x0000}, /* 00,05,00,aa */ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa */ {0xaa, 0x0b, 0x00b0}, /* 00,0b,b0,aa */ @@ -1563,115 +1564,119 @@ static const struct usb_action gc0305_InitialScale[] = { /* 320x240 */ {0xaa, 0x19, 0x0088}, /* 00,19,88,aa */ {0xaa, 0x20, 0x0000}, /* 00,20,00,aa */ {0xaa, 0x1b, 0x0020}, /* 00,1b,20,aa */ - {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x76, 0x0189}, /* 01,89,76,cc */ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc */ {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ {0xa0, 0x00, 0x011e}, /* 01,1e,00,cc */ - {0xa0, 0x52, 0x0116}, /* 01,16,52,cc */ - {0xa0, 0x40, 0x0117}, /* 01,17,40,cc */ - {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ - {0xa0, 0x03, 0x0113}, /* 01,13,03,cc */ + {0xa0, 0x52, ZC3XX_R116_RGAIN}, /* 01,16,52,cc */ + {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* 01,17,40,cc */ + {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ + {0xa0, 0x03, ZC3XX_R113_RGB03}, /* 01,13,03,cc */ {} }; static const struct usb_action gc0305_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ {0xaa, 0x84, 0x0038}, /* 00,84,38,aa */ /* win: 00,84,ec */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc */ - {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ /* win: 01,92,10 */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x8e, 0x0197}, /* 01,97,8e,cc */ /* win: 01,97,ec */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ -/* {0xa0, 0x85, 0x018d}, * 01,8d,85,cc * * if 640x480 */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ + {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ + /* win: 01,92,10 */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc */ + /* win: 01,97,ec */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ +/* {0xa0, 0x85, ZC3XX_R18D_YTARGET}, * 01,8d,85,cc * + * if 640x480 */ {} }; static const struct usb_action gc0305_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x00ec}, /* 00,84,ec,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc */ - {0xa0, 0x10, 0x0192}, /* 01,92,10,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0xec, 0x0197}, /* 01,97,ec,cc */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ - {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc */ + {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0xec, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,ec,cc */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ {} }; static const struct usb_action gc0305_NoFliker[] = { - {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc */ + {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x00, 0x0191}, /* 01,91,00,cc */ - {0xa0, 0x48, 0x0192}, /* 01,92,48,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x60, 0x011d}, /* 01,1d,60,cc */ - {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ - {0xa0, 0x80, 0x018d}, /* 01,8d,80,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,00,cc */ + {0xa0, 0x48, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,48,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,60,cc */ + {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* 01,8d,80,cc */ {} }; /* play poker with registers at your own risk !! */ static const struct usb_action hdcs2020xx_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0e, 0x0010}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xd0, 0x0006}, /* D0 ?? E0 did not start */ - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x08, 0x008d}, - {0xa0, 0x08, 0x0098}, - {0xa0, 0x02, 0x009a}, - {0xa0, 0x08, 0x011a}, - {0xa0, 0x02, 0x011c}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xd8, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x88, 0x009e}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, + /* D0 ?? E0 did not start */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0x08, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x08, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x02, 0x0002}, {0xaa, 0x07, 0x0006}, {0xaa, 0x08, 0x0002}, @@ -1684,71 +1689,71 @@ static const struct usb_action hdcs2020xx_Initial[] = { {0xaa, 0x12, 0x0005}, {0xaa, 0x13, 0x0063}, {0xaa, 0x15, 0x0070}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x70, 0x018d}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x04, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x07, 0x01cb}, /* sharpness- */ - {0xa0, 0x11, 0x0120}, /* gamma ~4 */ - {0xa0, 0x37, 0x0121}, - {0xa0, 0x58, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x91, 0x0124}, - {0xa0, 0xa6, 0x0125}, - {0xa0, 0xb8, 0x0126}, - {0xa0, 0xc7, 0x0127}, - {0xa0, 0xd3, 0x0128}, - {0xa0, 0xde, 0x0129}, - {0xa0, 0xe6, 0x012a}, - {0xa0, 0xed, 0x012b}, - {0xa0, 0xf3, 0x012c}, - {0xa0, 0xf8, 0x012d}, - {0xa0, 0xfb, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x23, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - - {0xa0, 0x4c, 0x010a}, /* matrix */ - {0xa0, 0xf5, 0x010b}, - {0xa0, 0xff, 0x010c}, - {0xa0, 0xf9, 0x010d}, - {0xa0, 0x51, 0x010e}, - {0xa0, 0xf5, 0x010f}, - {0xa0, 0xfb, 0x0110}, - {0xa0, 0xed, 0x0111}, - {0xa0, 0x5f, 0x0112}, + {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4 */ + {0xa0, 0x37, ZC3XX_R121_GAMMA01}, + {0xa0, 0x58, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x91, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa6, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb8, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc7, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd3, ZC3XX_R128_GAMMA08}, + {0xa0, 0xde, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xed, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x23, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + + {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf5, ZC3XX_R10B_RGB01}, + {0xa0, 0xff, ZC3XX_R10C_RGB02}, + {0xa0, 0xf9, ZC3XX_R10D_RGB10}, + {0xa0, 0x51, ZC3XX_R10E_RGB11}, + {0xa0, 0xf5, ZC3XX_R10F_RGB12}, + {0xa0, 0xfb, ZC3XX_R110_RGB20}, + {0xa0, 0xed, ZC3XX_R111_RGB21}, + {0xa0, 0x5f, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x20, 0x0087}, - {0xa0, 0x21, 0x0088}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, {0xaa, 0x20, 0x0004}, {0xaa, 0x21, 0x003d}, {0xaa, 0x03, 0x0041}, @@ -1756,67 +1761,67 @@ static const struct usb_action hdcs2020xx_Initial[] = { {0xaa, 0x05, 0x003d}, {0xaa, 0x0e, 0x0001}, {0xaa, 0x0f, 0x0000}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x04, 0x0191}, - {0xa0, 0x3d, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x9b, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x41, 0x001d}, - {0xa0, 0x6f, 0x001e}, - {0xa0, 0xad, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x0f, 0x0087}, - {0xa0, 0x0e, 0x0088}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x9b, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0195}, {0xa1, 0x01, 0x0196}, {0xa1, 0x01, 0x0197}, - {0xa0, 0x3d, 0x0192}, - {0xa0, 0x04, 0x0191}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x1d, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x85, 0x0118}, + {0xa0, 0x3d, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x1d, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x85, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0116}, {0xa1, 0x01, 0x0118}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x1d, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x85, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x1d, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x85, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0116}, {0xa1, 0x01, 0x0118}, -/* {0xa0, 0x02, 0x0008}, */ +/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ {0xa0, 0x00, 0x0007}, {} }; static const struct usb_action hdcs2020xx_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0e, 0x0010}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x08, 0x008d}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x03, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x03, 0x011c}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xe6, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x86, 0x009e}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0e, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x02, 0x0002}, {0xaa, 0x07, 0x0006}, {0xaa, 0x08, 0x0002}, @@ -1829,70 +1834,70 @@ static const struct usb_action hdcs2020xx_InitialScale[] = { {0xaa, 0x12, 0x0005}, {0xaa, 0x13, 0x0063}, {0xaa, 0x15, 0x0070}, - {0xa0, 0xb7, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x70, 0x018d}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x04, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x04, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x07, 0x01cb}, /* sharpness- */ - {0xa0, 0x11, 0x0120}, /* gamma ~4*/ - {0xa0, 0x37, 0x0121}, - {0xa0, 0x58, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x91, 0x0124}, - {0xa0, 0xa6, 0x0125}, - {0xa0, 0xb8, 0x0126}, - {0xa0, 0xc7, 0x0127}, - {0xa0, 0xd3, 0x0128}, - {0xa0, 0xde, 0x0129}, - {0xa0, 0xe6, 0x012a}, - {0xa0, 0xed, 0x012b}, - {0xa0, 0xf3, 0x012c}, - {0xa0, 0xf8, 0x012d}, - {0xa0, 0xfb, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x23, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x60, 0x010a}, /* matrix */ - {0xa0, 0xff, 0x010b}, - {0xa0, 0xff, 0x010c}, - {0xa0, 0xff, 0x010d}, - {0xa0, 0x60, 0x010e}, - {0xa0, 0xff, 0x010f}, - {0xa0, 0xff, 0x0110}, - {0xa0, 0xff, 0x0111}, - {0xa0, 0x60, 0x0112}, + {0xa0, 0x07, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x11, ZC3XX_R120_GAMMA00}, /* gamma ~4*/ + {0xa0, 0x37, ZC3XX_R121_GAMMA01}, + {0xa0, 0x58, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x91, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa6, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb8, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc7, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd3, ZC3XX_R128_GAMMA08}, + {0xa0, 0xde, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe6, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xed, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf3, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf8, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfb, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x23, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xff, ZC3XX_R10B_RGB01}, + {0xa0, 0xff, ZC3XX_R10C_RGB02}, + {0xa0, 0xff, ZC3XX_R10D_RGB10}, + {0xa0, 0x60, ZC3XX_R10E_RGB11}, + {0xa0, 0xff, ZC3XX_R10F_RGB12}, + {0xa0, 0xff, ZC3XX_R110_RGB20}, + {0xa0, 0xff, ZC3XX_R111_RGB21}, + {0xa0, 0x60, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x20, 0x0087}, - {0xa0, 0x21, 0x0088}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW}, {0xaa, 0x20, 0x0002}, {0xaa, 0x21, 0x001b}, {0xaa, 0x03, 0x0044}, @@ -1900,62 +1905,62 @@ static const struct usb_action hdcs2020xx_InitialScale[] = { {0xaa, 0x05, 0x001b}, {0xaa, 0x0e, 0x0001}, {0xaa, 0x0f, 0x0000}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x02, 0x0191}, - {0xa0, 0x1b, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x4d, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x44, 0x001d}, - {0xa0, 0x6f, 0x001e}, - {0xa0, 0xad, 0x001f}, - {0xa0, 0xeb, 0x0020}, - {0xa0, 0x0f, 0x0087}, - {0xa0, 0x0e, 0x0088}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x4d, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x44, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x6f, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xad, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xeb, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x0f, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x0e, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0195}, {0xa1, 0x01, 0x0196}, {0xa1, 0x01, 0x0197}, - {0xa0, 0x1b, 0x0192}, - {0xa0, 0x02, 0x0191}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x1d, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x99, 0x0118}, + {0xa0, 0x1b, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x1d, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x99, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0116}, {0xa1, 0x01, 0x0118}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x1d, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x99, 0x0118}, -/* {0xa0, 0x02, 0x0008}, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x1d, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x99, ZC3XX_R118_BGAIN}, +/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ {0xa0, 0x00, 0x0007}, /* {0xa0, 0x18, 0x00fe}, */ {} }; static const struct usb_action hdcs2020xb_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x11, 0x0002}, - {0xa0, 0x03, 0x0008}, /* qtable 0x05 */ - {0xa0, 0x08, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x88, 0x009e}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x1c, 0x0000}, {0xaa, 0x0a, 0x0001}, {0xaa, 0x0b, 0x0006}, @@ -1973,121 +1978,121 @@ static const struct usb_action hdcs2020xb_Initial[] = { {0xaa, 0x15, 0x004e}, {0xaa, 0x1c, 0x0004}, - {0xa0, 0xb7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x70, 0x018d}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - - {0xa0, 0x66, 0x010a}, /* matrix */ - {0xa0, 0xed, 0x010b}, - {0xa0, 0xed, 0x010c}, - {0xa0, 0xed, 0x010d}, - {0xa0, 0x66, 0x010e}, - {0xa0, 0xed, 0x010f}, - {0xa0, 0xed, 0x0110}, - {0xa0, 0xed, 0x0111}, - {0xa0, 0x66, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + + {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xed, ZC3XX_R10B_RGB01}, + {0xa0, 0xed, ZC3XX_R10C_RGB02}, + {0xa0, 0xed, ZC3XX_R10D_RGB10}, + {0xa0, 0x66, ZC3XX_R10E_RGB11}, + {0xa0, 0xed, ZC3XX_R10F_RGB12}, + {0xa0, 0xed, ZC3XX_R110_RGB20}, + {0xa0, 0xed, ZC3XX_R111_RGB21}, + {0xa0, 0x66, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x13, 0x0031}, {0xaa, 0x14, 0x0001}, {0xaa, 0x0e, 0x0004}, {0xaa, 0x19, 0x00cd}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x02, 0x0191}, - {0xa0, 0x62, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x3d, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - - {0xa0, 0x0c, 0x01a9}, /* 0x14 */ - {0xa0, 0x28, 0x01aa}, - {0xa0, 0x04, 0x001d}, - {0xa0, 0x18, 0x001e}, - {0xa0, 0x2c, 0x001f}, - {0xa0, 0x41, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 0x14 */ + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action hdcs2020xb_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x88, 0x009e}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x1c, 0x0000}, {0xaa, 0x0a, 0x0001}, {0xaa, 0x0b, 0x0006}, @@ -2103,182 +2108,182 @@ static const struct usb_action hdcs2020xb_InitialScale[] = { {0xaa, 0x12, 0x0018}, {0xaa, 0x15, 0x004e}, {0xaa, 0x1c, 0x0004}, - {0xa0, 0xf7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x70, 0x018d}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x66, 0x010a}, /* matrix */ - {0xa0, 0xed, 0x010b}, - {0xa0, 0xed, 0x010c}, - {0xa0, 0xed, 0x010d}, - {0xa0, 0x66, 0x010e}, - {0xa0, 0xed, 0x010f}, - {0xa0, 0xed, 0x0110}, - {0xa0, 0xed, 0x0111}, - {0xa0, 0x66, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x66, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xed, ZC3XX_R10B_RGB01}, + {0xa0, 0xed, ZC3XX_R10C_RGB02}, + {0xa0, 0xed, ZC3XX_R10D_RGB10}, + {0xa0, 0x66, ZC3XX_R10E_RGB11}, + {0xa0, 0xed, ZC3XX_R10F_RGB12}, + {0xa0, 0xed, ZC3XX_R110_RGB20}, + {0xa0, 0xed, ZC3XX_R111_RGB21}, + {0xa0, 0x66, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /**** set exposure ***/ {0xaa, 0x13, 0x0031}, {0xaa, 0x14, 0x0001}, {0xaa, 0x0e, 0x0004}, {0xaa, 0x19, 0x00cd}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x02, 0x0191}, - {0xa0, 0x62, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x3d, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x0c, 0x01a9}, - {0xa0, 0x28, 0x01aa}, - {0xa0, 0x04, 0x001d}, - {0xa0, 0x18, 0x001e}, - {0xa0, 0x2c, 0x001f}, - {0xa0, 0x41, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x41, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action hdcs2020b_50HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ - {0xa0, 0x76, 0x0192}, /* 01,92,76,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x46, 0x0197}, /* 01,97,46,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x28, 0x01aa}, /* 01,aa,28,cc */ - {0xa0, 0x05, 0x001d}, /* 00,1d,05,cc */ - {0xa0, 0x1a, 0x001e}, /* 00,1e,1a,cc */ - {0xa0, 0x2f, 0x001f}, /* 00,1f,2f,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ + {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ + {0xa0, 0x05, ZC3XX_R01D_HSYNC_0}, /* 00,1d,05,cc */ + {0xa0, 0x1a, ZC3XX_R01E_HSYNC_1}, /* 00,1e,1a,cc */ + {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */ {} }; static const struct usb_action hdcs2020b_60HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ - {0xa0, 0x62, 0x0192}, /* 01,92,62,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x3d, 0x0197}, /* 01,97,3d,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x28, 0x01aa}, /* 01,aa,28,cc */ - {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ - {0xa0, 0x18, 0x001e}, /* 00,1e,18,cc */ - {0xa0, 0x2c, 0x001f}, /* 00,1f,2c,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ + {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,28,cc */ + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ + {0xa0, 0x18, ZC3XX_R01E_HSYNC_1}, /* 00,1e,18,cc */ + {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */ {} }; static const struct usb_action hdcs2020b_NoFliker[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ - {0xa0, 0x70, 0x0192}, /* 01,92,70,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0x04, 0x001d}, /* 00,1d,04,cc */ - {0xa0, 0x17, 0x001e}, /* 00,1e,17,cc */ - {0xa0, 0x2a, 0x001f}, /* 00,1f,2a,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ + {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0x04, ZC3XX_R01D_HSYNC_0}, /* 00,1d,04,cc */ + {0xa0, 0x17, ZC3XX_R01E_HSYNC_1}, /* 00,1e,17,cc */ + {0xa0, 0x2a, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2a,cc */ {} }; static const struct usb_action hv7131bxx_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x00, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xaa, 0x30, 0x002d}, {0xaa, 0x01, 0x0005}, {0xaa, 0x11, 0x0000}, @@ -2291,48 +2296,48 @@ static const struct usb_action hv7131bxx_Initial[] = { {0xaa, 0x32, 0x0038}, {0xaa, 0x33, 0x0038}, {0xaa, 0x5b, 0x0001}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x68, 0x018d}, - {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x68, ZC3XX_R18D_YTARGET}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0xc0, 0x019b}, {0xa0, 0xa0, 0x019c}, - {0xa0, 0x02, 0x0188}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x02, ZC3XX_R188_MINGAIN}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */ {0xa1, 0x01, 0x0002}, - {0xa0, 0x00, 0x0092}, - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x25, 0x0007}, {0xaa, 0x26, 0x00a1}, {0xaa, 0x27, 0x0020}, @@ -2341,52 +2346,52 @@ static const struct usb_action hv7131bxx_Initial[] = { {0xaa, 0x22, 0x0016}, {0xaa, 0x23, 0x0040}, - {0xa0, 0x10, 0x0190}, /* 2F */ - {0xa0, 0x04, 0x0191}, /* 4d */ - {0xa0, 0x60, 0x0192}, - {0xa0, 0x01, 0x0195}, - {0xa0, 0x86, 0x0196}, - {0xa0, 0xa0, 0x0197}, - {0xa0, 0x07, 0x018c}, - {0xa0, 0x0f, 0x018f}, - {0xa0, 0x18, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x00, 0x001d}, - {0xa0, 0xa0, 0x001e}, - {0xa0, 0x16, 0x001f}, - {0xa0, 0x40, 0x0020}, - {0xa0, 0x60, 0x011d}, + {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2F */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ + {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x86, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0xa0, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x07, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x0f, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xa0, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x16, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x40, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, {0xa1, 0x01, 0x001d}, {0xa1, 0x01, 0x001e}, {0xa1, 0x01, 0x001f}, {0xa1, 0x01, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, -/* {0xa0, 0x02, 0x0008}, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, +/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ {} }; static const struct usb_action hv7131bxx_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x00, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, {0xaa, 0x30, 0x002d}, {0xaa, 0x01, 0x0005}, {0xaa, 0x11, 0x0001}, @@ -2399,47 +2404,47 @@ static const struct usb_action hv7131bxx_InitialScale[] = { {0xaa, 0x32, 0x0038}, {0xaa, 0x33, 0x0038}, {0xaa, 0x5b, 0x0001}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x70, 0x018d}, - {0xa0, 0x60, 0x01a8}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x70, ZC3XX_R18D_YTARGET}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0xc0, 0x019b}, {0xa0, 0xa0, 0x019c}, - {0xa0, 0x02, 0x0188}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x02, ZC3XX_R188_MINGAIN}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xaa, 0x02, 0x0090}, /* {0xaa, 0x02, 0x0080}, */ {0xa1, 0x01, 0x0002}, - {0xa0, 0x00, 0x0092}, - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x25, 0x0007}, {0xaa, 0x26, 0x00a1}, {0xaa, 0x27, 0x0020}, @@ -2447,57 +2452,57 @@ static const struct usb_action hv7131bxx_InitialScale[] = { {0xaa, 0x21, 0x0040}, {0xaa, 0x22, 0x0013}, {0xaa, 0x23, 0x004c}, - {0xa0, 0x10, 0x0190}, /* 2f */ - {0xa0, 0x04, 0x0191}, /* 4d */ - {0xa0, 0x60, 0x0192}, /* 60 */ - {0xa0, 0x00, 0x0195}, - {0xa0, 0xc3, 0x0196}, - {0xa0, 0x50, 0x0197}, - {0xa0, 0x0c, 0x018c}, - {0xa0, 0x18, 0x018f}, - {0xa0, 0x18, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0x00, 0x001d}, - {0xa0, 0x40, 0x001e}, - {0xa0, 0x13, 0x001f}, - {0xa0, 0x4c, 0x0020}, - {0xa0, 0x60, 0x011d}, + {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 4d */ + {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 60 */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0xc3, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x50, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x18, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x00, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0x13, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0x4c, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, {0xa1, 0x01, 0x001d}, {0xa1, 0x01, 0x001e}, {0xa1, 0x01, 0x001f}, {0xa1, 0x01, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, -/* {0xa0, 0x02, 0x0008}, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, +/* {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, */ {} }; static const struct usb_action hv7131cxx_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x01, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x0012}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x000c}, {0xaa, 0x11, 0x0000}, {0xaa, 0x13, 0x0000}, @@ -2506,96 +2511,96 @@ static const struct usb_action hv7131cxx_Initial[] = { {0xaa, 0x16, 0x0002}, {0xaa, 0x17, 0x0088}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x89, 0x018d}, - {0xa0, 0x50, 0x01a8}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x89, ZC3XX_R18D_YTARGET}, + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0xc0, 0x019b}, {0xa0, 0xa0, 0x019c}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, - {0xa0, 0x00, 0x0092}, - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x60, 0x010a}, /* matrix */ - {0xa0, 0xf0, 0x010b}, - {0xa0, 0xf0, 0x010c}, - {0xa0, 0xf0, 0x010d}, - {0xa0, 0x60, 0x010e}, - {0xa0, 0xf0, 0x010f}, - {0xa0, 0xf0, 0x0110}, - {0xa0, 0xf0, 0x0111}, - {0xa0, 0x60, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf0, ZC3XX_R10B_RGB01}, + {0xa0, 0xf0, ZC3XX_R10C_RGB02}, + {0xa0, 0xf0, ZC3XX_R10D_RGB10}, + {0xa0, 0x60, ZC3XX_R10E_RGB11}, + {0xa0, 0xf0, ZC3XX_R10F_RGB12}, + {0xa0, 0xf0, ZC3XX_R110_RGB20}, + {0xa0, 0xf0, ZC3XX_R111_RGB21}, + {0xa0, 0x60, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x25, 0x0007}, {0xaa, 0x26, 0x0053}, {0xaa, 0x27, 0x0000}, - {0xa0, 0x10, 0x0190}, /* 2f */ - {0xa0, 0x04, 0x0191}, /* 9b */ - {0xa0, 0x60, 0x0192}, /* 80 */ - {0xa0, 0x01, 0x0195}, - {0xa0, 0xd4, 0x0196}, - {0xa0, 0xc0, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x13, 0x01aa}, + {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */ + {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */ + {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa1, 0x01, 0x001d}, {0xa1, 0x01, 0x001e}, {0xa1, 0x01, 0x001f}, {0xa1, 0x01, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action hv7131cxx_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - - {0xa0, 0x00, 0x0002}, /* diff */ - {0xa0, 0x01, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x03, 0x0008}, - - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x0012}, - - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, /* 1e0 */ - - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* diff */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 1e0 */ + + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x000c}, {0xaa, 0x11, 0x0000}, {0xaa, 0x13, 0x0000}, @@ -2604,101 +2609,102 @@ static const struct usb_action hv7131cxx_InitialScale[] = { {0xaa, 0x16, 0x0002}, {0xaa, 0x17, 0x0088}, - {0xa0, 0x00, 0x0019}, /* 00 */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00 */ - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x89, 0x018d}, - {0xa0, 0x50, 0x01a8}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x89, ZC3XX_R18D_YTARGET}, + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, {0xa0, 0xc0, 0x019b}, {0xa0, 0xa0, 0x019c}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, - {0xa0, 0x00, 0x0092}, /* read the i2c chips ident */ - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + /* read the i2c chips ident */ + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x60, 0x010a}, /* matrix */ - {0xa0, 0xf0, 0x010b}, - {0xa0, 0xf0, 0x010c}, - {0xa0, 0xf0, 0x010d}, - {0xa0, 0x60, 0x010e}, - {0xa0, 0xf0, 0x010f}, - {0xa0, 0xf0, 0x0110}, - {0xa0, 0xf0, 0x0111}, - {0xa0, 0x60, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x60, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf0, ZC3XX_R10B_RGB01}, + {0xa0, 0xf0, ZC3XX_R10C_RGB02}, + {0xa0, 0xf0, ZC3XX_R10D_RGB10}, + {0xa0, 0x60, ZC3XX_R10E_RGB11}, + {0xa0, 0xf0, ZC3XX_R10F_RGB12}, + {0xa0, 0xf0, ZC3XX_R110_RGB20}, + {0xa0, 0xf0, ZC3XX_R111_RGB21}, + {0xa0, 0x60, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x25, 0x0007}, {0xaa, 0x26, 0x0053}, {0xaa, 0x27, 0x0000}, - {0xa0, 0x10, 0x0190}, /* 2f */ - {0xa0, 0x04, 0x0191}, /* 9b */ - {0xa0, 0x60, 0x0192}, /* 80 */ + {0xa0, 0x10, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 2f */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 9b */ + {0xa0, 0x60, ZC3XX_R192_EXPOSURELIMITLOW}, /* 80 */ - {0xa0, 0x01, 0x0195}, - {0xa0, 0xd4, 0x0196}, - {0xa0, 0xc0, 0x0197}, + {0xa0, 0x01, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0xd4, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0xc0, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x13, 0x01aa}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x13, ZC3XX_R1AA_DIGITALGAINSTEP}, {0xa1, 0x01, 0x001d}, {0xa1, 0x01, 0x001e}, {0xa1, 0x01, 0x001f}, {0xa1, 0x01, 0x0020}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action icm105axx_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0c, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0xa1, 0x008b}, - {0xa0, 0x00, 0x0097}, - {0xa0, 0x01, 0x0098}, - {0xa0, 0x00, 0x0099}, - {0xa0, 0x01, 0x009a}, - {0xa0, 0x01, 0x011a}, - {0xa0, 0x01, 0x011c}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, + {0xa0, 0x01, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, + {0xa0, 0x01, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x01, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x01, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xaa, 0x01, 0x0010}, {0xaa, 0x03, 0x0000}, {0xaa, 0x04, 0x0001}, @@ -2779,36 +2785,36 @@ static const struct usb_action icm105axx_Initial[] = { {0xaa, 0x24, 0x0080}, {0xaa, 0x26, 0x0080}, {0xaa, 0x00, 0x0084}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xaa, 0xa8, 0x00c0}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x52, 0x010a}, /* matrix */ - {0xa0, 0xf7, 0x010b}, - {0xa0, 0xf7, 0x010c}, - {0xa0, 0xf7, 0x010d}, - {0xa0, 0x52, 0x010e}, - {0xa0, 0xf7, 0x010f}, - {0xa0, 0xf7, 0x0110}, - {0xa0, 0xf7, 0x0111}, - {0xa0, 0x52, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf7, ZC3XX_R10B_RGB01}, + {0xa0, 0xf7, ZC3XX_R10C_RGB02}, + {0xa0, 0xf7, ZC3XX_R10D_RGB10}, + {0xa0, 0x52, ZC3XX_R10E_RGB11}, + {0xa0, 0xf7, ZC3XX_R10F_RGB12}, + {0xa0, 0xf7, ZC3XX_R110_RGB20}, + {0xa0, 0xf7, ZC3XX_R111_RGB21}, + {0xa0, 0x52, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x0d, 0x0003}, {0xaa, 0x0c, 0x008c}, {0xaa, 0x0e, 0x0095}, @@ -2820,62 +2826,62 @@ static const struct usb_action icm105axx_Initial[] = { {0xaa, 0x24, 0x0080}, {0xaa, 0x26, 0x0080}, {0xaa, 0x00, 0x0084}, - {0xa0, 0x02, 0x00a3}, - {0xa0, 0x94, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x04, 0x0191}, - {0xa0, 0x20, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x84, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x12, 0x01aa}, - {0xa0, 0xe3, 0x001d}, - {0xa0, 0xec, 0x001e}, - {0xa0, 0xf5, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0xc0, 0x01a8}, - {0xa0, 0xc0, 0x011d}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0xc0, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action icm105axx_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0c, 0x0010}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0xa1, 0x008b}, - {0xa0, 0x00, 0x0097}, - {0xa0, 0x02, 0x0098}, - {0xa0, 0x00, 0x0099}, - {0xa0, 0x02, 0x009a}, - {0xa0, 0x02, 0x011a}, - {0xa0, 0x02, 0x011c}, - {0xa0, 0x01, 0x009b}, - {0xa0, 0xe6, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x86, 0x009e}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0c, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x00, ZC3XX_R097_WINYSTARTHIGH}, + {0xa0, 0x02, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R099_WINXSTARTHIGH}, + {0xa0, 0x02, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x02, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x02, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, {0xaa, 0x01, 0x0010}, {0xaa, 0x03, 0x0000}, {0xaa, 0x04, 0x0001}, @@ -2903,9 +2909,9 @@ static const struct usb_action icm105axx_InitialScale[] = { {0xaa, 0x06, 0x000d}, {0xaa, 0x08, 0x0000}, {0xaa, 0x03, 0x0005}, - {0xa0, 0x04, 0x0092}, - {0xa0, 0x19, 0x0093}, - {0xa0, 0x01, 0x0090}, + {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x19, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xaa, 0x05, 0x0020}, {0xaa, 0x06, 0x0005}, @@ -2959,38 +2965,38 @@ static const struct usb_action icm105axx_InitialScale[] = { {0xaa, 0x24, 0x0080}, {0xaa, 0x26, 0x0080}, {0xaa, 0x00, 0x0084}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xaa, 0xa8, 0x0080}, - {0xa0, 0x78, 0x018d}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x52, 0x010a}, /* matrix */ - {0xa0, 0xf7, 0x010b}, - {0xa0, 0xf7, 0x010c}, - {0xa0, 0xf7, 0x010d}, - {0xa0, 0x52, 0x010e}, - {0xa0, 0xf7, 0x010f}, - {0xa0, 0xf7, 0x0110}, - {0xa0, 0xf7, 0x0111}, - {0xa0, 0x52, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x52, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf7, ZC3XX_R10B_RGB01}, + {0xa0, 0xf7, ZC3XX_R10C_RGB02}, + {0xa0, 0xf7, ZC3XX_R10D_RGB10}, + {0xa0, 0x52, ZC3XX_R10E_RGB11}, + {0xa0, 0xf7, ZC3XX_R10F_RGB12}, + {0xa0, 0xf7, ZC3XX_R110_RGB20}, + {0xa0, 0xf7, ZC3XX_R111_RGB21}, + {0xa0, 0x52, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x0d, 0x0003}, {0xaa, 0x0c, 0x0020}, {0xaa, 0x0e, 0x000e}, @@ -3002,33 +3008,33 @@ static const struct usb_action icm105axx_InitialScale[] = { {0xaa, 0x24, 0x0080}, {0xaa, 0x26, 0x0080}, {0xaa, 0x00, 0x0084}, - {0xa0, 0x02, 0x00a3}, - {0xa0, 0x0d, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x04, 0x0191}, - {0xa0, 0x1a, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x4b, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x12, 0x01aa}, - {0xa0, 0xc8, 0x001d}, - {0xa0, 0xd8, 0x001e}, - {0xa0, 0xea, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x00, 0x01a7}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, - {0xa0, 0x40, 0x0116}, - {0xa0, 0x40, 0x0117}, - {0xa0, 0x40, 0x0118}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action icm105a_50HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0020}, /* 00,0c,20,aa */ {0xaa, 0x0e, 0x000e}, /* 00,0e,0e,aa */ @@ -3040,26 +3046,26 @@ static const struct usb_action icm105a_50HZ[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x0d, 0x00a4}, /* 00,a4,0d,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x1a, 0x0192}, /* 01,92,1a,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x4b, 0x0197}, /* 01,97,4b,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ - {0xa0, 0xc8, 0x001d}, /* 00,1d,c8,cc */ - {0xa0, 0xd8, 0x001e}, /* 00,1e,d8,cc */ - {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x0d, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,0d,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x1a, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,1a,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x4b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,4b,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ + {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ + {0xa0, 0xd8, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d8,cc */ + {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {} }; static const struct usb_action icm105a_50HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x008c}, /* 00,0c,8c,aa */ {0xaa, 0x0e, 0x0095}, /* 00,0e,95,aa */ @@ -3071,28 +3077,28 @@ static const struct usb_action icm105a_50HZScale[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x94, 0x00a4}, /* 00,a4,94,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x84, 0x0197}, /* 01,97,84,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ - {0xa0, 0xe3, 0x001d}, /* 00,1d,e3,cc */ - {0xa0, 0xec, 0x001e}, /* 00,1e,ec,cc */ - {0xa0, 0xf5, 0x001f}, /* 00,1f,f5,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ - {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x94, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,94,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x84, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,84,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ + {0xa0, 0xe3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e3,cc */ + {0xa0, 0xec, ZC3XX_R01E_HSYNC_1}, /* 00,1e,ec,cc */ + {0xa0, 0xf5, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f5,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ + {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ {} }; static const struct usb_action icm105a_60HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ @@ -3104,26 +3110,26 @@ static const struct usb_action icm105a_60HZ[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x08, 0x00a4}, /* 00,a4,08,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x10, 0x0192}, /* 01,92,10,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x41, 0x0197}, /* 01,97,41,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ - {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x08, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,08,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x41, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,41,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ + {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {} }; static const struct usb_action icm105a_60HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0008}, /* 00,0c,08,aa */ {0xaa, 0x0e, 0x0086}, /* 00,0e,86,aa */ @@ -3135,28 +3141,28 @@ static const struct usb_action icm105a_60HZScale[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x85, 0x00a4}, /* 00,a4,85,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x08, 0x0192}, /* 01,92,08,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x81, 0x0197}, /* 01,97,81,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x12, 0x01aa}, /* 01,aa,12,cc */ - {0xa0, 0xc2, 0x001d}, /* 00,1d,c2,cc */ - {0xa0, 0xd6, 0x001e}, /* 00,1e,d6,cc */ - {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ - {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x85, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,85,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x08, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,08,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x81, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,81,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x12, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,12,cc */ + {0xa0, 0xc2, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c2,cc */ + {0xa0, 0xd6, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d6,cc */ + {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ + {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ {} }; static const struct usb_action icm105a_NoFliker[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ {0xaa, 0x0e, 0x000d}, /* 00,0e,0d,aa */ @@ -3168,26 +3174,26 @@ static const struct usb_action icm105a_NoFliker[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x00, 0x00a4}, /* 00,a4,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x00, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ {} }; static const struct usb_action icm105a_NoFlikerScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0x0d, 0x0003}, /* 00,0d,03,aa */ {0xaa, 0x0c, 0x0004}, /* 00,0c,04,aa */ {0xaa, 0x0e, 0x0081}, /* 00,0e,81,aa */ @@ -3199,52 +3205,52 @@ static const struct usb_action icm105a_NoFlikerScale[] = { {0xaa, 0x24, 0x0080}, /* 00,24,80,aa */ {0xaa, 0x26, 0x0080}, /* 00,26,80,aa */ {0xaa, 0x00, 0x0084}, /* 00,00,84,aa */ - {0xa0, 0x02, 0x00a3}, /* 00,a3,02,cc */ - {0xa0, 0x80, 0x00a4}, /* 00,a4,80,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x20, 0x0192}, /* 01,92,20,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0xc1, 0x001d}, /* 00,1d,c1,cc */ - {0xa0, 0xd4, 0x001e}, /* 00,1e,d4,cc */ - {0xa0, 0xe8, 0x001f}, /* 00,1f,e8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x00, 0x01a7}, /* 01,a7,00,cc */ - {0xa0, 0xc0, 0x01a8}, /* 01,a8,c0,cc */ + {0xa0, 0x02, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,02,cc */ + {0xa0, 0x80, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,80,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x20, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,20,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0xc1, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c1,cc */ + {0xa0, 0xd4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d4,cc */ + {0xa0, 0xe8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN}, /* 01,a7,00,cc */ + {0xa0, 0xc0, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,c0,cc */ {} }; static const struct usb_action MC501CB_InitialScale[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x00, 0x0002}, /* 00,02,00,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xd8, 0x0006}, /* 00,06,d8,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0x01, 0x009b}, /* 00,9b,01,cc */ - {0xa0, 0xde, 0x009c}, /* 00,9c,de,cc */ - {0xa0, 0x02, 0x009d}, /* 00,9d,02,cc */ - {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ - {0xa0, 0x33, 0x0086}, /* 00,86,33,cc */ - {0xa0, 0x34, 0x0087}, /* 00,87,34,cc */ - {0xa0, 0x35, 0x0088}, /* 00,88,35,cc */ - {0xa0, 0xb0, 0x008b}, /* 00,8b,b0,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ + {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ + {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ + {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ + {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ + {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ @@ -3280,7 +3286,7 @@ static const struct usb_action MC501CB_InitialScale[] = { {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ - {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ + {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ @@ -3312,15 +3318,15 @@ static const struct usb_action MC501CB_InitialScale[] = { {0xaa, 0x3e, 0x006a}, /* 00,3e,6A,aa */ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x37, 0x0101}, /* 01,01,37,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ {0xaa, 0x51, 0x0027}, /* 00,51,27,aa */ {0xaa, 0x52, 0x0020}, /* 00,52,20,aa */ @@ -3341,30 +3347,30 @@ static const struct usb_action MC501CB_InitialScale[] = { }; static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xd0, 0x0006}, /* 00,06,d0,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0x01, 0x009b}, /* 00,9b,01,cc */ - {0xa0, 0xd8, 0x009c}, /* 00,9c,d8,cc */ - {0xa0, 0x02, 0x009d}, /* 00,9d,02,cc */ - {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ - {0xa0, 0x33, 0x0086}, /* 00,86,33,cc */ - {0xa0, 0x34, 0x0087}, /* 00,87,34,cc */ - {0xa0, 0x35, 0x0088}, /* 00,88,35,cc */ - {0xa0, 0xb0, 0x008b}, /* 00,8b,b0,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, /* 00,9b,01,cc */ + {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */ + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, /* 00,9d,02,cc */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ + {0xa0, 0x33, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,33,cc */ + {0xa0, 0x34, ZC3XX_R087_EXPTIMEMID}, /* 00,87,34,cc */ + {0xa0, 0x35, ZC3XX_R088_EXPTIMELOW}, /* 00,88,35,cc */ + {0xa0, 0xb0, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,b0,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ {0xaa, 0x01, 0x0003}, /* 00,01,03,aa */ {0xaa, 0x01, 0x0001}, /* 00,01,01,aa */ @@ -3400,7 +3406,7 @@ static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ - {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */ + {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ @@ -3432,15 +3438,15 @@ static const struct usb_action MC501CB_Initial[] = { /* 320x240 */ {0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */ {0xaa, 0x01, 0x0000}, /* 00,01,00,aa */ {0xaa, 0x52, 0x00ff}, /* 00,52,FF,aa */ - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x37, 0x0101}, /* 01,01,37,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ {0xaa, 0x03, 0x0002}, /* 00,03,02,aa */ {0xaa, 0x51, 0x004e}, /* 00,51,4E,aa */ {0xaa, 0x52, 0x0041}, /* 00,52,41,aa */ @@ -3558,30 +3564,30 @@ static const struct usb_action MC501CB_NoFlikerScale[] = { /* from zs211.inf - HKR,%OV7620%,Initial - 640x480 */ static const struct usb_action OV7620_mode0[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x40, 0x0002}, /* 00,02,40,cc */ - {0xa0, 0x00, 0x0008}, /* 00,08,00,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x06, 0x0010}, /* 00,10,06,cc */ - {0xa0, 0x02, 0x0083}, /* 00,83,02,cc */ - {0xa0, 0x01, 0x0085}, /* 00,85,01,cc */ - {0xa0, 0x80, 0x0086}, /* 00,86,80,cc */ - {0xa0, 0x81, 0x0087}, /* 00,87,81,cc */ - {0xa0, 0x10, 0x0088}, /* 00,88,10,cc */ - {0xa0, 0xa1, 0x008b}, /* 00,8b,a1,cc */ - {0xa0, 0x08, 0x008d}, /* 00,8d,08,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xd8, 0x0006}, /* 00,06,d8,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xde, 0x009c}, /* 00,9c,de,cc */ - {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, /* 00,02,40,cc */ + {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ + {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ + {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ + {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ + {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ + {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */ + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ @@ -3610,49 +3616,51 @@ static const struct usb_action OV7620_mode0[] = { {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ - {0xa0, 0x77, 0x0101}, /* 01,01,77,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x68, 0x0116}, /* 01,16,68,cc */ - {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ - {0xa0, 0x40, 0x011d}, /* 01,1d,40,cc */ - {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ - {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ + {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ + {0xa0, 0x40, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,40,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ {} }; /* from zs211.inf - HKR,%OV7620%,InitialScale - 320x240 */ static const struct usb_action OV7620_mode1[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x50, 0x0002}, /* 00,02,50,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,00,cc */ /* mx change? */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x06, 0x0010}, /* 00,10,06,cc */ - {0xa0, 0x02, 0x0083}, /* 00,83,02,cc */ - {0xa0, 0x01, 0x0085}, /* 00,85,01,cc */ - {0xa0, 0x80, 0x0086}, /* 00,86,80,cc */ - {0xa0, 0x81, 0x0087}, /* 00,87,81,cc */ - {0xa0, 0x10, 0x0088}, /* 00,88,10,cc */ - {0xa0, 0xa1, 0x008b}, /* 00,8b,a1,cc */ - {0xa0, 0x08, 0x008d}, /* 00,8d,08,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xd0, 0x0006}, /* 00,06,d0,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xd6, 0x009c}, /* 00,9c,d6,cc */ /* OV7648 00,9c,d8,cc */ - {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, /* 00,02,50,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,00,cc */ + /* mx change? */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,06,cc */ + {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, /* 00,83,02,cc */ + {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, /* 00,85,01,cc */ + {0xa0, 0x80, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,80,cc */ + {0xa0, 0x81, ZC3XX_R087_EXPTIMEMID}, /* 00,87,81,cc */ + {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, /* 00,88,10,cc */ + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,a1,cc */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* 00,8d,08,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xd6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d6,cc */ + /* OV7648 00,9c,d8,cc */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ {0xaa, 0x12, 0x0088}, /* 00,12,88,aa */ {0xaa, 0x12, 0x0048}, /* 00,12,48,aa */ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ @@ -3681,20 +3689,20 @@ static const struct usb_action OV7620_mode1[] = { {0xaa, 0x06, 0x0080}, /* 00,06,80,aa */ {0xaa, 0x01, 0x0090}, /* 00,01,90,aa */ {0xaa, 0x02, 0x0030}, /* 00,02,30,aa */ - {0xa0, 0x77, 0x0101}, /* 01,01,77,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ - {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x68, 0x0116}, /* 01,16,68,cc */ - {0xa0, 0x52, 0x0118}, /* 01,18,52,cc */ - {0xa0, 0x50, 0x011d}, /* 01,1d,50,cc */ - {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ - {0xa0, 0x50, 0x01a8}, /* 01,a8,50,cc */ + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,77,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ + {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x68, ZC3XX_R116_RGAIN}, /* 01,16,68,cc */ + {0xa0, 0x52, ZC3XX_R118_BGAIN}, /* 01,18,52,cc */ + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,50,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ + {0xa0, 0x50, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,50,cc */ {} }; @@ -3705,34 +3713,37 @@ static const struct usb_action OV7620_50HZ[] = { {0xaa, 0x2b, 0x0096}, /* 00,2b,96,aa */ {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ - {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ - {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ -/* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ + {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ + {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ +/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc + if mode0 (640x480) */ {} }; /* from zs211.inf - HKR,%OV7620%\AE,60HZ */ static const struct usb_action OV7620_60HZ[] = { - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ - {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ - {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x83, 0x0197}, /* 01,97,83,cc */ - {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */ - {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ -/* {0xa0, 0x40, 0x0002}, * 00,02,40,cc - if mode0 (640x480) */ + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ + /* (bug in zs211.inf) */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ + {0xaa, 0x75, 0x008a}, /* 00,75,8a,aa */ + {0xaa, 0x2d, 0x0005}, /* 00,2d,05,aa */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x83, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,83,cc */ + {0xaa, 0x10, 0x0020}, /* 00,10,20,aa */ + {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ +/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc + * if mode0 (640x480) */ /* ?? in gspca v1, it was {0xa0, 0x00, 0x0039}, * 00,00,00,dd * {0xa1, 0x01, 0x0037}, */ @@ -3741,18 +3752,20 @@ static const struct usb_action OV7620_60HZ[] = { /* from zs211.inf - HKR,%OV7620%\AE,NoFliker */ static const struct usb_action OV7620_NoFliker[] = { - {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ /* (bug in zs211.inf) */ - {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ - {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ - {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */ - {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x04, 0x0191}, /* 01,91,04,cc */ - {0xa0, 0x18, 0x0192}, /* 01,92,18,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x01, 0x0197}, /* 01,97,01,cc */ -/* {0xa0, 0x44, 0x0002}, * 00,02,44,cc - if mode1 (320x240) */ + {0xaa, 0x13, 0x00a3}, /* 00,13,a3,aa */ + /* (bug in zs211.inf) */ + {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */ + {0xaa, 0x2b, 0x0000}, /* 00,2b,00,aa */ + {0xaa, 0x75, 0x008e}, /* 00,75,8e,aa */ + {0xaa, 0x2d, 0x0001}, /* 00,2d,01,aa */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x04, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,04,cc */ + {0xa0, 0x18, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,18,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x01, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,01,cc */ +/* {0xa0, 0x44, ZC3XX_R002_CLOCKSELECT}, * 00,02,44,cc + - if mode1 (320x240) */ /* ?? was {0xa0, 0x00, 0x0039}, * 00,00,00,dd * {0xa1, 0x01, 0x0037}, */ @@ -3760,32 +3773,32 @@ static const struct usb_action OV7620_NoFliker[] = { }; static const struct usb_action ov7630c_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x06, 0x0010}, - {0xa0, 0xa1, 0x008b}, - {0xa0, 0x08, 0x008d}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x12, 0x0080}, - {0xa0, 0x02, 0x0083}, - {0xa0, 0x01, 0x0085}, - {0xa0, 0x90, 0x0086}, - {0xa0, 0x91, 0x0087}, - {0xa0, 0x10, 0x0088}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xd8, 0x009c}, - {0xa0, 0x88, 0x009e}, + {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, + {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, + {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, + {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x12, 0x0069}, {0xaa, 0x04, 0x0020}, {0xaa, 0x06, 0x0050}, @@ -3817,131 +3830,131 @@ static const struct usb_action ov7630c_Initial[] = { {0xaa, 0x77, 0x00b5}, {0xaa, 0x01, 0x0060}, {0xaa, 0x02, 0x0060}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x04, 0x01a7}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x46, 0x0118}, - {0xa0, 0x04, 0x0113}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x46, ZC3XX_R118_BGAIN}, + {0xa0, 0x04, ZC3XX_R113_RGB03}, /* 0x10, */ {0xa1, 0x01, 0x0002}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, /* 0x03, */ {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x01, 0x0120}, /* gamma 2 ?*/ - {0xa0, 0x0c, 0x0121}, - {0xa0, 0x1f, 0x0122}, - {0xa0, 0x3a, 0x0123}, - {0xa0, 0x53, 0x0124}, - {0xa0, 0x6d, 0x0125}, - {0xa0, 0x85, 0x0126}, - {0xa0, 0x9c, 0x0127}, - {0xa0, 0xb0, 0x0128}, - {0xa0, 0xc2, 0x0129}, - {0xa0, 0xd1, 0x012a}, - {0xa0, 0xde, 0x012b}, - {0xa0, 0xe9, 0x012c}, - {0xa0, 0xf2, 0x012d}, - {0xa0, 0xf9, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x05, 0x0130}, - {0xa0, 0x0f, 0x0131}, - {0xa0, 0x16, 0x0132}, - {0xa0, 0x1a, 0x0133}, - {0xa0, 0x19, 0x0134}, - {0xa0, 0x19, 0x0135}, - {0xa0, 0x17, 0x0136}, - {0xa0, 0x15, 0x0137}, - {0xa0, 0x12, 0x0138}, - {0xa0, 0x10, 0x0139}, - {0xa0, 0x0e, 0x013a}, - {0xa0, 0x0b, 0x013b}, - {0xa0, 0x09, 0x013c}, - {0xa0, 0x08, 0x013d}, - {0xa0, 0x06, 0x013e}, - {0xa0, 0x03, 0x013f}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x01, ZC3XX_R120_GAMMA00}, /* gamma 2 ?*/ + {0xa0, 0x0c, ZC3XX_R121_GAMMA01}, + {0xa0, 0x1f, ZC3XX_R122_GAMMA02}, + {0xa0, 0x3a, ZC3XX_R123_GAMMA03}, + {0xa0, 0x53, ZC3XX_R124_GAMMA04}, + {0xa0, 0x6d, ZC3XX_R125_GAMMA05}, + {0xa0, 0x85, ZC3XX_R126_GAMMA06}, + {0xa0, 0x9c, ZC3XX_R127_GAMMA07}, + {0xa0, 0xb0, ZC3XX_R128_GAMMA08}, + {0xa0, 0xc2, ZC3XX_R129_GAMMA09}, + {0xa0, 0xd1, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xde, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xe9, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf2, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xf9, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x05, ZC3XX_R130_GAMMA10}, + {0xa0, 0x0f, ZC3XX_R131_GAMMA11}, + {0xa0, 0x16, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, + {0xa0, 0x19, ZC3XX_R134_GAMMA14}, + {0xa0, 0x19, ZC3XX_R135_GAMMA15}, + {0xa0, 0x17, ZC3XX_R136_GAMMA16}, + {0xa0, 0x15, ZC3XX_R137_GAMMA17}, + {0xa0, 0x12, ZC3XX_R138_GAMMA18}, + {0xa0, 0x10, ZC3XX_R139_GAMMA19}, + {0xa0, 0x0e, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x0b, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x09, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x08, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x06, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x03, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, {0xaa, 0x10, 0x001b}, {0xaa, 0x76, 0x0002}, {0xaa, 0x2a, 0x0081}, {0xaa, 0x2b, 0x0000}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x01, 0x0191}, - {0xa0, 0xb8, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x37, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x26, 0x01aa}, - {0xa0, 0x50, 0x011d}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xb8, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x37, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xaa, 0x13, 0x0083}, /* 40 */ {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action ov7630c_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x06, 0x0010}, - {0xa0, 0xa1, 0x008b}, - {0xa0, 0x08, 0x008d}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x06, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0xa1, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x12, 0x0080}, - {0xa0, 0x02, 0x0083}, - {0xa0, 0x01, 0x0085}, - {0xa0, 0x90, 0x0086}, - {0xa0, 0x91, 0x0087}, - {0xa0, 0x10, 0x0088}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xe6, 0x009c}, - {0xa0, 0x86, 0x009e}, + {0xa0, 0x02, ZC3XX_R083_RGAINADDR}, + {0xa0, 0x01, ZC3XX_R085_BGAINADDR}, + {0xa0, 0x90, ZC3XX_R086_EXPTIMEHIGH}, + {0xa0, 0x91, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x10, ZC3XX_R088_EXPTIMELOW}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, {0xaa, 0x12, 0x0069}, /* i2c */ {0xaa, 0x04, 0x0020}, {0xaa, 0x06, 0x0050}, @@ -3973,103 +3986,103 @@ static const struct usb_action ov7630c_InitialScale[] = { {0xaa, 0x02, 0x0060}, {0xaa, 0x17, 0x0018}, {0xaa, 0x18, 0x00ba}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x77, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x04, 0x01a7}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x77, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x0116}, - {0xa0, 0x46, 0x0118}, - {0xa0, 0x04, 0x0113}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R116_RGAIN}, + {0xa0, 0x46, ZC3XX_R118_BGAIN}, + {0xa0, 0x04, ZC3XX_R113_RGB03}, {0xa1, 0x01, 0x0002}, - {0xa0, 0x4e, 0x010a}, /* matrix */ - {0xa0, 0xfe, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf7, 0x010d}, - {0xa0, 0x4d, 0x010e}, - {0xa0, 0xfc, 0x010f}, - {0xa0, 0x00, 0x0110}, - {0xa0, 0xf6, 0x0111}, - {0xa0, 0x4a, 0x0112}, + {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xfe, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf7, ZC3XX_R10D_RGB10}, + {0xa0, 0x4d, ZC3XX_R10E_RGB11}, + {0xa0, 0xfc, ZC3XX_R10F_RGB12}, + {0xa0, 0x00, ZC3XX_R110_RGB20}, + {0xa0, 0xf6, ZC3XX_R111_RGB21}, + {0xa0, 0x4a, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x16, 0x0120}, /* gamma ~4 */ - {0xa0, 0x3a, 0x0121}, - {0xa0, 0x5b, 0x0122}, - {0xa0, 0x7c, 0x0123}, - {0xa0, 0x94, 0x0124}, - {0xa0, 0xa9, 0x0125}, - {0xa0, 0xbb, 0x0126}, - {0xa0, 0xca, 0x0127}, - {0xa0, 0xd7, 0x0128}, - {0xa0, 0xe1, 0x0129}, - {0xa0, 0xea, 0x012a}, - {0xa0, 0xf1, 0x012b}, - {0xa0, 0xf7, 0x012c}, - {0xa0, 0xfc, 0x012d}, - {0xa0, 0xff, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x20, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x00, 0x013e}, - {0xa0, 0x01, 0x013f}, - {0xa0, 0x4e, 0x010a}, /* matrix */ - {0xa0, 0xfe, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf7, 0x010d}, - {0xa0, 0x4d, 0x010e}, - {0xa0, 0xfc, 0x010f}, - {0xa0, 0x00, 0x0110}, - {0xa0, 0xf6, 0x0111}, - {0xa0, 0x4a, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x16, ZC3XX_R120_GAMMA00}, /* gamma ~4 */ + {0xa0, 0x3a, ZC3XX_R121_GAMMA01}, + {0xa0, 0x5b, ZC3XX_R122_GAMMA02}, + {0xa0, 0x7c, ZC3XX_R123_GAMMA03}, + {0xa0, 0x94, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa9, ZC3XX_R125_GAMMA05}, + {0xa0, 0xbb, ZC3XX_R126_GAMMA06}, + {0xa0, 0xca, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd7, ZC3XX_R128_GAMMA08}, + {0xa0, 0xe1, ZC3XX_R129_GAMMA09}, + {0xa0, 0xea, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xf1, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf7, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xfc, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x20, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x4e, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xfe, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf7, ZC3XX_R10D_RGB10}, + {0xa0, 0x4d, ZC3XX_R10E_RGB11}, + {0xa0, 0xfc, ZC3XX_R10F_RGB12}, + {0xa0, 0x00, ZC3XX_R110_RGB20}, + {0xa0, 0xf6, ZC3XX_R111_RGB21}, + {0xa0, 0x4a, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, {0xaa, 0x10, 0x000d}, {0xaa, 0x76, 0x0002}, {0xaa, 0x2a, 0x0081}, {0xaa, 0x2b, 0x0000}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x00, 0x0191}, - {0xa0, 0xd8, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x1b, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x10, 0x01a9}, - {0xa0, 0x26, 0x01aa}, - {0xa0, 0x50, 0x011d}, - {0xa0, 0x02, 0x0180}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x00, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xd8, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x1b, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xaa, 0x13, 0x00c3}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; @@ -4077,10 +4090,10 @@ static const struct usb_action pas106b_Initial_com[] = { /* Sream and Sensor specific */ {0xa1, 0x01, 0x0010}, /* CMOSSensorSelect */ /* System */ - {0xa0, 0x01, 0x0000}, /* SystemControl */ - {0xa0, 0x01, 0x0000}, /* SystemControl */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* SystemControl */ /* Picture size */ - {0xa0, 0x00, 0x0002}, /* ClockSelect */ + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* ClockSelect */ {0xa0, 0x03, 0x003a}, {0xa0, 0x0c, 0x003b}, {0xa0, 0x04, 0x0038}, @@ -4089,27 +4102,27 @@ static const struct usb_action pas106b_Initial_com[] = { static const struct usb_action pas106b_Initial[] = { /* 176x144 */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ /* Sream and Sensor specific */ - {0xa0, 0x0f, 0x0010}, /* CMOSSensorSelect */ + {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ /* Picture size */ - {0xa0, 0x00, 0x0003}, /* FrameWidthHigh 00 */ - {0xa0, 0xb0, 0x0004}, /* FrameWidthLow B0 */ - {0xa0, 0x00, 0x0005}, /* FrameHeightHigh 00 */ - {0xa0, 0x90, 0x0006}, /* FrameHightLow 90 */ + {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh 00 */ + {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow B0 */ + {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */ + {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow 90 */ /* System */ - {0xa0, 0x01, 0x0001}, /* SystemOperating */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ /* Sream and Sensor specific */ - {0xa0, 0x03, 0x0012}, /* VideoControlFunction */ - {0xa0, 0x01, 0x0012}, /* VideoControlFunction */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ /* Sensor Interface */ - {0xa0, 0x08, 0x008d}, /* Compatibily Mode */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ /* Window inside sensor array */ - {0xa0, 0x03, 0x009a}, /* WinXStartLow */ - {0xa0, 0x00, 0x011a}, /* FirstYLow */ - {0xa0, 0x03, 0x011c}, /* FirstxLow */ - {0xa0, 0x28, 0x009c}, /* WinHeightLow */ - {0xa0, 0x68, 0x009e}, /* WinWidthLow */ + {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ + {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ + {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ + {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ /* Init the sensor */ {0xaa, 0x02, 0x0004}, {0xaa, 0x08, 0x0000}, @@ -4122,112 +4135,112 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xaa, 0x14, 0x0081}, /* Other registors */ - {0xa0, 0x37, 0x0101}, /* SensorCorrection */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ /* Frame retreiving */ - {0xa0, 0x00, 0x0019}, /* AutoAdjustFPS */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ /* Gains */ - {0xa0, 0xa0, 0x01a8}, /* DigitalGain */ + {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ /* Unknown */ {0xa0, 0x00, 0x01ad}, /* Sharpness */ - {0xa0, 0x03, 0x01c5}, /* SharpnessMode */ - {0xa0, 0x13, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ /* Other registors */ - {0xa0, 0x0d, 0x0100}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ /* Auto exposure and white balance */ - {0xa0, 0x06, 0x0189}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ /*Dead pixels */ - {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ /* EEPROM */ - {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ /* Other registers */ - {0xa0, 0x0d, 0x0100}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ /* Auto exposure and white balance */ - {0xa0, 0x06, 0x0189}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ /*Dead pixels */ - {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ /* EEPROM */ - {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, /* Auto correction */ - {0xa0, 0x03, 0x0181}, /* WinXstart */ - {0xa0, 0x08, 0x0182}, /* WinXWidth */ - {0xa0, 0x16, 0x0183}, /* WinXCenter */ - {0xa0, 0x03, 0x0184}, /* WinYStart */ - {0xa0, 0x05, 0x0185}, /* WinYWidth */ - {0xa0, 0x14, 0x0186}, /* WinYCenter */ - {0xa0, 0x00, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ + {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ + {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ + {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ + {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ + {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ /* Auto exposure and white balance */ - {0xa0, 0x00, 0x0190}, /* ExposureLimitHigh */ - {0xa0, 0x03, 0x0191}, /* ExposureLimitMid */ - {0xa0, 0xb1, 0x0192}, /* ExposureLimitLow */ - {0xa0, 0x00, 0x0195}, /* AntiFlickerHigh */ - {0xa0, 0x00, 0x0196}, /* AntiFlickerLow */ - {0xa0, 0x87, 0x0197}, /* AntiFlickerLow */ - {0xa0, 0x0c, 0x018c}, /* AEBFreeze */ - {0xa0, 0x18, 0x018f}, /* AEBUnfreeze */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ + {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow */ + {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze */ + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze */ /* sensor on */ {0xaa, 0x07, 0x00b1}, {0xaa, 0x05, 0x0003}, {0xaa, 0x04, 0x0001}, {0xaa, 0x03, 0x003b}, /* Gains */ - {0xa0, 0x20, 0x01a9}, /* DigitalLimitDiff */ - {0xa0, 0x26, 0x01aa}, /* DigitalGainStep */ - {0xa0, 0xa0, 0x011d}, /* GlobalGain */ - {0xa0, 0x60, 0x011d}, /* GlobalGain */ + {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ + {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ /* Auto correction */ - {0xa0, 0x40, 0x0180}, /* AutoCorrectEnable */ - {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ /* Gains */ - {0xa0, 0x40, 0x0116}, /* RGain */ - {0xa0, 0x40, 0x0117}, /* GGain */ - {0xa0, 0x40, 0x0118}, /* BGain */ + {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ + {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ + {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ {} }; static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ /* Sream and Sensor specific */ - {0xa0, 0x0f, 0x0010}, /* CMOSSensorSelect */ + {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ /* Picture size */ - {0xa0, 0x01, 0x0003}, /* FrameWidthHigh */ - {0xa0, 0x60, 0x0004}, /* FrameWidthLow */ - {0xa0, 0x01, 0x0005}, /* FrameHeightHigh */ - {0xa0, 0x20, 0x0006}, /* FrameHightLow */ + {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh */ + {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh */ + {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow */ /* System */ - {0xa0, 0x01, 0x0001}, /* SystemOperating */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ /* Sream and Sensor specific */ - {0xa0, 0x03, 0x0012}, /* VideoControlFunction */ - {0xa0, 0x01, 0x0012}, /* VideoControlFunction */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ /* Sensor Interface */ - {0xa0, 0x08, 0x008d}, /* Compatibily Mode */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ /* Window inside sensor array */ - {0xa0, 0x03, 0x009a}, /* WinXStartLow */ - {0xa0, 0x00, 0x011a}, /* FirstYLow */ - {0xa0, 0x03, 0x011c}, /* FirstxLow */ - {0xa0, 0x28, 0x009c}, /* WinHeightLow */ - {0xa0, 0x68, 0x009e}, /* WinWidthLow */ + {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ + {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ + {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ + {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ /* Init the sensor */ {0xaa, 0x02, 0x0004}, {0xaa, 0x08, 0x0000}, @@ -4240,161 +4253,161 @@ static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xaa, 0x14, 0x0081}, /* Other registors */ - {0xa0, 0x37, 0x0101}, /* SensorCorrection */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ /* Frame retreiving */ - {0xa0, 0x00, 0x0019}, /* AutoAdjustFPS */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ /* Gains */ - {0xa0, 0xa0, 0x01a8}, /* DigitalGain */ + {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ /* Unknown */ {0xa0, 0x00, 0x01ad}, /* Sharpness */ - {0xa0, 0x03, 0x01c5}, /* SharpnessMode */ - {0xa0, 0x13, 0x01cb}, /* Sharpness05 */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ /* Other registors */ - {0xa0, 0x0d, 0x0100}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ /* Auto exposure and white balance */ - {0xa0, 0x06, 0x0189}, /* AWBStatus */ - {0xa0, 0x80, 0x018d}, /* ????????? */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* ????????? */ /*Dead pixels */ - {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ /* EEPROM */ - {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ /* Other registers */ - {0xa0, 0x0d, 0x0100}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ /* Auto exposure and white balance */ - {0xa0, 0x06, 0x0189}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ /*Dead pixels */ - {0xa0, 0x08, 0x0250}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ /* EEPROM */ - {0xa0, 0x08, 0x0301}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ /* JPEG control */ - {0xa0, 0x03, 0x0008}, /* ClockSetting */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x58, 0x010a}, /* matrix */ - {0xa0, 0xf4, 0x010b}, - {0xa0, 0xf4, 0x010c}, - {0xa0, 0xf4, 0x010d}, - {0xa0, 0x58, 0x010e}, - {0xa0, 0xf4, 0x010f}, - {0xa0, 0xf4, 0x0110}, - {0xa0, 0xf4, 0x0111}, - {0xa0, 0x58, 0x0112}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf4, ZC3XX_R10B_RGB01}, + {0xa0, 0xf4, ZC3XX_R10C_RGB02}, + {0xa0, 0xf4, ZC3XX_R10D_RGB10}, + {0xa0, 0x58, ZC3XX_R10E_RGB11}, + {0xa0, 0xf4, ZC3XX_R10F_RGB12}, + {0xa0, 0xf4, ZC3XX_R110_RGB20}, + {0xa0, 0xf4, ZC3XX_R111_RGB21}, + {0xa0, 0x58, ZC3XX_R112_RGB22}, /* Auto correction */ - {0xa0, 0x03, 0x0181}, /* WinXstart */ - {0xa0, 0x08, 0x0182}, /* WinXWidth */ - {0xa0, 0x16, 0x0183}, /* WinXCenter */ - {0xa0, 0x03, 0x0184}, /* WinYStart */ - {0xa0, 0x05, 0x0185}, /* WinYWidth */ - {0xa0, 0x14, 0x0186}, /* WinYCenter */ - {0xa0, 0x00, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ + {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ + {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ + {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ + {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ + {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ /* Auto exposure and white balance */ - {0xa0, 0x00, 0x0190}, /* ExposureLimitHigh 0 */ - {0xa0, 0x03, 0x0191}, /* ExposureLimitMid */ - {0xa0, 0xb1, 0x0192}, /* ExposureLimitLow 0xb1 */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ + {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow 0xb1 */ - {0xa0, 0x00, 0x0195}, /* AntiFlickerHigh 0x00 */ - {0xa0, 0x00, 0x0196}, /* AntiFlickerLow 0x00 */ - {0xa0, 0x87, 0x0197}, /* AntiFlickerLow 0x87 */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh 0x00 */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow 0x00 */ + {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow 0x87 */ - {0xa0, 0x10, 0x018c}, /* AEBFreeze 0x10 0x0c */ - {0xa0, 0x20, 0x018f}, /* AEBUnfreeze 0x30 0x18 */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze 0x10 0x0c */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze 0x30 0x18 */ /* sensor on */ {0xaa, 0x07, 0x00b1}, {0xaa, 0x05, 0x0003}, {0xaa, 0x04, 0x0001}, {0xaa, 0x03, 0x003b}, /* Gains */ - {0xa0, 0x20, 0x01a9}, /* DigitalLimitDiff */ - {0xa0, 0x26, 0x01aa}, /* DigitalGainStep */ - {0xa0, 0xa0, 0x011d}, /* GlobalGain */ - {0xa0, 0x60, 0x011d}, /* GlobalGain */ + {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ + {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ /* Auto correction */ - {0xa0, 0x40, 0x0180}, /* AutoCorrectEnable */ - {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ /* Gains */ - {0xa0, 0x40, 0x0116}, /* RGain */ - {0xa0, 0x40, 0x0117}, /* GGain */ - {0xa0, 0x40, 0x0118}, /* BGain */ + {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ + {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ + {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ - {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ - {0xa0, 0xff, 0x0018}, /* Frame adjust */ + {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ + {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */ {} }; static const struct usb_action pas106b_50HZ[] = { - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ - {0xa0, 0x54, 0x0192}, /* 01,92,54,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x87, 0x0197}, /* 01,97,87,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x30, 0x018f}, /* 01,8f,30,cc */ - {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */ - {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */ - {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ - {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ - {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ + {0xa0, 0x54, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,54,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,87,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ + {0xaa, 0x03, 0x0021}, /* 00,03,21,aa */ + {0xaa, 0x04, 0x000c}, /* 00,04,0c,aa */ + {0xaa, 0x05, 0x0002}, /* 00,05,02,aa */ + {0xaa, 0x07, 0x001c}, /* 00,07,1c,aa */ + {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ {} }; static const struct usb_action pas106b_60HZ[] = { - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ - {0xa0, 0x2e, 0x0192}, /* 01,92,2e,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x71, 0x0197}, /* 01,97,71,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x30, 0x018f}, /* 01,8f,30,cc */ - {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */ - {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */ - {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ - {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ - {0xa0, 0x04, 0x01a9}, /* 01,a9,04,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ + {0xa0, 0x2e, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,2e,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x71, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,71,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x30, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,30,cc */ + {0xaa, 0x03, 0x001c}, /* 00,03,1c,aa */ + {0xaa, 0x04, 0x0004}, /* 00,04,04,aa */ + {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ + {0xaa, 0x07, 0x00c4}, /* 00,07,c4,aa */ + {0xa0, 0x04, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,04,cc */ {} }; static const struct usb_action pas106b_NoFliker[] = { - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x06, 0x0191}, /* 01,91,06,cc */ - {0xa0, 0x50, 0x0192}, /* 01,92,50,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */ - {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ - {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ - {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,06,cc */ + {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xaa, 0x03, 0x0013}, /* 00,03,13,aa */ + {0xaa, 0x04, 0x0000}, /* 00,04,00,aa */ + {0xaa, 0x05, 0x0001}, /* 00,05,01,aa */ + {0xaa, 0x07, 0x0030}, /* 00,07,30,aa */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ {} }; static const struct usb_action pb03303x_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0xdc, 0x008b}, /* 8b -> dc */ - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xdc, 0x008b}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, {0xaa, 0x01, 0x0001}, {0xaa, 0x06, 0x0000}, {0xaa, 0x08, 0x0483}, @@ -4414,20 +4427,20 @@ static const struct usb_action pb03303x_Initial[] = { {0xaa, 0x2c, 0x0030}, {0xaa, 0x2d, 0x0030}, {0xaa, 0x2e, 0x0028}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x78, 0x018d}, - {0xa0, 0x61, 0x0116}, - {0xa0, 0x65, 0x0118}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x61, ZC3XX_R116_RGAIN}, + {0xa0, 0x65, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0002}, {0xa0, 0x09, 0x01ad}, @@ -4435,112 +4448,112 @@ static const struct usb_action pb03303x_Initial[] = { {0xa0, 0x0d, 0x003a}, {0xa0, 0x02, 0x003b}, {0xa0, 0x00, 0x0038}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x05, 0x0009}, {0xaa, 0x09, 0x0134}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xec, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x9c, 0x0197}, - {0xa0, 0x0e, 0x018c}, - {0xa0, 0x1c, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0xd7, 0x001d}, - {0xa0, 0xf4, 0x001e}, - {0xa0, 0xf9, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action pb03303x_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0xdc, 0x008b}, /* 8b -> dc */ - {0xa0, 0x01, 0x0001}, - {0xa0, 0x03, 0x0012}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xdc, 0x008b}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, /* 8b -> dc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, {0xaa, 0x01, 0x0001}, {0xaa, 0x06, 0x0000}, {0xaa, 0x08, 0x0483}, @@ -4560,20 +4573,20 @@ static const struct usb_action pb03303x_InitialScale[] = { {0xaa, 0x2c, 0x0030}, {0xaa, 0x2d, 0x0030}, {0xaa, 0x2e, 0x0028}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x78, 0x018d}, - {0xa0, 0x61, 0x0116}, - {0xa0, 0x65, 0x0118}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, + {0xa0, 0x61, ZC3XX_R116_RGAIN}, + {0xa0, 0x65, ZC3XX_R118_BGAIN}, {0xa1, 0x01, 0x0002}, @@ -4583,113 +4596,113 @@ static const struct usb_action pb03303x_InitialScale[] = { {0xa0, 0x0d, 0x003a}, {0xa0, 0x02, 0x003b}, {0xa0, 0x00, 0x0038}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x13, 0x0120}, /* gamma 4 */ - {0xa0, 0x38, 0x0121}, - {0xa0, 0x59, 0x0122}, - {0xa0, 0x79, 0x0123}, - {0xa0, 0x92, 0x0124}, - {0xa0, 0xa7, 0x0125}, - {0xa0, 0xb9, 0x0126}, - {0xa0, 0xc8, 0x0127}, - {0xa0, 0xd4, 0x0128}, - {0xa0, 0xdf, 0x0129}, - {0xa0, 0xe7, 0x012a}, - {0xa0, 0xee, 0x012b}, - {0xa0, 0xf4, 0x012c}, - {0xa0, 0xf9, 0x012d}, - {0xa0, 0xfc, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x26, 0x0130}, - {0xa0, 0x22, 0x0131}, - {0xa0, 0x20, 0x0132}, - {0xa0, 0x1c, 0x0133}, - {0xa0, 0x16, 0x0134}, - {0xa0, 0x13, 0x0135}, - {0xa0, 0x10, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x06, 0x013b}, - {0xa0, 0x05, 0x013c}, - {0xa0, 0x04, 0x013d}, - {0xa0, 0x03, 0x013e}, - {0xa0, 0x02, 0x013f}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */ + {0xa0, 0x38, ZC3XX_R121_GAMMA01}, + {0xa0, 0x59, ZC3XX_R122_GAMMA02}, + {0xa0, 0x79, ZC3XX_R123_GAMMA03}, + {0xa0, 0x92, ZC3XX_R124_GAMMA04}, + {0xa0, 0xa7, ZC3XX_R125_GAMMA05}, + {0xa0, 0xb9, ZC3XX_R126_GAMMA06}, + {0xa0, 0xc8, ZC3XX_R127_GAMMA07}, + {0xa0, 0xd4, ZC3XX_R128_GAMMA08}, + {0xa0, 0xdf, ZC3XX_R129_GAMMA09}, + {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xee, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x26, ZC3XX_R130_GAMMA10}, + {0xa0, 0x22, ZC3XX_R131_GAMMA11}, + {0xa0, 0x20, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1c, ZC3XX_R133_GAMMA13}, + {0xa0, 0x16, ZC3XX_R134_GAMMA14}, + {0xa0, 0x13, ZC3XX_R135_GAMMA15}, + {0xa0, 0x10, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x06, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x05, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x04, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x03, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x02, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x05, 0x0009}, {0xaa, 0x09, 0x0134}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xec, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x9c, 0x0197}, - {0xa0, 0x0e, 0x018c}, - {0xa0, 0x1c, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0xd7, 0x001d}, - {0xa0, 0xf4, 0x001e}, - {0xa0, 0xf9, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xec, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x9c, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action pb0330xx_Initial[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x0006}, {0xaa, 0x02, 0x0011}, {0xaa, 0x03, 0x01e7}, @@ -4706,79 +4719,79 @@ static const struct usb_action pb0330xx_Initial[] = { {0xaa, 0x40, 0x01e0}, {0xaa, 0x58, 0x0078}, {0xaa, 0x62, 0x0411}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x6c, 0x018d}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0002}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x00, 0x0092}, - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x05, 0x0066}, {0xaa, 0x09, 0x02b2}, {0xaa, 0x10, 0x0002}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0x8c, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x8a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0xd7, 0x001d}, - {0xa0, 0xf0, 0x001e}, - {0xa0, 0xf8, 0x001f}, - {0xa0, 0xff, 0x0020}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0007}, /* {0xa0, 0x30, 0x0007}, */ @@ -4789,22 +4802,22 @@ static const struct usb_action pb0330xx_Initial[] = { static const struct usb_action pb0330xx_InitialScale[] = { {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, /* 00 */ - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x00, 0x0002}, /* 10 */ - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0x05, 0x0012}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00 */ + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 10 */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, {0xaa, 0x01, 0x0006}, {0xaa, 0x02, 0x0011}, {0xaa, 0x03, 0x01e7}, @@ -4821,78 +4834,78 @@ static const struct usb_action pb0330xx_InitialScale[] = { {0xaa, 0x40, 0x01e0}, {0xaa, 0x58, 0x0078}, {0xaa, 0x62, 0x0411}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x6c, 0x018d}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0002}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x00, 0x0092}, - {0xa0, 0x02, 0x0090}, + {0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R090_I2CCOMMAND}, {0xa1, 0x01, 0x0091}, {0xa1, 0x01, 0x0095}, {0xa1, 0x01, 0x0096}, - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x50, 0x010a}, /* matrix */ - {0xa0, 0xf8, 0x010b}, - {0xa0, 0xf8, 0x010c}, - {0xa0, 0xf8, 0x010d}, - {0xa0, 0x50, 0x010e}, - {0xa0, 0xf8, 0x010f}, - {0xa0, 0xf8, 0x0110}, - {0xa0, 0xf8, 0x0111}, - {0xa0, 0x50, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x50, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf8, ZC3XX_R10B_RGB01}, + {0xa0, 0xf8, ZC3XX_R10C_RGB02}, + {0xa0, 0xf8, ZC3XX_R10D_RGB10}, + {0xa0, 0x50, ZC3XX_R10E_RGB11}, + {0xa0, 0xf8, ZC3XX_R10F_RGB12}, + {0xa0, 0xf8, ZC3XX_R110_RGB20}, + {0xa0, 0xf8, ZC3XX_R111_RGB21}, + {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0x05, 0x0066}, {0xaa, 0x09, 0x02b2}, {0xaa, 0x10, 0x0002}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0x8c, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x8a, 0x0197}, - {0xa0, 0x10, 0x018c}, - {0xa0, 0x20, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0xd7, 0x001d}, - {0xa0, 0xf0, 0x001e}, - {0xa0, 0xf8, 0x001f}, - {0xa0, 0xff, 0x0020}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x8c, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x8a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0008}, {0xa1, 0x01, 0x0007}, /* {0xa0, 0x30, 0x0007}, */ @@ -4900,136 +4913,136 @@ static const struct usb_action pb0330xx_InitialScale[] = { {} }; static const struct usb_action pb0330_50HZ[] = { - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xee, 0x0192}, /* 01,92,ee,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x46, 0x0197}, /* 01,97,46,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0x68, 0x001d}, /* 00,1d,68,cc */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,ee,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x46, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,46,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x68, ZC3XX_R01D_HSYNC_0}, /* 00,1d,68,cc */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc */ {} }; static const struct usb_action pb0330_50HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xa0, 0x0192}, /* 01,92,a0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x7a, 0x0197}, /* 01,97,7a,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0xe5, 0x001d}, /* 00,1d,e5,cc */ - {0xa0, 0xf0, 0x001e}, /* 00,1e,f0,cc */ - {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0xe5, ZC3XX_R01D_HSYNC_0}, /* 00,1d,e5,cc */ + {0xa0, 0xf0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f0,cc */ + {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ {} }; static const struct usb_action pb0330_60HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xdd, 0x0192}, /* 01,92,dd,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x3d, 0x0197}, /* 01,97,3d,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0x43, 0x001d}, /* 00,1d,43,cc */ - {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ - {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xdd, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,dd,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x3d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3d,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x43, ZC3XX_R01D_HSYNC_0}, /* 00,1d,43,cc */ + {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ {} }; static const struct usb_action pb0330_60HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xa0, 0x0192}, /* 01,92,a0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x7a, 0x0197}, /* 01,97,7a,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0x41, 0x001d}, /* 00,1d,41,cc */ - {0xa0, 0x50, 0x001e}, /* 00,1e,50,cc */ - {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xa0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,a0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x7a, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7a,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0x41, ZC3XX_R01D_HSYNC_0}, /* 00,1d,41,cc */ + {0xa0, 0x50, ZC3XX_R01E_HSYNC_1}, /* 00,1e,50,cc */ + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ {} }; static const struct usb_action pb0330_NoFliker[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ - {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ - {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ {} }; static const struct usb_action pb0330_NoFlikerScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x07, 0x0191}, /* 01,91,07,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0x09, 0x001d}, /* 00,1d,09,cc */ - {0xa0, 0x40, 0x001e}, /* 00,1e,40,cc */ - {0xa0, 0x90, 0x001f}, /* 00,1f,90,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,07,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0x09, ZC3XX_R01D_HSYNC_0}, /* 00,1d,09,cc */ + {0xa0, 0x40, ZC3XX_R01E_HSYNC_1}, /* 00,1e,40,cc */ + {0xa0, 0x90, ZC3XX_R01F_HSYNC_2}, /* 00,1f,90,cc */ {} }; /* from oem9.inf - HKR,%PO2030%,Initial - 640x480 - (close to CS2102) */ static const struct usb_action PO2030_mode0[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x04, 0x0002}, /* 00,02,04,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x04, 0x0080}, /* 00,80,04,cc */ - {0xa0, 0x05, 0x0081}, /* 00,81,05,cc */ - {0xa0, 0x16, 0x0083}, /* 00,83,16,cc */ - {0xa0, 0x18, 0x0085}, /* 00,85,18,cc */ - {0xa0, 0x1a, 0x0086}, /* 00,86,1a,cc */ - {0xa0, 0x1b, 0x0087}, /* 00,87,1b,cc */ - {0xa0, 0x1c, 0x0088}, /* 00,88,1c,cc */ - {0xa0, 0xee, 0x008b}, /* 00,8b,ee,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xe6, 0x009c}, /* 00,9c,e6,cc */ - {0xa0, 0x86, 0x009e}, /* 00,9e,86,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ + {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ + {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ + {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ + {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ + {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ + {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ + {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc */ + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */ {0xaa, 0x09, 0x00ce}, /* 00,09,ce,aa */ {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ {0xaa, 0x0d, 0x0054}, /* 00,0d,54,aa */ @@ -5064,49 +5077,49 @@ static const struct usb_action PO2030_mode0[] = { {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ - {0xa0, 0xf7, 0x0101}, /* 01,01,f7,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ - {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ + {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ {} }; /* from oem9.inf - HKR,%PO2030%,InitialScale - 320x240 */ static const struct usb_action PO2030_mode1[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc */ - {0xa0, 0x10, 0x0002}, /* 00,02,10,cc */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc */ - {0xa0, 0x04, 0x0080}, /* 00,80,04,cc */ - {0xa0, 0x05, 0x0081}, /* 00,81,05,cc */ - {0xa0, 0x16, 0x0083}, /* 00,83,16,cc */ - {0xa0, 0x18, 0x0085}, /* 00,85,18,cc */ - {0xa0, 0x1a, 0x0086}, /* 00,86,1a,cc */ - {0xa0, 0x1b, 0x0087}, /* 00,87,1b,cc */ - {0xa0, 0x1c, 0x0088}, /* 00,88,1c,cc */ - {0xa0, 0xee, 0x008b}, /* 00,8b,ee,cc */ - {0xa0, 0x03, 0x0008}, /* 00,08,03,cc */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ - {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc */ - {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc */ - {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */ + {0xa0, 0x04, ZC3XX_R080_HBLANKHIGH}, /* 00,80,04,cc */ + {0xa0, 0x05, ZC3XX_R081_HBLANKLOW}, /* 00,81,05,cc */ + {0xa0, 0x16, ZC3XX_R083_RGAINADDR}, /* 00,83,16,cc */ + {0xa0, 0x18, ZC3XX_R085_BGAINADDR}, /* 00,85,18,cc */ + {0xa0, 0x1a, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,1a,cc */ + {0xa0, 0x1b, ZC3XX_R087_EXPTIMEMID}, /* 00,87,1b,cc */ + {0xa0, 0x1c, ZC3XX_R088_EXPTIMELOW}, /* 00,88,1c,cc */ + {0xa0, 0xee, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,ee,cc */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ + {0xaa, 0x8d, 0x0008}, /* 00,8d,08,aa */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */ + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */ {0xaa, 0x09, 0x00cc}, /* 00,09,cc,aa */ {0xaa, 0x0b, 0x0005}, /* 00,0b,05,aa */ {0xaa, 0x0d, 0x0058}, /* 00,0d,58,aa */ @@ -5141,17 +5154,17 @@ static const struct usb_action PO2030_mode1[] = { {0xaa, 0x6b, 0x00a0}, /* 00,6b,a0,aa */ {0xaa, 0x6c, 0x0054}, /* 00,6c,54,aa */ {0xaa, 0xd6, 0x0007}, /* 00,d6,07,aa */ - {0xa0, 0xf7, 0x0101}, /* 01,01,f7,cc */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc */ - {0xa0, 0x06, 0x0189}, /* 01,89,06,cc */ + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,f7,cc */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */ {0xa0, 0x00, 0x01ad}, /* 01,ad,00,cc */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc */ - {0xa0, 0x7a, 0x0116}, /* 01,16,7a,cc */ - {0xa0, 0x4a, 0x0118}, /* 01,18,4a,cc */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */ + {0xa0, 0x7a, ZC3XX_R116_RGAIN}, /* 01,16,7a,cc */ + {0xa0, 0x4a, ZC3XX_R118_BGAIN}, /* 01,18,4a,cc */ {} }; @@ -5160,20 +5173,20 @@ static const struct usb_action PO2030_50HZ[] = { {0xaa, 0x1a, 0x0001}, /* 00,1a,01,aa */ {0xaa, 0x1b, 0x000a}, /* 00,1b,0a,aa */ {0xaa, 0x1c, 0x00b0}, /* 00,1c,b0,aa */ - {0xa0, 0x05, 0x0190}, /* 01,90,05,cc */ - {0xa0, 0x35, 0x0191}, /* 01,91,35,cc */ - {0xa0, 0x70, 0x0192}, /* 01,92,70,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x85, 0x0196}, /* 01,96,85,cc */ - {0xa0, 0x58, 0x0197}, /* 01,97,58,cc */ - {0xa0, 0x0c, 0x018c}, /* 01,8c,0c,cc */ - {0xa0, 0x18, 0x018f}, /* 01,8f,18,cc */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x22, 0x01aa}, /* 01,aa,22,cc */ - {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0xa0, 0x05, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,05,cc */ + {0xa0, 0x35, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,35,cc */ + {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x85, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,85,cc */ + {0xa0, 0x58, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,58,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ + {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ {} }; @@ -5182,25 +5195,26 @@ static const struct usb_action PO2030_60HZ[] = { {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ {0xaa, 0x1b, 0x00de}, /* 00,1b,de,aa */ {0xaa, 0x1c, 0x0040}, /* 00,1c,40,aa */ - {0xa0, 0x08, 0x0190}, /* 01,90,08,cc */ - {0xa0, 0xae, 0x0191}, /* 01,91,ae,cc */ - {0xa0, 0x80, 0x0192}, /* 01,92,80,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x6f, 0x0196}, /* 01,96,6f,cc */ - {0xa0, 0x20, 0x0197}, /* 01,97,20,cc */ - {0xa0, 0x0c, 0x018c}, /* 01,8c,0c,cc */ - {0xa0, 0x18, 0x018f}, /* 01,8f,18,cc */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc */ - {0xa0, 0x22, 0x01aa}, /* 01,aa,22,cc */ - {0xa0, 0x88, 0x018d}, /* 01,8d,88,cc */ /* win: 01,8d,80 */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc */ + {0xa0, 0x08, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,08,cc */ + {0xa0, 0xae, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,ae,cc */ + {0xa0, 0x80, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,80,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x6f, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,6f,cc */ + {0xa0, 0x20, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,20,cc */ + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0c,cc */ + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,18,cc */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc */ + {0xa0, 0x22, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,22,cc */ + {0xa0, 0x88, ZC3XX_R18D_YTARGET}, /* 01,8d,88,cc */ + /* win: 01,8d,80 */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc */ {} }; static const struct usb_action PO2030_NoFliker[] = { - {0xa0, 0x02, 0x0180}, /* 01,80,02,cc */ + {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */ {0xaa, 0x8d, 0x000d}, /* 00,8d,0d,aa */ {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa */ {0xaa, 0x1b, 0x0002}, /* 00,1b,02,aa */ @@ -5212,756 +5226,759 @@ static const struct usb_action PO2030_NoFliker[] = { /* TEST */ static const struct usb_action tas5130CK_Initial[] = { - {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x01, 0x003b}, {0xa0, 0x0e, 0x003a}, {0xa0, 0x01, 0x0038}, {0xa0, 0x0b, 0x0039}, {0xa0, 0x00, 0x0038}, {0xa0, 0x0b, 0x0039}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x10, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0xdc, 0x008b}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x07, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xdc, 0x008b}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x01, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x06, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x08, 0x0092}, - {0xa0, 0x83, 0x0093}, - {0xa0, 0x04, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x01, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x08, 0x0092}, - {0xa0, 0x06, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x02, 0x0092}, - {0xa0, 0x11, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x03, 0x0092}, - {0xa0, 0xE7, 0x0093}, - {0xa0, 0x01, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x04, 0x0092}, - {0xa0, 0x87, 0x0093}, - {0xa0, 0x02, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x07, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x30, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x51, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x35, 0x0092}, - {0xa0, 0x7F, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x30, 0x0092}, - {0xa0, 0x05, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x31, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x58, 0x0092}, - {0xa0, 0x78, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x62, 0x0092}, - {0xa0, 0x11, 0x0093}, - {0xa0, 0x04, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2B, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2c, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2D, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2e, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0xb7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xE7, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x87, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2c, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x09, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x6c, 0x018d}, - {0xa0, 0x61, 0x0116}, - {0xa0, 0x65, 0x0118}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, + {0xa0, 0x61, ZC3XX_R116_RGAIN}, + {0xa0, 0x65, ZC3XX_R118_BGAIN}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x4c, 0x010a}, /* matrix */ - {0xa0, 0xf1, 0x010b}, - {0xa0, 0x03, 0x010c}, - {0xa0, 0xfe, 0x010d}, - {0xa0, 0x51, 0x010e}, - {0xa0, 0xf1, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0x03, 0x0111}, - {0xa0, 0x51, 0x0112}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x38, 0x0120}, /* gamma > 5 */ - {0xa0, 0x51, 0x0121}, - {0xa0, 0x6e, 0x0122}, - {0xa0, 0x8c, 0x0123}, - {0xa0, 0xa2, 0x0124}, - {0xa0, 0xb6, 0x0125}, - {0xa0, 0xc8, 0x0126}, - {0xa0, 0xd6, 0x0127}, - {0xa0, 0xe2, 0x0128}, - {0xa0, 0xed, 0x0129}, - {0xa0, 0xf5, 0x012a}, - {0xa0, 0xfc, 0x012b}, - {0xa0, 0xff, 0x012c}, - {0xa0, 0xff, 0x012d}, - {0xa0, 0xff, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x12, 0x0130}, - {0xa0, 0x1b, 0x0131}, - {0xa0, 0x1d, 0x0132}, - {0xa0, 0x1a, 0x0133}, - {0xa0, 0x15, 0x0134}, - {0xa0, 0x12, 0x0135}, - {0xa0, 0x0f, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x05, 0x013b}, - {0xa0, 0x00, 0x013c}, - {0xa0, 0x00, 0x013d}, - {0xa0, 0x00, 0x013e}, - {0xa0, 0x01, 0x013f}, - {0xa0, 0x4c, 0x010a}, /* matrix */ - {0xa0, 0xf1, 0x010b}, - {0xa0, 0x03, 0x010c}, - {0xa0, 0xfe, 0x010d}, - {0xa0, 0x51, 0x010e}, - {0xa0, 0xf1, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0x03, 0x0111}, - {0xa0, 0x51, 0x0112}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0092}, - {0xa0, 0x09, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x09, 0x0092}, - {0xa0, 0x34, 0x0093}, - {0xa0, 0x01, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x07, 0x0191}, - {0xa0, 0xd2, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x9a, 0x0197}, - {0xa0, 0x0e, 0x018c}, - {0xa0, 0x1c, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x66, 0x01aa}, - {0xa0, 0xd7, 0x001d}, - {0xa0, 0xf4, 0x001e}, - {0xa0, 0xf9, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf1, ZC3XX_R10B_RGB01}, + {0xa0, 0x03, ZC3XX_R10C_RGB02}, + {0xa0, 0xfe, ZC3XX_R10D_RGB10}, + {0xa0, 0x51, ZC3XX_R10E_RGB11}, + {0xa0, 0xf1, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0x03, ZC3XX_R111_RGB21}, + {0xa0, 0x51, ZC3XX_R112_RGB22}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */ + {0xa0, 0x51, ZC3XX_R121_GAMMA01}, + {0xa0, 0x6e, ZC3XX_R122_GAMMA02}, + {0xa0, 0x8c, ZC3XX_R123_GAMMA03}, + {0xa0, 0xa2, ZC3XX_R124_GAMMA04}, + {0xa0, 0xb6, ZC3XX_R125_GAMMA05}, + {0xa0, 0xc8, ZC3XX_R126_GAMMA06}, + {0xa0, 0xd6, ZC3XX_R127_GAMMA07}, + {0xa0, 0xe2, ZC3XX_R128_GAMMA08}, + {0xa0, 0xed, ZC3XX_R129_GAMMA09}, + {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x12, ZC3XX_R130_GAMMA10}, + {0xa0, 0x1b, ZC3XX_R131_GAMMA11}, + {0xa0, 0x1d, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, + {0xa0, 0x15, ZC3XX_R134_GAMMA14}, + {0xa0, 0x12, ZC3XX_R135_GAMMA15}, + {0xa0, 0x0f, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x05, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf1, ZC3XX_R10B_RGB01}, + {0xa0, 0x03, ZC3XX_R10C_RGB02}, + {0xa0, 0xfe, ZC3XX_R10D_RGB10}, + {0xa0, 0x51, ZC3XX_R10E_RGB11}, + {0xa0, 0xf1, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0x03, ZC3XX_R111_RGB21}, + {0xa0, 0x51, ZC3XX_R112_RGB22}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x09, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x34, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xd2, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x9a, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd7, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf9, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action tas5130CK_InitialScale[] = { - {0xa0, 0x01, 0x0000}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, {0xa0, 0x01, 0x003b}, {0xa0, 0x0e, 0x003a}, {0xa0, 0x01, 0x0038}, {0xa0, 0x0b, 0x0039}, {0xa0, 0x00, 0x0038}, {0xa0, 0x0b, 0x0039}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x0a, 0x0010}, - {0xa0, 0x00, 0x0002}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0xdc, 0x008b}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x07, 0x0012}, - {0xa0, 0x00, 0x0098}, - {0xa0, 0x00, 0x009a}, - {0xa0, 0x00, 0x011a}, - {0xa0, 0x00, 0x011c}, - {0xa0, 0xdc, 0x008b}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x01, 0x0092}, - {0xa0, 0x01, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x06, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x08, 0x0092}, - {0xa0, 0x83, 0x0093}, - {0xa0, 0x04, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x01, 0x0092}, - {0xa0, 0x04, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x08, 0x0092}, - {0xa0, 0x06, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x02, 0x0092}, - {0xa0, 0x11, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x03, 0x0092}, - {0xa0, 0xe5, 0x0093}, - {0xa0, 0x01, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x04, 0x0092}, - {0xa0, 0x85, 0x0093}, - {0xa0, 0x02, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x07, 0x0092}, - {0xa0, 0x02, 0x0093}, - {0xa0, 0x30, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x20, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x51, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x35, 0x0092}, - {0xa0, 0x7F, 0x0093}, - {0xa0, 0x50, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x30, 0x0092}, - {0xa0, 0x05, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x31, 0x0092}, - {0xa0, 0x00, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x58, 0x0092}, - {0xa0, 0x78, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x62, 0x0092}, - {0xa0, 0x11, 0x0093}, - {0xa0, 0x04, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2B, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2C, 0x0092}, - {0xa0, 0x7F, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2D, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x2e, 0x0092}, - {0xa0, 0x7f, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x10, 0x0087}, - {0xa0, 0xb7, 0x0101}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x07, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xdc, ZC3XX_R08B_I2CDEVICEADDR}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x83, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x01, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x08, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x06, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x02, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xe5, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x04, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x85, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x02, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x07, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x30, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x51, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x35, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x50, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x30, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x05, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x31, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x58, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x78, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x62, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x11, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x04, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2B, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2C, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7F, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2D, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x2e, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x7f, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, {0xa0, 0x09, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, - {0xa0, 0x60, 0x01a8}, - {0xa0, 0x6c, 0x018d}, - {0xa0, 0x61, 0x0116}, - {0xa0, 0x65, 0x0118}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, + {0xa0, 0x6c, ZC3XX_R18D_YTARGET}, + {0xa0, 0x61, ZC3XX_R116_RGAIN}, + {0xa0, 0x65, ZC3XX_R118_BGAIN}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x4c, 0x010a}, /* matrix */ - {0xa0, 0xf1, 0x010b}, - {0xa0, 0x03, 0x010c}, - {0xa0, 0xfe, 0x010d}, - {0xa0, 0x51, 0x010e}, - {0xa0, 0xf1, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0x03, 0x0111}, - {0xa0, 0x51, 0x0112}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - {0xa0, 0x38, 0x0120}, /* gamma > 5 */ - {0xa0, 0x51, 0x0121}, - {0xa0, 0x6e, 0x0122}, - {0xa0, 0x8c, 0x0123}, - {0xa0, 0xa2, 0x0124}, - {0xa0, 0xb6, 0x0125}, - {0xa0, 0xc8, 0x0126}, - {0xa0, 0xd6, 0x0127}, - {0xa0, 0xe2, 0x0128}, - {0xa0, 0xed, 0x0129}, - {0xa0, 0xf5, 0x012a}, - {0xa0, 0xfc, 0x012b}, - {0xa0, 0xff, 0x012c}, - {0xa0, 0xff, 0x012d}, - {0xa0, 0xff, 0x012e}, - {0xa0, 0xff, 0x012f}, - {0xa0, 0x12, 0x0130}, - {0xa0, 0x1b, 0x0131}, - {0xa0, 0x1d, 0x0132}, - {0xa0, 0x1a, 0x0133}, - {0xa0, 0x15, 0x0134}, - {0xa0, 0x12, 0x0135}, - {0xa0, 0x0f, 0x0136}, - {0xa0, 0x0d, 0x0137}, - {0xa0, 0x0b, 0x0138}, - {0xa0, 0x09, 0x0139}, - {0xa0, 0x07, 0x013a}, - {0xa0, 0x05, 0x013b}, - {0xa0, 0x00, 0x013c}, - {0xa0, 0x00, 0x013d}, - {0xa0, 0x00, 0x013e}, - {0xa0, 0x01, 0x013f}, - {0xa0, 0x4c, 0x010a}, /* matrix */ - {0xa0, 0xf1, 0x010b}, - {0xa0, 0x03, 0x010c}, - {0xa0, 0xfe, 0x010d}, - {0xa0, 0x51, 0x010e}, - {0xa0, 0xf1, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0x03, 0x0111}, - {0xa0, 0x51, 0x0112}, - {0xa0, 0x10, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, - {0xa0, 0x05, 0x0092}, - {0xa0, 0x62, 0x0093}, - {0xa0, 0x00, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x09, 0x0092}, - {0xa0, 0xaa, 0x0093}, - {0xa0, 0x01, 0x0094}, - {0xa0, 0x01, 0x0090}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x03, 0x0191}, - {0xa0, 0x9b, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x47, 0x0197}, - {0xa0, 0x0e, 0x018c}, - {0xa0, 0x1c, 0x018f}, - {0xa0, 0x14, 0x01a9}, - {0xa0, 0x66, 0x01aa}, - {0xa0, 0x62, 0x001d}, - {0xa0, 0x90, 0x001e}, - {0xa0, 0xc8, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x60, 0x011d}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf1, ZC3XX_R10B_RGB01}, + {0xa0, 0x03, ZC3XX_R10C_RGB02}, + {0xa0, 0xfe, ZC3XX_R10D_RGB10}, + {0xa0, 0x51, ZC3XX_R10E_RGB11}, + {0xa0, 0xf1, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0x03, ZC3XX_R111_RGB21}, + {0xa0, 0x51, ZC3XX_R112_RGB22}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x38, ZC3XX_R120_GAMMA00}, /* gamma > 5 */ + {0xa0, 0x51, ZC3XX_R121_GAMMA01}, + {0xa0, 0x6e, ZC3XX_R122_GAMMA02}, + {0xa0, 0x8c, ZC3XX_R123_GAMMA03}, + {0xa0, 0xa2, ZC3XX_R124_GAMMA04}, + {0xa0, 0xb6, ZC3XX_R125_GAMMA05}, + {0xa0, 0xc8, ZC3XX_R126_GAMMA06}, + {0xa0, 0xd6, ZC3XX_R127_GAMMA07}, + {0xa0, 0xe2, ZC3XX_R128_GAMMA08}, + {0xa0, 0xed, ZC3XX_R129_GAMMA09}, + {0xa0, 0xf5, ZC3XX_R12A_GAMMA0A}, + {0xa0, 0xfc, ZC3XX_R12B_GAMMA0B}, + {0xa0, 0xff, ZC3XX_R12C_GAMMA0C}, + {0xa0, 0xff, ZC3XX_R12D_GAMMA0D}, + {0xa0, 0xff, ZC3XX_R12E_GAMMA0E}, + {0xa0, 0xff, ZC3XX_R12F_GAMMA0F}, + {0xa0, 0x12, ZC3XX_R130_GAMMA10}, + {0xa0, 0x1b, ZC3XX_R131_GAMMA11}, + {0xa0, 0x1d, ZC3XX_R132_GAMMA12}, + {0xa0, 0x1a, ZC3XX_R133_GAMMA13}, + {0xa0, 0x15, ZC3XX_R134_GAMMA14}, + {0xa0, 0x12, ZC3XX_R135_GAMMA15}, + {0xa0, 0x0f, ZC3XX_R136_GAMMA16}, + {0xa0, 0x0d, ZC3XX_R137_GAMMA17}, + {0xa0, 0x0b, ZC3XX_R138_GAMMA18}, + {0xa0, 0x09, ZC3XX_R139_GAMMA19}, + {0xa0, 0x07, ZC3XX_R13A_GAMMA1A}, + {0xa0, 0x05, ZC3XX_R13B_GAMMA1B}, + {0xa0, 0x00, ZC3XX_R13C_GAMMA1C}, + {0xa0, 0x00, ZC3XX_R13D_GAMMA1D}, + {0xa0, 0x00, ZC3XX_R13E_GAMMA1E}, + {0xa0, 0x01, ZC3XX_R13F_GAMMA1F}, + {0xa0, 0x4c, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xf1, ZC3XX_R10B_RGB01}, + {0xa0, 0x03, ZC3XX_R10C_RGB02}, + {0xa0, 0xfe, ZC3XX_R10D_RGB10}, + {0xa0, 0x51, ZC3XX_R10E_RGB11}, + {0xa0, 0xf1, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0x03, ZC3XX_R111_RGB21}, + {0xa0, 0x51, ZC3XX_R112_RGB22}, + {0xa0, 0x10, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, + {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0x62, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT}, + {0xa0, 0xaa, ZC3XX_R093_I2CSETVALUE}, + {0xa0, 0x01, ZC3XX_R094_I2CWRITEACK}, + {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x9b, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x1c, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x14, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x66, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x09, 0x01ad}, {0xa0, 0x15, 0x01ae}, - {0xa0, 0x40, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa0, 0x30, 0x0007}, - {0xa0, 0x02, 0x0008}, + {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, {0xa0, 0x00, 0x0007}, - {0xa0, 0x03, 0x0008}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {} }; static const struct usb_action tas5130cxx_Initial[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x50, 0x0002}, - {0xa0, 0x03, 0x0008}, - {0xa0, 0x02, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x00, 0x0001}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x00a5}, - {0xa0, 0x02, 0x00a6}, - - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - - {0xa0, 0x04, 0x0098}, - {0xa0, 0x0f, 0x009a}, - {0xa0, 0x04, 0x011a}, - {0xa0, 0x0f, 0x011c}, - {0xa0, 0xe8, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x88, 0x009e}, - {0xa0, 0x06, 0x008d}, - {0xa0, 0xf7, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x68, 0x018d}, - {0xa0, 0x60, 0x01a8}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x50, ZC3XX_R002_CLOCKSELECT}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, + {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, + + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + + {0xa0, 0x04, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x04, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x68, ZC3XX_R18D_YTARGET}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x68, 0x010a}, /* matrix */ - {0xa0, 0xec, 0x010b}, - {0xa0, 0xec, 0x010c}, - {0xa0, 0xec, 0x010d}, - {0xa0, 0x68, 0x010e}, - {0xa0, 0xec, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0xec, 0x0111}, - {0xa0, 0x68, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xec, ZC3XX_R10B_RGB01}, + {0xa0, 0xec, ZC3XX_R10C_RGB02}, + {0xa0, 0xec, ZC3XX_R10D_RGB10}, + {0xa0, 0x68, ZC3XX_R10E_RGB11}, + {0xa0, 0xec, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0xec, ZC3XX_R111_RGB21}, + {0xa0, 0x68, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x018d}, - {0xa0, 0x90, 0x018d}, /* 90 */ + {0xa0, 0x90, ZC3XX_R18D_YTARGET}, /* 90 */ {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0xa3, 0x0001}, {0xaa, 0xa4, 0x0077}, - {0xa0, 0x01, 0x00a3}, - {0xa0, 0x77, 0x00a4}, - - {0xa0, 0x00, 0x0190}, /* 00 */ - {0xa0, 0x03, 0x0191}, /* 03 */ - {0xa0, 0xe8, 0x0192}, /* e8 */ - {0xa0, 0x00, 0x0195}, /* 0 */ - {0xa0, 0x00, 0x0196}, /* 0 */ - {0xa0, 0x7d, 0x0197}, /* 7d */ - - {0xa0, 0x0c, 0x018c}, - {0xa0, 0x18, 0x018f}, - {0xa0, 0x08, 0x01a9}, /* 08 */ - {0xa0, 0x24, 0x01aa}, /* 24 */ - {0xa0, 0xf0, 0x001d}, - {0xa0, 0xf4, 0x001e}, - {0xa0, 0xf8, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x03, 0x009f}, - {0xa0, 0xc0, 0x00a0}, - {0xa0, 0x50, 0x011d}, /* 50 */ - {0xa0, 0x40, 0x0180}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, + + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 00 */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 03 */ + {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* e8 */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 0 */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 0 */ + {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 7d */ + + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 08 */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 24 */ + {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, + {0xa0, 0xc0, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, /* 50 */ + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action tas5130cxx_InitialScale[] = { - {0xa0, 0x01, 0x0000}, - {0xa0, 0x01, 0x0000}, - {0xa0, 0x40, 0x0002}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, + {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, - {0xa0, 0x03, 0x0008}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x02, 0x0010}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x00, 0x0001}, - {0xa0, 0x01, 0x0012}, - {0xa0, 0x01, 0x0001}, - {0xa0, 0x05, 0x0012}, - {0xa0, 0x07, 0x00a5}, - {0xa0, 0x02, 0x00a6}, - {0xa0, 0x02, 0x0003}, - {0xa0, 0x80, 0x0004}, - {0xa0, 0x01, 0x0005}, - {0xa0, 0xe0, 0x0006}, - {0xa0, 0x05, 0x0098}, - {0xa0, 0x0f, 0x009a}, - {0xa0, 0x05, 0x011a}, - {0xa0, 0x0f, 0x011c}, - {0xa0, 0xe6, 0x009c}, - {0xa0, 0x02, 0x009d}, - {0xa0, 0x86, 0x009e}, - {0xa0, 0x06, 0x008d}, - {0xa0, 0x37, 0x0101}, - {0xa0, 0x0d, 0x0100}, - {0xa0, 0x06, 0x0189}, - {0xa0, 0x68, 0x018d}, - {0xa0, 0x60, 0x01a8}, + {0xa0, 0x02, ZC3XX_R010_CMOSSENSORSELECT}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x00, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x07, ZC3XX_R0A5_EXPOSUREGAIN}, + {0xa0, 0x02, ZC3XX_R0A6_EXPOSUREBLACKLVL}, + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, + {0xa0, 0x05, ZC3XX_R098_WINYSTARTLOW}, + {0xa0, 0x0f, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x05, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x0f, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0xe6, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x02, ZC3XX_R09D_WINWIDTHHIGH}, + {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, + {0xa0, 0x06, ZC3XX_R08D_COMPABILITYMODE}, + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x68, ZC3XX_R18D_YTARGET}, + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, {0xa0, 0x00, 0x01ad}, - {0xa0, 0x03, 0x01c5}, - {0xa0, 0x13, 0x01cb}, - {0xa0, 0x08, 0x0250}, - {0xa0, 0x08, 0x0301}, + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, {0xa1, 0x01, 0x0002}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, 0x0008}, + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, {0xa1, 0x01, 0x0008}, /* clock ? */ - {0xa0, 0x08, 0x01c6}, /* sharpness+ */ + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, - {0xa0, 0x0f, 0x01cb}, /* sharpness- */ - - {0xa0, 0x68, 0x010a}, /* matrix */ - {0xa0, 0xec, 0x010b}, - {0xa0, 0xec, 0x010c}, - {0xa0, 0xec, 0x010d}, - {0xa0, 0x68, 0x010e}, - {0xa0, 0xec, 0x010f}, - {0xa0, 0xec, 0x0110}, - {0xa0, 0xec, 0x0111}, - {0xa0, 0x68, 0x0112}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + + {0xa0, 0x68, ZC3XX_R10A_RGB00}, /* matrix */ + {0xa0, 0xec, ZC3XX_R10B_RGB01}, + {0xa0, 0xec, ZC3XX_R10C_RGB02}, + {0xa0, 0xec, ZC3XX_R10D_RGB10}, + {0xa0, 0x68, ZC3XX_R10E_RGB11}, + {0xa0, 0xec, ZC3XX_R10F_RGB12}, + {0xa0, 0xec, ZC3XX_R110_RGB20}, + {0xa0, 0xec, ZC3XX_R111_RGB21}, + {0xa0, 0x68, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x018d}, - {0xa0, 0x90, 0x018d}, + {0xa0, 0x90, ZC3XX_R18D_YTARGET}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x00, 0x0180}, - {0xa0, 0x00, 0x0019}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, {0xaa, 0xa3, 0x0001}, {0xaa, 0xa4, 0x0063}, - {0xa0, 0x01, 0x00a3}, - {0xa0, 0x63, 0x00a4}, - {0xa0, 0x00, 0x0190}, - {0xa0, 0x02, 0x0191}, - {0xa0, 0x38, 0x0192}, - {0xa0, 0x00, 0x0195}, - {0xa0, 0x00, 0x0196}, - {0xa0, 0x47, 0x0197}, - {0xa0, 0x0c, 0x018c}, - {0xa0, 0x18, 0x018f}, - {0xa0, 0x08, 0x01a9}, - {0xa0, 0x24, 0x01aa}, - {0xa0, 0xd3, 0x001d}, - {0xa0, 0xda, 0x001e}, - {0xa0, 0xea, 0x001f}, - {0xa0, 0xff, 0x0020}, - {0xa0, 0x03, 0x009f}, - {0xa0, 0x4c, 0x00a0}, - {0xa0, 0x50, 0x011d}, - {0xa0, 0x40, 0x0180}, + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, + {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, + {0xa0, 0x08, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, + {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, + {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, + {0xa0, 0x4c, ZC3XX_R0A0_MAXXLOW}, + {0xa0, 0x50, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, - {0xa0, 0x42, 0x0180}, + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, {} }; static const struct usb_action tas5130cxx_50HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0063}, /* 00,a4,63,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x63, 0x00a4}, /* 00,a4,63,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x02, 0x0191}, /* 01,91,02,cc */ - {0xa0, 0x38, 0x0192}, /* 01,92,38,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x47, 0x0197}, /* 01,97,47,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0xd3, 0x001d}, /* 00,1d,d3,cc */ - {0xa0, 0xda, 0x001e}, /* 00,1e,da,cc */ - {0xa0, 0xea, 0x001f}, /* 00,1f,ea,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x63, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,63,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ + {0xa0, 0x38, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,38,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x47, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0xd3, ZC3XX_R01D_HSYNC_0}, /* 00,1d,d3,cc */ + {0xa0, 0xda, ZC3XX_R01E_HSYNC_1}, /* 00,1e,da,cc */ + {0xa0, 0xea, ZC3XX_R01F_HSYNC_2}, /* 00,1f,ea,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ {} }; static const struct usb_action tas5130cxx_50HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x77, 0x00a4}, /* 00,a4,77,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ - {0xa0, 0xe8, 0x0192}, /* 01,92,e8,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x7d, 0x0197}, /* 01,97,7d,cc */ - {0xa0, 0x14, 0x018c}, /* 01,8c,14,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0xf0, 0x001d}, /* 00,1d,f0,cc */ - {0xa0, 0xf4, 0x001e}, /* 00,1e,f4,cc */ - {0xa0, 0xf8, 0x001f}, /* 00,1f,f8,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ + {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ + {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0xf0, ZC3XX_R01D_HSYNC_0}, /* 00,1d,f0,cc */ + {0xa0, 0xf4, ZC3XX_R01E_HSYNC_1}, /* 00,1e,f4,cc */ + {0xa0, 0xf8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,f8,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ {} }; static const struct usb_action tas5130cxx_60HZ[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0036}, /* 00,a4,36,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x36, 0x00a4}, /* 00,a4,36,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x01, 0x0191}, /* 01,91,01,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x3e, 0x0197}, /* 01,97,3e,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0xca, 0x001d}, /* 00,1d,ca,cc */ - {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x36, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,36,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x3e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3e,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0xca, ZC3XX_R01D_HSYNC_0}, /* 00,1d,ca,cc */ + {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ {} }; static const struct usb_action tas5130cxx_60HZScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0077}, /* 00,a4,77,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x77, 0x00a4}, /* 00,a4,77,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ - {0xa0, 0xe8, 0x0192}, /* 01,92,e8,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x7d, 0x0197}, /* 01,97,7d,cc */ - {0xa0, 0x14, 0x018c}, /* 01,8c,14,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x0c, 0x01a9}, /* 01,a9,0c,cc */ - {0xa0, 0x26, 0x01aa}, /* 01,aa,26,cc */ - {0xa0, 0xc8, 0x001d}, /* 00,1d,c8,cc */ - {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x03, 0x009f}, /* 00,9f,03,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x77, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,77,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ + {0xa0, 0xe8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,e8,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x7d, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,7d,cc */ + {0xa0, 0x14, ZC3XX_R18C_AEFREEZE}, /* 01,8c,14,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,0c,cc */ + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,26,cc */ + {0xa0, 0xc8, ZC3XX_R01D_HSYNC_0}, /* 00,1d,c8,cc */ + {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x03, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,03,cc */ {} }; static const struct usb_action tas5130cxx_NoFliker[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0040}, /* 00,a4,40,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x40, 0x00a4}, /* 00,a4,40,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x01, 0x0191}, /* 01,91,01,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0xbc, 0x001d}, /* 00,1d,bc,cc */ - {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x40, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,40,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x01, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,01,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ + {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ {} }; static const struct usb_action tas5130cxx_NoFlikerScale[] = { - {0xa0, 0x00, 0x0019}, /* 00,19,00,cc */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ {0xaa, 0xa3, 0x0001}, /* 00,a3,01,aa */ {0xaa, 0xa4, 0x0090}, /* 00,a4,90,aa */ - {0xa0, 0x01, 0x00a3}, /* 00,a3,01,cc */ - {0xa0, 0x90, 0x00a4}, /* 00,a4,90,cc */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc */ - {0xa0, 0x03, 0x0191}, /* 01,91,03,cc */ - {0xa0, 0xf0, 0x0192}, /* 01,92,f0,cc */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc */ - {0xa0, 0x10, 0x018c}, /* 01,8c,10,cc */ - {0xa0, 0x20, 0x018f}, /* 01,8f,20,cc */ - {0xa0, 0x00, 0x01a9}, /* 01,a9,00,cc */ - {0xa0, 0x00, 0x01aa}, /* 01,aa,00,cc */ - {0xa0, 0xbc, 0x001d}, /* 00,1d,bc,cc */ - {0xa0, 0xd0, 0x001e}, /* 00,1e,d0,cc */ - {0xa0, 0xe0, 0x001f}, /* 00,1f,e0,cc */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc */ - {0xa0, 0x02, 0x009f}, /* 00,9f,02,cc */ + {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH}, /* 00,a3,01,cc */ + {0xa0, 0x90, ZC3XX_R0A4_EXPOSURETIMELOW}, /* 00,a4,90,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,03,cc */ + {0xa0, 0xf0, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,f0,cc */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* 01,8c,10,cc */ + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,20,cc */ + {0xa0, 0x00, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,00,cc */ + {0xa0, 0x00, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,00,cc */ + {0xa0, 0xbc, ZC3XX_R01D_HSYNC_0}, /* 00,1d,bc,cc */ + {0xa0, 0xd0, ZC3XX_R01E_HSYNC_1}, /* 00,1e,d0,cc */ + {0xa0, 0xe0, ZC3XX_R01F_HSYNC_2}, /* 00,1f,e0,cc */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc */ + {0xa0, 0x02, ZC3XX_R09F_MAXXHIGH}, /* 00,9f,02,cc */ {} }; static const struct usb_action tas5130c_vf0250_Initial[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ - {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ - {0xa0, 0x10, 0x0002}, /* 00,02,00,cc, 0<->10 */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc, */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc, */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc, */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc, */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc, */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc, */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc, */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc, */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc, */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc, */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc, */ - {0xa0, 0xe8, 0x009c}, /* 00,9c,e6,cc, 6<->8 */ - {0xa0, 0x88, 0x009e}, /* 00,9e,86,cc, 6<->8 */ - {0xa0, 0x10, 0x0087}, /* 00,87,10,cc, */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ + {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ + {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,00,cc, + * 0<->10 */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e6,cc, + * 6<->8 */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc, + * 6<->8 */ + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ @@ -5971,9 +5988,9 @@ static const struct usb_action tas5130c_vf0250_Initial[] = { {0xaa, 0x01, 0x0000}, {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ - {0xa0, 0x82, 0x0086}, /* 00,86,82,cc, */ - {0xa0, 0x83, 0x0087}, /* 00,87,83,cc, */ - {0xa0, 0x84, 0x0088}, /* 00,88,84,cc, */ + {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ + {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ + {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ @@ -5990,42 +6007,44 @@ static const struct usb_action tas5130c_vf0250_Initial[] = { {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ {0xaa, 0x19, 0x0088}, /* 00,19,86,aa, */ {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ - {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc, */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc, */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc, */ - {0xa0, 0x76, 0x0189}, /* 01,89,76,cc, */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc, */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc, */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc, */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc, */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ - {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ - {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ + {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ + {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ + {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ {} }; static const struct usb_action tas5130c_vf0250_InitialScale[] = { - {0xa0, 0x01, 0x0000}, /* 00,00,01,cc, */ - {0xa0, 0x02, 0x0008}, /* 00,08,02,cc, */ - {0xa0, 0x01, 0x0010}, /* 00,10,01,cc, */ - {0xa0, 0x00, 0x0002}, /* 00,02,10,cc, */ - {0xa0, 0x02, 0x0003}, /* 00,03,02,cc, */ - {0xa0, 0x80, 0x0004}, /* 00,04,80,cc, */ - {0xa0, 0x01, 0x0005}, /* 00,05,01,cc, */ - {0xa0, 0xe0, 0x0006}, /* 00,06,e0,cc, */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ - {0xa0, 0x01, 0x0001}, /* 00,01,01,cc, */ - {0xa0, 0x03, 0x0012}, /* 00,12,03,cc, */ - {0xa0, 0x01, 0x0012}, /* 00,12,01,cc, */ - {0xa0, 0x00, 0x0098}, /* 00,98,00,cc, */ - {0xa0, 0x00, 0x009a}, /* 00,9a,00,cc, */ - {0xa0, 0x00, 0x011a}, /* 01,1a,00,cc, */ - {0xa0, 0x00, 0x011c}, /* 01,1c,00,cc, */ - {0xa0, 0xe8, 0x009c}, /* 00,9c,e8,cc, 8<->6 */ - {0xa0, 0x88, 0x009e}, /* 00,9e,88,cc, 8<->6 */ - {0xa0, 0x10, 0x0087}, /* 00,87,10,cc, */ - {0xa0, 0x98, 0x008b}, /* 00,8b,98,cc, */ + {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc, */ + {0xa0, 0x02, ZC3XX_R008_CLOCKSETTING}, /* 00,08,02,cc, */ + {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc, */ + {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc, */ + {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc, */ + {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc, */ + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc, */ + {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,e0,cc, */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc, */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc, */ + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc, */ + {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc, */ + {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc, */ + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc, */ + {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc, */ + {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,e8,cc, + * 8<->6 */ + {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc, + * 8<->6 */ + {0xa0, 0x10, ZC3XX_R087_EXPTIMEMID}, /* 00,87,10,cc, */ + {0xa0, 0x98, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,98,cc, */ {0xaa, 0x1b, 0x0024}, /* 00,1b,24,aa, */ {0xdd, 0x00, 0x0080}, /* 00,00,80,dd, */ {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ @@ -6035,9 +6054,9 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = { {0xaa, 0x01, 0x0000}, {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ - {0xa0, 0x82, 0x0086}, /* 00,86,82,cc, */ - {0xa0, 0x83, 0x0087}, /* 00,87,83,cc, */ - {0xa0, 0x84, 0x0088}, /* 00,88,84,cc, */ + {0xa0, 0x82, ZC3XX_R086_EXPTIMEHIGH}, /* 00,86,82,cc, */ + {0xa0, 0x83, ZC3XX_R087_EXPTIMEMID}, /* 00,87,83,cc, */ + {0xa0, 0x84, ZC3XX_R088_EXPTIMELOW}, /* 00,88,84,cc, */ {0xaa, 0x05, 0x0010}, /* 00,05,10,aa, */ {0xaa, 0x0a, 0x0000}, /* 00,0a,00,aa, */ {0xaa, 0x0b, 0x00a0}, /* 00,0b,a0,aa, */ @@ -6054,18 +6073,18 @@ static const struct usb_action tas5130c_vf0250_InitialScale[] = { {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ {0xaa, 0x19, 0x0088}, /* 00,19,88,aa, */ {0xaa, 0x20, 0x0020}, /* 00,20,20,aa, */ - {0xa0, 0xb7, 0x0101}, /* 01,01,b7,cc, */ - {0xa0, 0x05, 0x0012}, /* 00,12,05,cc, */ - {0xa0, 0x0d, 0x0100}, /* 01,00,0d,cc, */ - {0xa0, 0x76, 0x0189}, /* 01,89,76,cc, */ - {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ - {0xa0, 0x03, 0x01c5}, /* 01,c5,03,cc, */ - {0xa0, 0x13, 0x01cb}, /* 01,cb,13,cc, */ - {0xa0, 0x08, 0x0250}, /* 02,50,08,cc, */ - {0xa0, 0x08, 0x0301}, /* 03,01,08,cc, */ - {0xa0, 0x60, 0x01a8}, /* 01,a8,60,cc, */ - {0xa0, 0x61, 0x0116}, /* 01,16,61,cc, */ - {0xa0, 0x65, 0x0118}, /* 01,18,65,cc */ + {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,b7,cc, */ + {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc, */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc, */ + {0xa0, 0x76, ZC3XX_R189_AWBSTATUS}, /* 01,89,76,cc, */ + {0xa0, 0x09, 0x01ad}, /* 01,ad,09,cc, */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc, */ + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc, */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc, */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc, */ + {0xa0, 0x60, ZC3XX_R1A8_DIGITALGAIN}, /* 01,a8,60,cc, */ + {0xa0, 0x61, ZC3XX_R116_RGAIN}, /* 01,16,61,cc, */ + {0xa0, 0x65, ZC3XX_R118_BGAIN}, /* 01,18,65,cc */ {} }; /* "50HZ" light frequency banding filter */ @@ -6073,23 +6092,23 @@ static const struct usb_action tas5130c_vf0250_50HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ {0xaa, 0x84, 0x00aa}, /* 00,84,aa,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ - {0xa0, 0x06, 0x0191}, /* 01,91,0d,cc, */ - {0xa0, 0xa8, 0x0192}, /* 01,92,50,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ - {0xa0, 0x8e, 0x0197}, /* 01,97,47,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ - {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ + {0xa0, 0x06, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ + {0xa0, 0xa8, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ + {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,47,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ {} }; @@ -6098,23 +6117,23 @@ static const struct usb_action tas5130c_vf0250_50HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0003}, /* 00,83,03,aa */ {0xaa, 0x84, 0x0054}, /* 00,84,54,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ - {0xa0, 0x0d, 0x0191}, /* 01,91,0d,cc, */ - {0xa0, 0x50, 0x0192}, /* 01,92,50,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ - {0xa0, 0x8e, 0x0197}, /* 01,97,8e,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ - {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ + {0xa0, 0x0d, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0d,cc, */ + {0xa0, 0x50, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,50,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ + {0xa0, 0x8e, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,8e,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ {} }; @@ -6123,23 +6142,23 @@ static const struct usb_action tas5130c_vf0250_60HZ[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0001}, /* 00,83,01,aa */ {0xaa, 0x84, 0x0062}, /* 00,84,62,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ - {0xa0, 0x05, 0x0191}, /* 01,91,05,cc, */ - {0xa0, 0x88, 0x0192}, /* 01,92,88,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ - {0xa0, 0x3b, 0x0197}, /* 01,97,3b,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ - {0xa0, 0x10, 0x01a9}, /* 01,a9,10,cc, */ - {0xa0, 0x24, 0x01aa}, /* 01,aa,24,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ - {0xa0, 0x78, 0x018d}, /* 01,8d,78,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ + {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ + {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ + {0xa0, 0x3b, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,3b,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,a9,10,cc, */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,aa,24,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,8d,78,cc */ {} }; @@ -6148,69 +6167,69 @@ static const struct usb_action tas5130c_vf0250_60HZScale[] = { {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0002}, /* 00,83,02,aa */ {0xaa, 0x84, 0x00c4}, /* 00,84,c4,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ - {0xa0, 0x0b, 0x0191}, /* 01,1,0b,cc, */ - {0xa0, 0x10, 0x0192}, /* 01,2,10,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,5,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,6,00,cc, */ - {0xa0, 0x76, 0x0197}, /* 01,7,76,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,f,15,cc, */ - {0xa0, 0x10, 0x01a9}, /* 01,9,10,cc, */ - {0xa0, 0x24, 0x01aa}, /* 01,a,24,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,0,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,d,58,cc, */ - {0xa0, 0x42, 0x0180}, /* 01,80,42,cc, */ - {0xa0, 0x78, 0x018d}, /* 01,d,78,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ + {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,1,0b,cc, */ + {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,2,10,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,5,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,6,00,cc, */ + {0xa0, 0x76, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,7,76,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,f,15,cc, */ + {0xa0, 0x10, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* 01,9,10,cc, */ + {0xa0, 0x24, ZC3XX_R1AA_DIGITALGAINSTEP}, /* 01,a,24,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,0,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,d,58,cc, */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,42,cc, */ + {0xa0, 0x78, ZC3XX_R18D_YTARGET}, /* 01,d,78,cc */ {} }; /* "NoFliker" light frequency banding flter */ static const struct usb_action tas5130c_vf0250_NoFliker[] = { - {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ + {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, 0x0190}, /* 01,0,00,cc, */ - {0xa0, 0x05, 0x0191}, /* 01,91,05,cc, */ - {0xa0, 0x88, 0x0192}, /* 01,92,88,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ - {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,0,00,cc, */ + {0xa0, 0x05, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,05,cc, */ + {0xa0, 0x88, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,88,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ + {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ {} }; /* "NoFlikerScale" light frequency banding filter */ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = { - {0xa0, 0x0c, 0x0100}, /* 01,00,0c,cc, */ + {0xa0, 0x0c, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0c,cc, */ {0xaa, 0x82, 0x0000}, /* 00,82,00,aa */ {0xaa, 0x83, 0x0000}, /* 00,83,00,aa */ {0xaa, 0x84, 0x0020}, /* 00,84,20,aa */ - {0xa0, 0x00, 0x0190}, /* 01,90,00,cc, */ - {0xa0, 0x0b, 0x0191}, /* 01,91,0b,cc, */ - {0xa0, 0x10, 0x0192}, /* 01,92,10,cc, */ - {0xa0, 0x00, 0x0195}, /* 01,95,00,cc, */ - {0xa0, 0x00, 0x0196}, /* 01,96,00,cc, */ - {0xa0, 0x10, 0x0197}, /* 01,97,10,cc, */ - {0xa0, 0x0e, 0x018c}, /* 01,8c,0e,cc, */ - {0xa0, 0x15, 0x018f}, /* 01,8f,15,cc, */ - {0xa0, 0x62, 0x001d}, /* 00,1d,62,cc, */ - {0xa0, 0x90, 0x001e}, /* 00,1e,90,cc, */ - {0xa0, 0xc8, 0x001f}, /* 00,1f,c8,cc, */ - {0xa0, 0xff, 0x0020}, /* 00,20,ff,cc, */ - {0xa0, 0x58, 0x011d}, /* 01,1d,58,cc, */ - {0xa0, 0x03, 0x0180}, /* 01,80,03,cc */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc, */ + {0xa0, 0x0b, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,0b,cc, */ + {0xa0, 0x10, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,10,cc, */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* 01,95,00,cc, */ + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* 01,96,00,cc, */ + {0xa0, 0x10, ZC3XX_R197_ANTIFLICKERLOW}, /* 01,97,10,cc, */ + {0xa0, 0x0e, ZC3XX_R18C_AEFREEZE}, /* 01,8c,0e,cc, */ + {0xa0, 0x15, ZC3XX_R18F_AEUNFREEZE}, /* 01,8f,15,cc, */ + {0xa0, 0x62, ZC3XX_R01D_HSYNC_0}, /* 00,1d,62,cc, */ + {0xa0, 0x90, ZC3XX_R01E_HSYNC_1}, /* 00,1e,90,cc, */ + {0xa0, 0xc8, ZC3XX_R01F_HSYNC_2}, /* 00,1f,c8,cc, */ + {0xa0, 0xff, ZC3XX_R020_HSYNC_3}, /* 00,20,ff,cc, */ + {0xa0, 0x58, ZC3XX_R11D_GLOBALGAIN}, /* 01,1d,58,cc, */ + {0xa0, 0x03, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,03,cc */ {} }; -- cgit v1.2.3 From 794af52a4ce5279c52f1467448b9e672a7db37f0 Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Wed, 16 Jul 2008 08:33:14 -0300 Subject: V4L/DVB (8360): gspca: Bad initialization of sn9c103 - ov7630. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 62 ++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 7303df0dc16b..054ce4e3ece7 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -254,7 +254,7 @@ static const __u8 ov7630_sensor_init_com[][8] = { {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ - {0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10}, /* jfm */ + {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */ {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10}, {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10}, @@ -262,8 +262,8 @@ static const __u8 ov7630_sensor_init_com[][8] = { {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10}, {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10}, {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10}, -/* {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, jfm */ - {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, /* jfm */ + {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10}, +/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */ {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10}, {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10}, {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10}, @@ -489,6 +489,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) goto err; break; } + case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2cOV[] = {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16}; @@ -583,6 +584,14 @@ static void setsensorgain(struct gspca_dev *gspca_dev) goto err; break; } + case SENSOR_OV7630_3: { + __u8 i2c[] = {0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; + + i2c[3] = sd->gain >> 2; + if (i2c_w(gspca_dev, i2c) < 0) + goto err; + break; + } } return; err: @@ -649,6 +658,34 @@ static void setexposure(struct gspca_dev *gspca_dev) results in no change */ const int reg10_max = 0x4d; + reg11 = (60 * sd->exposure + 999) / 1000; + if (reg11 < 1) + reg11 = 1; + else if (reg11 > 16) + reg11 = 16; + + /* frame exposure time in ms = 1000 * reg11 / 30 -> + reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ + reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); + if (reg10 < 1) /* 0 is a valid value, but is very _black_ */ + reg10 = 1; + else if (reg10 > reg10_max) + reg10 = reg10_max; + + /* Write reg 10 and reg11 low nibble */ + i2c[3] = reg10; + i2c[4] |= reg11 - 1; + if (i2c_w(gspca_dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error exposure"); + break; + } + case SENSOR_OV7630_3: { + __u8 i2c[] = {0xb0, 0x21, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; + int reg10, reg11; + /* No clear idea why, but setting reg10 above this value + results in no change */ + const int reg10_max = 0x4d; + reg11 = (60 * sd->exposure + 999) / 1000; if (reg11 < 1) reg11 = 1; @@ -705,6 +742,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->fr_h_sz = 12; /* default size of the frame header */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */ + sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ product = id->idProduct; /* switch (id->idVendor) { */ @@ -740,6 +778,10 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x60b0: /* SN9C103 */ sd->sensor = SENSOR_OV7630_3; sd->fr_h_sz = 18; /* size of frame header */ + sd->sensor_has_gain = 1; + sd->sd_desc.nctrls = 4; + sd->sd_desc.dq_callback = do_autogain; + sd->autogain = 0; break; case 0x6024: /* SN9C102 */ case 0x6025: /* SN9C102 */ @@ -777,7 +819,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; - sd->autogain = AUTOGAIN_DEF; if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); return 0; @@ -940,18 +981,15 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2); /* compression register */ reg_w(gspca_dev, 0x18, ®17_19[1], 1); - if (sd->sensor != SENSOR_OV7630_3) { - /* H_start */ - reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); - /* V_START */ - reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); - } + /* H_start */ + reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1); + /* V_START */ + reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1); /* reset 0x17 SensorClk enable inv Clk 0x60 */ /*fixme: ov7630 [17]=68 8f (+20 if 102)*/ reg_w(gspca_dev, 0x17, ®17_19[0], 1); /*MCKSIZE ->3 */ /*fixme: not ov7630*/ - if (sd->sensor != SENSOR_OV7630_3) - reg_w(gspca_dev, 0x19, ®17_19[2], 1); + reg_w(gspca_dev, 0x19, ®17_19[2], 1); /* AE_STRX AE_STRY AE_ENDX AE_ENDY */ reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4); /* Enable video transfert */ -- cgit v1.2.3 From b7474cf9f693a83c9a64c8504a08823a34994a2e Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Wed, 16 Jul 2008 08:40:30 -0300 Subject: V4L/DVB (8361): gspca: Bad check of i2c write to sn9c10x. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 054ce4e3ece7..80879bf3188f 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -456,8 +456,11 @@ static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer) while (retry--) { msleep(10); reg_r(gspca_dev, 0x08); - if (gspca_dev->usb_buf[0] == 4) + if (gspca_dev->usb_buf[0] & 0x04) { + if (gspca_dev->usb_buf[0] & 0x08) + return -1; return 0; + } } return -1; } -- cgit v1.2.3 From c36260ee27dff9a0236ddaaee0e3524ecd389645 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 16 Jul 2008 09:56:07 -0300 Subject: V4L/DVB (8362): gspca: Bad offset of the brightness sum in sn9c103 packets. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 80879bf3188f..a512772664a3 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1033,6 +1033,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, int i; struct sd *sd = (struct sd *) gspca_dev; + /* frames start with: + * ff ff 00 c4 c4 96 synchro + * 00 (unknown) + * xx (frame sequence / size / compression) + * (xx) (idem - extra byte for sn9c103) + * ll mm brightness sum inside auto exposure + * ll mm brightness sum outside auto exposure + * (xx xx xx xx xx) audio values for snc103 + */ if (len > 6 && len < 24) { for (i = 0; i < len - 6; i++) { if (data[0 + i] == 0xff @@ -1043,15 +1052,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[5 + i] == 0x96) { /* start of frame */ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - if (i < (len - 10)) { - atomic_set(&sd->avg_lum, data[i + 8] + + if (len - i < sd->fr_h_sz) { + atomic_set(&sd->avg_lum, -1); + PDEBUG(D_STREAM, "packet too short to" + " get avg brightness"); + } else if (sd->fr_h_sz == 12) { + atomic_set(&sd->avg_lum, + data[i + 8] + (data[i + 9] << 8)); } else { - atomic_set(&sd->avg_lum, -1); -#ifdef CONFIG_VIDEO_ADV_DEBUG - PDEBUG(D_STREAM, "packet too short to " - "get avg brightness"); -#endif + atomic_set(&sd->avg_lum, + data[i + 9] + + (data[i + 10] << 8)); } data += i + sd->fr_h_sz; len -= i + sd->fr_h_sz; -- cgit v1.2.3 From 5c6644f305650d3d533b67fc74a96e4a2ea0aa89 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 16 Jul 2008 10:00:08 -0300 Subject: V4L/DVB (8363): gspca: Bad image size with spca501. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/spca501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 8cee6748d38f..50e929de0203 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -104,17 +104,17 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format vga_mode[] = { {160, 120, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, .bytesperline = 160, - .sizeimage = 160 * 120 * 3 / 8, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {320, 240, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, .bytesperline = 320, - .sizeimage = 320 * 240 * 3 / 8, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {640, 480, V4L2_PIX_FMT_SPCA501, V4L2_FIELD_NONE, .bytesperline = 640, - .sizeimage = 640 * 480 * 3 / 8, + .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; -- cgit v1.2.3 From 66f358211d4f8bf1a43e3aef9565c5c1454f73b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 16 Jul 2008 10:16:28 -0300 Subject: V4L/DVB (8364): gspca: Support of powerline frequency for ov6650. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 100 ++++++++++++++++++++++++++++++++++--- 1 file changed, 93 insertions(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index a512772664a3..51435e3dbb10 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -44,6 +44,7 @@ struct sd { unsigned char brightness; unsigned char autogain; unsigned char autogain_ignore_frames; + unsigned char freq; /* light freq filter setting */ unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ @@ -85,6 +86,8 @@ static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -147,6 +150,20 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, + { + { + .id = V4L2_CID_POWER_LINE_FREQUENCY, + .type = V4L2_CTRL_TYPE_MENU, + .name = "Light frequency filter", + .minimum = 0, + .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */ + .step = 1, +#define FREQ_DEF 1 + .default_value = FREQ_DEF, + }, + .set = sd_setfreq, + .get = sd_getfreq, + }, }; static struct v4l2_pix_format vga_mode[] = { @@ -225,11 +242,6 @@ static const __u8 ov6650_sensor_init[][8] = /* Some more unknown stuff */ {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ - {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16}, - /* Framerate adjust register for artificial light 50 hz flicker - compensation, identical to ov6630 0x2b register, see 6630 datasheet. - 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ - {0xa0, 0x60, 0x2b, 0x4f, 0x99, 0x04, 0x94, 0x15}, }; static const __u8 initOv7630[] = { @@ -657,8 +669,12 @@ static void setexposure(struct gspca_dev *gspca_dev) */ __u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; int reg10, reg11; - /* No clear idea why, but setting reg10 above this value - results in no change */ + /* ov6645 datasheet says reg10_max is 9a, but that uses + tline * 2 * reg10 as formula for calculating texpo, the + ov6650 probably uses the same formula as the 7730 which uses + tline * 4 * reg10, which explains why the reg10max we've + found experimentally for the ov6650 is exactly half that of + the ov6645. */ const int reg10_max = 0x4d; reg11 = (60 * sd->exposure + 999) / 1000; @@ -713,6 +729,34 @@ static void setexposure(struct gspca_dev *gspca_dev) } } +static void setfreq(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->sensor) { + case SENSOR_OV6650: { + /* Framerate adjust register for artificial light 50 hz flicker + compensation, identical to ov6630 0x2b register, see ov6630 + datasheet. + 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ + __u8 i2c[] = {0xa0, 0x60, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; + switch (sd->freq) { + default: +/* case 0: * no filter*/ +/* case 2: * 60 hz */ + i2c[3] = 0; + break; + case 1: /* 50 hz */ + i2c[3] = 0x4f; + break; + } + if (i2c_w(gspca_dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error setfreq"); + break; + } + } +} + static void do_autogain(struct gspca_dev *gspca_dev) { @@ -746,6 +790,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->fr_h_sz = 12; /* default size of the frame header */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */ sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ + sd->freq = FREQ_DEF; product = id->idProduct; /* switch (id->idVendor) { */ @@ -1004,6 +1049,7 @@ static void sd_start(struct gspca_dev *gspca_dev) setgain(gspca_dev); setbrightness(gspca_dev); setexposure(gspca_dev); + setfreq(gspca_dev); sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); @@ -1161,6 +1207,45 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->freq = val; + if (gspca_dev->streaming) + setfreq(gspca_dev); + return 0; +} + +static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->freq; + return 0; +} + +static int sd_querymenu(struct gspca_dev *gspca_dev, + struct v4l2_querymenu *menu) +{ + switch (menu->id) { + case V4L2_CID_POWER_LINE_FREQUENCY: + switch (menu->index) { + case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ + strcpy((char *) menu->name, "NoFliker"); + return 0; + case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ + strcpy((char *) menu->name, "50 Hz"); + return 0; + case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ + strcpy((char *) menu->name, "60 Hz"); + return 0; + } + break; + } + return -EINVAL; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1173,6 +1258,7 @@ static const struct sd_desc sd_desc = { .stop0 = sd_stop0, .close = sd_close, .pkt_scan = sd_pkt_scan, + .querymenu = sd_querymenu, }; /* -- module initialisation -- */ -- cgit v1.2.3 From a975a5279e39b5bc104cc8329d25a36a25136ad9 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 16 Jul 2008 15:29:11 -0300 Subject: V4L/DVB (8366): gspca: Better code for ov6650 and ov7630. sonixb: Common code between ov6650 and ov7630. Fix brightness oscillation with ov6650 sensor. Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 91 ++++++++++++++------------------------ 1 file changed, 34 insertions(+), 57 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 51435e3dbb10..4625a464a547 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -48,7 +48,6 @@ struct sd { unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ - char sensor_has_gain; #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 #define SENSOR_OV7630 2 @@ -57,6 +56,8 @@ struct sd { #define SENSOR_PAS202 5 #define SENSOR_TAS5110 6 #define SENSOR_TAS5130CXX 7 + char sensor_has_gain; + __u8 sensor_addr; }; #define COMP2 0x8f @@ -495,21 +496,14 @@ static void setbrightness(struct gspca_dev *gspca_dev) __u8 value; switch (sd->sensor) { - case SENSOR_OV6650: { - __u8 i2cOV6650[] = - {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15}; - - i2cOV6650[3] = sd->brightness; - if (i2c_w(gspca_dev, i2cOV6650) < 0) - goto err; - break; - } + case SENSOR_OV6650: case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2cOV[] = - {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16}; + {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; /* change reg 0x06 */ + i2cOV[1] = sd->sensor_addr; i2cOV[3] = sd->brightness; if (i2c_w(gspca_dev, i2cOV) < 0) goto err; @@ -579,6 +573,7 @@ err: static void setsensorgain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; + unsigned char gain = sd->gain; switch (sd->sensor) { @@ -586,23 +581,20 @@ static void setsensorgain(struct gspca_dev *gspca_dev) __u8 i2c[] = {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}; - i2c[4] = 255 - sd->gain; + i2c[4] = 255 - gain; if (i2c_w(gspca_dev, i2c) < 0) goto err; break; } - case SENSOR_OV6650: { - __u8 i2c[] = {0xa0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[3] = sd->gain >> 3; - if (i2c_w(gspca_dev, i2c) < 0) - goto err; - break; - } + case SENSOR_OV6650: + gain >>= 1; + /* fall thru */ case SENSOR_OV7630_3: { - __u8 i2c[] = {0xa0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; + __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[3] = sd->gain >> 2; + i2c[1] = sd->sensor_addr; + i2c[3] = gain >> 2; if (i2c_w(gspca_dev, i2c) < 0) goto err; break; @@ -652,9 +644,10 @@ static void setexposure(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x19, ®, 1); break; } - case SENSOR_OV6650: { - /* The ov6650 has 2 registers which both influence exposure, - first there is register 11, whose low nibble sets the no fps + case SENSOR_OV6650: + case SENSOR_OV7630_3: { + /* The ov6650 / ov7630 have 2 registers which both influence + exposure, register 11, whose low nibble sets the nr off fps according to: fps = 30 / (low_nibble + 1) The fps configures the maximum exposure setting, but it is @@ -667,15 +660,15 @@ static void setexposure(struct gspca_dev *gspca_dev) The code maps our 0 - 510 ms exposure ctrl to these 2 registers, trying to keep fps as high as possible. */ - __u8 i2c[] = {0xb0, 0x60, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; + __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; int reg10, reg11; /* ov6645 datasheet says reg10_max is 9a, but that uses tline * 2 * reg10 as formula for calculating texpo, the ov6650 probably uses the same formula as the 7730 which uses tline * 4 * reg10, which explains why the reg10max we've found experimentally for the ov6650 is exactly half that of - the ov6645. */ - const int reg10_max = 0x4d; + the ov6645. The ov7630 datasheet says the max is 0x41. */ + const int reg10_max = (sd->sensor == SENSOR_OV6650)? 0x4d:0x41; reg11 = (60 * sd->exposure + 999) / 1000; if (reg11 < 1) @@ -686,40 +679,18 @@ static void setexposure(struct gspca_dev *gspca_dev) /* frame exposure time in ms = 1000 * reg11 / 30 -> reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); - if (reg10 < 1) /* 0 is a valid value, but is very _black_ */ - reg10 = 1; - else if (reg10 > reg10_max) - reg10 = reg10_max; - /* Write reg 10 and reg11 low nibble */ - i2c[3] = reg10; - i2c[4] |= reg11 - 1; - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error exposure"); - break; - } - case SENSOR_OV7630_3: { - __u8 i2c[] = {0xb0, 0x21, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; - int reg10, reg11; - /* No clear idea why, but setting reg10 above this value - results in no change */ - const int reg10_max = 0x4d; - - reg11 = (60 * sd->exposure + 999) / 1000; - if (reg11 < 1) - reg11 = 1; - else if (reg11 > 16) - reg11 = 16; - - /* frame exposure time in ms = 1000 * reg11 / 30 -> - reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */ - reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11); - if (reg10 < 1) /* 0 is a valid value, but is very _black_ */ - reg10 = 1; + /* Don't allow this to get below 10 when using autogain, the + steps become very large (relatively) when below 10 causing + the image to oscilate from much too dark, to much too bright + and back again. */ + if (sd->autogain && reg10 < 10) + reg10 = 10; else if (reg10 > reg10_max) reg10 = reg10_max; /* Write reg 10 and reg11 low nibble */ + i2c[1] = sd->sensor_addr; i2c[3] = reg10; i2c[4] |= reg11 - 1; if (i2c_w(gspca_dev, i2c) < 0) @@ -770,8 +741,11 @@ static void do_autogain(struct gspca_dev *gspca_dev) sd->autogain_ignore_frames--; else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, sd->brightness * DESIRED_AVG_LUM / 127, - AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) + AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) { + PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n", + (int)sd->gain, (int)sd->exposure); sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; + } } /* this function is called at probe time */ @@ -814,6 +788,7 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x6011: /* SN9C101 - SN9C101G */ sd->sensor = SENSOR_OV6650; sd->sensor_has_gain = 1; + sd->sensor_addr = 0x60; sd->sd_desc.nctrls = 4; sd->sd_desc.dq_callback = do_autogain; sif = 1; @@ -822,9 +797,11 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x602c: /* SN9C102 */ case 0x602e: /* SN9C102 */ sd->sensor = SENSOR_OV7630; + sd->sensor_addr = 0x21; break; case 0x60b0: /* SN9C103 */ sd->sensor = SENSOR_OV7630_3; + sd->sensor_addr = 0x21; sd->fr_h_sz = 18; /* size of frame header */ sd->sensor_has_gain = 1; sd->sd_desc.nctrls = 4; -- cgit v1.2.3 From d87616f5a5af028d399f2c3e14c3115c67e415cf Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Thu, 17 Jul 2008 05:35:52 -0300 Subject: V4L/DVB (8367): gspca: Light frequency filter / exposure / clean-up for sn9c103 ov7630. Signed-off-by: Andoni Zubimendi Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 41 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 4625a464a547..045ed6b7d053 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -291,22 +291,9 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ }; -static const __u8 ov7630_sensor_init_3[][5][8] = { - { {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ - {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ - {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d}, - }, - { {0xa0, 0x21, 0x10, 0x83, 0xbd, 0x06, 0xf6, 0x16}, /* exposure */ - {0xa0, 0x21, 0x76, 0x00, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x11, 0x00, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ -/* {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d}, - * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */ -/* {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d}, * from win */ - {0xb0, 0x21, 0x2a, 0x80, 0x60, 0x06, 0xf6, 0x1d}, - } +static const __u8 ov7630_sensor_init_3[][8] = { + {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10}, + {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10}, }; static const __u8 initPas106[] = { @@ -693,6 +680,15 @@ static void setexposure(struct gspca_dev *gspca_dev) i2c[1] = sd->sensor_addr; i2c[3] = reg10; i2c[4] |= reg11 - 1; + if (sd->sensor == SENSOR_OV7630_3) { + __u8 reg76 = reg10 & 0x03; + __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, + 0x00, 0x00, 0x00, 0x10}; + reg10 >>= 2; + i2c_reg76[3] = reg76; + if (i2c_w(gspca_dev, i2c_reg76) < 0) + PDEBUG(D_ERR, "i2c error exposure"); + } if (i2c_w(gspca_dev, i2c) < 0) PDEBUG(D_ERR, "i2c error exposure"); break; @@ -705,12 +701,13 @@ static void setfreq(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; switch (sd->sensor) { - case SENSOR_OV6650: { + case SENSOR_OV6650: + case SENSOR_OV7630_3: { /* Framerate adjust register for artificial light 50 hz flicker compensation, identical to ov6630 0x2b register, see ov6630 datasheet. 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ - __u8 i2c[] = {0xa0, 0x60, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; + __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; switch (sd->freq) { default: /* case 0: * no filter*/ @@ -718,9 +715,10 @@ static void setfreq(struct gspca_dev *gspca_dev) i2c[3] = 0; break; case 1: /* 50 hz */ - i2c[3] = 0x4f; + i2c[3] = (sd->sensor == SENSOR_OV6650)? 0x4f:0x8a; break; } + i2c[1] = sd->sensor_addr; if (i2c_w(gspca_dev, i2c) < 0) PDEBUG(D_ERR, "i2c error setfreq"); break; @@ -804,7 +802,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor_addr = 0x21; sd->fr_h_sz = 18; /* size of frame header */ sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 4; + sd->sd_desc.nctrls = 5; sd->sd_desc.dq_callback = do_autogain; sd->autogain = 0; break; @@ -982,8 +980,7 @@ static void sd_start(struct gspca_dev *gspca_dev) i2c_w_vector(gspca_dev, ov7630_sensor_init_com, sizeof ov7630_sensor_init_com); msleep(200); - i2c_w_vector(gspca_dev, ov7630_sensor_init_3[mode], - sizeof ov7630_sensor_init_3[mode]); + i2c_w(gspca_dev, ov7630_sensor_init_3[mode]); break; case SENSOR_PAS106: pas106_i2cinit(gspca_dev); -- cgit v1.2.3 From 1ff1e48442188b9ae68aef82b66baef89e988cf6 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 17 Jul 2008 09:37:57 -0300 Subject: V4L/DVB (8369): gspca: Bad initialization of sn9c102 ov7630. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 2 +- drivers/media/video/gspca/vc032x.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 045ed6b7d053..f1b16d4451f2 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -938,7 +938,7 @@ static void sd_start(struct gspca_dev *gspca_dev) case SENSOR_OV7630: reg01 = 0x06; reg17 = 0x29; - l = 0x10; + l = sizeof initOv7630; break; case SENSOR_OV7630_3: reg01 = 0x44; diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index dd7c1389f38d..fcf2c9e32573 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -925,14 +925,14 @@ static const __u8 ov7660_initQVGA_data[][4] = { {0xb8, 0x8f, 0xff, 0xcc}, /* ff */ {0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc}, /* 45 */ - {0x00, 0x00, 0x00, 0x00} + {} }; static const __u8 ov7660_50HZ[][4] = { {0x00, 0x3b, 0x08, 0xaa}, {0x00, 0x9d, 0x40, 0xaa}, {0x00, 0x13, 0xa7, 0xaa}, - {0x00, 0x00, 0x00, 0x00} + {} }; static const __u8 ov7660_60HZ[][4] = { -- cgit v1.2.3 From 100f7f2a34ded88e79ecbeaf9ed46c58fbdf339c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 17 Jul 2008 09:41:03 -0300 Subject: V4L/DVB (8370): gspca: Webcam 0461:0821 added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 4 ++-- drivers/media/video/gspca/sunplus.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f1b16d4451f2..7099c3770b3e 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -24,8 +24,8 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) +static const char version[] = "2.1.8"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index acd4a077198a..7fa280d731a3 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,8 +24,8 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) +static const char version[] = "2.1.8"; MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); @@ -825,6 +825,13 @@ static int sd_config(struct gspca_dev *gspca_dev, /* case 0x7006: */ sd->bridge = BRIDGE_SPCA504B; /* break; */ +/* } */ + break; + case 0x0461: /* MicroInnovation */ +/* switch (product) { */ +/* case 0x0821: */ + sd->bridge = BRIDGE_SPCA533; +/* break; */ /* } */ break; case 0x046d: /* Logitech Labtec */ @@ -1579,6 +1586,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, + {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")}, {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, -- cgit v1.2.3 From c91256c27b9509624df2619271cfca9ec5436f8f Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 17 Jul 2008 10:12:55 -0300 Subject: V4L/DVB (8371): gspca: Webcam 08ca:2050 added. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 2 ++ drivers/media/video/gspca/sunplus.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 24f55a0cc027..0c4880af57a3 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -46,6 +46,7 @@ sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 ov519 045e:028c Micro$oft xbox cam spca508 0461:0815 Micro Innovation IC200 +sunplus 0461:0821 Fujifilm MV-1 zc3xx 0461:0a00 MicroInnovation WebCam320 spca500 046d:0890 Logitech QuickCam traveler vc032x 046d:0892 Logitech Orbicam @@ -169,6 +170,7 @@ sunplus 08ca:2024 Aiptek DV3500 Mpeg4 sunplus 08ca:2028 Aiptek PocketCam4M sunplus 08ca:2040 Aiptek PocketDV4100M sunplus 08ca:2042 Aiptek PocketDV5100 +sunplus 08ca:2050 Medion MD 41437 sunplus 08ca:2060 Aiptek PocketDV5300 tv8532 0923:010f ICM532 cams mars 093a:050f Mars-Semi Pc-Camera diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 7fa280d731a3..abd7bef9b3d1 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -1008,6 +1008,7 @@ static int sd_config(struct gspca_dev *gspca_dev, break; case 0x2040: case 0x2042: + case 0x2050: case 0x2060: sd->bridge = BRIDGE_SPCA536; break; @@ -1636,6 +1637,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, + {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")}, {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, {} -- cgit v1.2.3 From 722103e390bb0a526f71440f44bf7f891614e1d6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 17 Jul 2008 10:24:47 -0300 Subject: V4L/DVB (8372): gspca: Small ov6650 fixes. 1) Don't change the red and blue pre-gain's from their defaults 2) Actually make the powerline freq ctrl available to userspace Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 7099c3770b3e..d34d582e5f59 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -238,8 +238,15 @@ static const __u8 ov6650_sensor_init[][8] = {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */ {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10}, - /* Disable autobright ? */ - {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, + /* Enable rgb brightness control */ + {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10}, + /* HDG: Note windows uses the line below, which sets both register 0x60 + and 0x61 I believe these registers of the ov6650 are identical as + those of the ov7630, because if this is true the windows settings + add a bit additional red gain and a lot additional blue gain, which + matches my findings that the windows settings make blue much too + blue and red a little too red. + {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */ /* Some more unknown stuff */ {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10}, {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */ @@ -655,7 +662,8 @@ static void setexposure(struct gspca_dev *gspca_dev) tline * 4 * reg10, which explains why the reg10max we've found experimentally for the ov6650 is exactly half that of the ov6645. The ov7630 datasheet says the max is 0x41. */ - const int reg10_max = (sd->sensor == SENSOR_OV6650)? 0x4d:0x41; + const int reg10_max = (sd->sensor == SENSOR_OV6650) + ? 0x4d : 0x41; reg11 = (60 * sd->exposure + 999) / 1000; if (reg11 < 1) @@ -715,7 +723,8 @@ static void setfreq(struct gspca_dev *gspca_dev) i2c[3] = 0; break; case 1: /* 50 hz */ - i2c[3] = (sd->sensor == SENSOR_OV6650)? 0x4f:0x8a; + i2c[3] = (sd->sensor == SENSOR_OV6650) + ? 0x4f : 0x8a; break; } i2c[1] = sd->sensor_addr; @@ -787,7 +796,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor = SENSOR_OV6650; sd->sensor_has_gain = 1; sd->sensor_addr = 0x60; - sd->sd_desc.nctrls = 4; + sd->sd_desc.nctrls = 5; sd->sd_desc.dq_callback = do_autogain; sif = 1; break; -- cgit v1.2.3 From 12ff91264ce3e2f24013d667d44ba786f947506c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 17 Jul 2008 10:30:56 -0300 Subject: V4L/DVB (8373): gspca: Hue, saturation and contrast controls added for sn9c10x ovxxxx. (does not work with ov6650) Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 177 ++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index d34d582e5f59..5b3490ad661a 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -45,6 +45,9 @@ struct sd { unsigned char autogain; unsigned char autogain_ignore_frames; unsigned char freq; /* light freq filter setting */ + unsigned char saturation; + unsigned char hue; + unsigned char contrast; unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ @@ -89,6 +92,12 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -165,6 +174,48 @@ static struct ctrl sd_ctrls[] = { .set = sd_setfreq, .get = sd_getfreq, }, + { + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, +#define SATURATION_DEF 127 + .default_value = SATURATION_DEF, + }, + .set = sd_setsaturation, + .get = sd_getsaturation, + }, + { + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 255, + .step = 1, +#define HUE_DEF 127 + .default_value = HUE_DEF, + }, + .set = sd_sethue, + .get = sd_gethue, + }, + { + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, +#define CONTRAST_DEF 127 + .default_value = CONTRAST_DEF, + }, + .set = sd_setcontrast, + .get = sd_getcontrast, + }, }; static struct v4l2_pix_format vga_mode[] = { @@ -735,6 +786,68 @@ static void setfreq(struct gspca_dev *gspca_dev) } } +static void setsaturation(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->sensor) { +/* case SENSOR_OV6650: */ + case SENSOR_OV7630_3: + case SENSOR_OV7630: { + __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; + i2c[1] = sd->sensor_addr; + i2c[3] = sd->saturation & 0xf0; + if (i2c_w(gspca_dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error setsaturation"); + else + PDEBUG(D_CONF, "saturation set to: %d", + (int)sd->saturation); + break; + } + } +} + +static void sethue(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->sensor) { +/* case SENSOR_OV6650: */ + case SENSOR_OV7630_3: + case SENSOR_OV7630: { + __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; + i2c[1] = sd->sensor_addr; + i2c[3] = 0x20 | (sd->hue >> 3); + if (i2c_w(gspca_dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error setsaturation"); + else + PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue); + break; + } + } +} + +static void setcontrast(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + + switch (sd->sensor) { +/* case SENSOR_OV6650: */ + case SENSOR_OV7630_3: + case SENSOR_OV7630: { + __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; + i2c[1] = sd->sensor_addr; + i2c[3] = 0x20 | (sd->contrast >> 3); + if (i2c_w(gspca_dev, i2c) < 0) + PDEBUG(D_ERR, "i2c error setcontrast"); + else + PDEBUG(D_CONF, "contrast set to: %d", + (int)sd->contrast); + break; + } + } +} + static void do_autogain(struct gspca_dev *gspca_dev) { @@ -771,7 +884,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->fr_h_sz = 12; /* default size of the frame header */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */ sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ - sd->freq = FREQ_DEF; product = id->idProduct; /* switch (id->idVendor) { */ @@ -811,7 +923,7 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->sensor_addr = 0x21; sd->fr_h_sz = 18; /* size of frame header */ sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 5; + sd->sd_desc.nctrls = 8; sd->sd_desc.dq_callback = do_autogain; sd->autogain = 0; break; @@ -851,6 +963,10 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; + sd->freq = FREQ_DEF; + sd->contrast = CONTRAST_DEF; + sd->saturation = SATURATION_DEF; + sd->hue = HUE_DEF; if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); return 0; @@ -1033,6 +1149,9 @@ static void sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setexposure(gspca_dev); setfreq(gspca_dev); + setsaturation(gspca_dev); + sethue(gspca_dev); + setcontrast(gspca_dev); sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); @@ -1208,6 +1327,60 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->saturation = val; + if (gspca_dev->streaming) + setsaturation(gspca_dev); + return 0; +} + +static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->saturation; + return 0; +} + +static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->hue = val; + if (gspca_dev->streaming) + sethue(gspca_dev); + return 0; +} + +static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->hue; + return 0; +} + +static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->contrast = val; + if (gspca_dev->streaming) + setcontrast(gspca_dev); + return 0; +} + +static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->contrast; + return 0; +} + static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { -- cgit v1.2.3 From 5de39b2b1f68253d79f3548ef2d103fd5edae563 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 17 Jul 2008 10:34:28 -0300 Subject: V4L/DVB (8374): gspca: No conflict of 0c45:6011 with the sn9c102 driver. The sn9c102 driver claims to support usb-ID 0x0c45:0x6011, which is a sn9c102 with ov6650 sensor, but the sn9c102 driver does not support the ov6650 sensor (tested). Also the sn9c102 driver claims to support usb-ID 0x0c45:0x603f, which is a sn9c102 with CISVF10 sensor, but the sn9c102 driver does not support the CISVF10 sensor (not tested). Signed-off-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 2 ++ drivers/media/video/sn9c102/sn9c102_devtable.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 5b3490ad661a..dbeebe8625c5 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1426,7 +1426,9 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, +#endif {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, +#ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h index 35223e0d7e49..6ff489baacf3 100644 --- a/drivers/media/video/sn9c102/sn9c102_devtable.h +++ b/drivers/media/video/sn9c102/sn9c102_devtable.h @@ -44,7 +44,6 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x6005, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6007, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6009, BRIDGE_SN9C102), }, - { SN9C102_USB_DEVICE(0x0c45, 0x6011, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x600d, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6019, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6024, BRIDGE_SN9C102), }, @@ -57,7 +56,6 @@ static const struct usb_device_id sn9c102_id_table[] = { { SN9C102_USB_DEVICE(0x0c45, 0x602d, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x602e, BRIDGE_SN9C102), }, { SN9C102_USB_DEVICE(0x0c45, 0x6030, BRIDGE_SN9C102), }, - { SN9C102_USB_DEVICE(0x0c45, 0x603f, BRIDGE_SN9C102), }, /* SN9C103 */ { SN9C102_USB_DEVICE(0x0c45, 0x6080, BRIDGE_SN9C103), }, { SN9C102_USB_DEVICE(0x0c45, 0x6082, BRIDGE_SN9C103), }, -- cgit v1.2.3 From cb5aa1c62df81ba2cdbae7f7ce469b231d43aba6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 11:08:40 -0300 Subject: V4L/DVB (8376): cx25840: move cx25840_vbi_setup to core.c and rename to cx25840_std_setup cx25840_vbi_setup has nothing to do with setting up VBI, but everything with setting up the standard. Move to cx25840-core.c and rename. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 153 ++++++++++++++++++++++++++++- drivers/media/video/cx25840/cx25840-core.h | 2 +- drivers/media/video/cx25840/cx25840-vbi.c | 152 +--------------------------- 3 files changed, 155 insertions(+), 152 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 8d5f25caf01b..120c498cb60c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -237,7 +237,7 @@ static void cx25840_initialize(struct i2c_client *client) cx25840_write(client, 0x8d3, 0x1f); cx25840_write(client, 0x8e3, 0x03); - cx25840_vbi_setup(client); + cx25840_std_setup(client); /* trial and error says these are needed to get audio */ cx25840_write(client, 0x914, 0xa0); @@ -337,7 +337,7 @@ static void cx23885_initialize(struct i2c_client *client) finish_wait(&state->fw_wait, &wait); destroy_workqueue(q); - cx25840_vbi_setup(client); + cx25840_std_setup(client); /* (re)set input */ set_input(client, state->vid_input, state->aud_input); @@ -348,6 +348,153 @@ static void cx23885_initialize(struct i2c_client *client) /* ----------------------------------------------------------------------- */ +void cx25840_std_setup(struct i2c_client *client) +{ + struct cx25840_state *state = i2c_get_clientdata(client); + v4l2_std_id std = state->std; + int hblank, hactive, burst, vblank, vactive, sc; + int vblank656, src_decimation; + int luma_lpf, uv_lpf, comb; + u32 pll_int, pll_frac, pll_post; + + /* datasheet startup, step 8d */ + if (std & ~V4L2_STD_NTSC) + cx25840_write(client, 0x49f, 0x11); + else + cx25840_write(client, 0x49f, 0x14); + + if (std & V4L2_STD_625_50) { + hblank = 132; + hactive = 720; + burst = 93; + vblank = 36; + vactive = 580; + vblank656 = 40; + src_decimation = 0x21f; + luma_lpf = 2; + + if (std & V4L2_STD_SECAM) { + uv_lpf = 0; + comb = 0; + sc = 0x0a425f; + } else if (std == V4L2_STD_PAL_Nc) { + uv_lpf = 1; + comb = 0x20; + sc = 556453; + } else { + uv_lpf = 1; + comb = 0x20; + sc = 688739; + } + } else { + hactive = 720; + hblank = 122; + vactive = 487; + luma_lpf = 1; + uv_lpf = 1; + + src_decimation = 0x21f; + if (std == V4L2_STD_PAL_60) { + vblank = 26; + vblank656 = 26; + burst = 0x5b; + luma_lpf = 2; + comb = 0x20; + sc = 688739; + } else if (std == V4L2_STD_PAL_M) { + vblank = 20; + vblank656 = 24; + burst = 0x61; + comb = 0x20; + sc = 555452; + } else { + vblank = 26; + vblank656 = 26; + burst = 0x5b; + comb = 0x66; + sc = 556063; + } + } + + /* DEBUG: Displays configured PLL frequency */ + pll_int = cx25840_read(client, 0x108); + pll_frac = cx25840_read4(client, 0x10c) & 0x1ffffff; + pll_post = cx25840_read(client, 0x109); + v4l_dbg(1, cx25840_debug, client, + "PLL regs = int: %u, frac: %u, post: %u\n", + pll_int, pll_frac, pll_post); + + if (pll_post) { + int fin, fsc; + int pll = (28636363L * ((((u64)pll_int) << 25L) + pll_frac)) >> 25L; + + pll /= pll_post; + v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", + pll / 1000000, pll % 1000000); + v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", + pll / 8000000, (pll / 8) % 1000000); + + fin = ((u64)src_decimation * pll) >> 12; + v4l_dbg(1, cx25840_debug, client, + "ADC Sampling freq = %d.%06d MHz\n", + fin / 1000000, fin % 1000000); + + fsc = (((u64)sc) * pll) >> 24L; + v4l_dbg(1, cx25840_debug, client, + "Chroma sub-carrier freq = %d.%06d MHz\n", + fsc / 1000000, fsc % 1000000); + + v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " + "vblank %i, vactive %i, vblank656 %i, src_dec %i, " + "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x, " + "sc 0x%06x\n", + hblank, hactive, vblank, vactive, vblank656, + src_decimation, burst, luma_lpf, uv_lpf, comb, sc); + } + + /* Sets horizontal blanking delay and active lines */ + cx25840_write(client, 0x470, hblank); + cx25840_write(client, 0x471, + 0xff & (((hblank >> 8) & 0x3) | (hactive << 4))); + cx25840_write(client, 0x472, hactive >> 4); + + /* Sets burst gate delay */ + cx25840_write(client, 0x473, burst); + + /* Sets vertical blanking delay and active duration */ + cx25840_write(client, 0x474, vblank); + cx25840_write(client, 0x475, + 0xff & (((vblank >> 8) & 0x3) | (vactive << 4))); + cx25840_write(client, 0x476, vactive >> 4); + cx25840_write(client, 0x477, vblank656); + + /* Sets src decimation rate */ + cx25840_write(client, 0x478, 0xff & src_decimation); + cx25840_write(client, 0x479, 0xff & (src_decimation >> 8)); + + /* Sets Luma and UV Low pass filters */ + cx25840_write(client, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); + + /* Enables comb filters */ + cx25840_write(client, 0x47b, comb); + + /* Sets SC Step*/ + cx25840_write(client, 0x47c, sc); + cx25840_write(client, 0x47d, 0xff & sc >> 8); + cx25840_write(client, 0x47e, 0xff & sc >> 16); + + /* Sets VBI parameters */ + if (std & V4L2_STD_625_50) { + cx25840_write(client, 0x47f, 0x01); + state->vbi_line_offset = 5; + } else { + cx25840_write(client, 0x47f, 0x00); + state->vbi_line_offset = 8; + } +} + +/* ----------------------------------------------------------------------- */ + static void input_change(struct i2c_client *client) { struct cx25840_state *state = i2c_get_clientdata(client); @@ -565,7 +712,7 @@ static int set_v4lstd(struct i2c_client *client) } cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_and_or(client, 0x403, ~0x3, pal_m); - cx25840_vbi_setup(client); + cx25840_std_setup(client); if (!state->is_cx25836) input_change(client); return 0; diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 8bf797f48b09..27d8e52cd67e 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h @@ -61,6 +61,7 @@ int cx25840_write4(struct i2c_client *client, u16 addr, u32 value); u8 cx25840_read(struct i2c_client *client, u16 addr); u32 cx25840_read4(struct i2c_client *client, u16 addr); int cx25840_and_or(struct i2c_client *client, u16 addr, unsigned mask, u8 value); +void cx25840_std_setup(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-firmware.c */ @@ -73,7 +74,6 @@ void cx25840_audio_set_path(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-vbi.c */ -void cx25840_vbi_setup(struct i2c_client *client); int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg); #endif diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c index c754b9d13369..69f2bbdbb929 100644 --- a/drivers/media/video/cx25840/cx25840-vbi.c +++ b/drivers/media/video/cx25840/cx25840-vbi.c @@ -82,150 +82,6 @@ static int decode_vps(u8 * dst, u8 * p) return err & 0xf0; } -void cx25840_vbi_setup(struct i2c_client *client) -{ - struct cx25840_state *state = i2c_get_clientdata(client); - v4l2_std_id std = state->std; - int hblank,hactive,burst,vblank,vactive,sc,vblank656,src_decimation; - int luma_lpf,uv_lpf, comb; - u32 pll_int,pll_frac,pll_post; - - /* datasheet startup, step 8d */ - if (std & ~V4L2_STD_NTSC) { - cx25840_write(client, 0x49f, 0x11); - } else { - cx25840_write(client, 0x49f, 0x14); - } - - if (std & V4L2_STD_625_50) { - hblank=0x084; - hactive=0x2d0; - burst=0x5d; - vblank=0x024; - vactive=0x244; - vblank656=0x28; - src_decimation=0x21f; - - luma_lpf=2; - if (std & V4L2_STD_SECAM) { - uv_lpf=0; - comb=0; - sc=0x0a425f; - } else if (std == V4L2_STD_PAL_Nc) { - uv_lpf=1; - comb=0x20; - sc=556453; - } else { - uv_lpf=1; - comb=0x20; - sc=0x0a8263; - } - } else { - hactive=720; - hblank=122; - vactive=487; - luma_lpf=1; - uv_lpf=1; - - src_decimation=0x21f; - if (std == V4L2_STD_PAL_60) { - vblank=26; - vblank656=26; - burst=0x5b; - luma_lpf=2; - comb=0x20; - sc=0x0a8263; - } else if (std == V4L2_STD_PAL_M) { - vblank=20; - vblank656=24; - burst=0x61; - comb=0x20; - - sc=555452; - } else { - vblank=26; - vblank656=26; - burst=0x5b; - comb=0x66; - sc=556063; - } - } - - /* DEBUG: Displays configured PLL frequency */ - pll_int=cx25840_read(client, 0x108); - pll_frac=cx25840_read4(client, 0x10c)&0x1ffffff; - pll_post=cx25840_read(client, 0x109); - v4l_dbg(1, cx25840_debug, client, - "PLL regs = int: %u, frac: %u, post: %u\n", - pll_int,pll_frac,pll_post); - - if (pll_post) { - int fin, fsc; - int pll= (28636363L*((((u64)pll_int)<<25L)+pll_frac)) >>25L; - - pll/=pll_post; - v4l_dbg(1, cx25840_debug, client, "PLL = %d.%06d MHz\n", - pll/1000000, pll%1000000); - v4l_dbg(1, cx25840_debug, client, "PLL/8 = %d.%06d MHz\n", - pll/8000000, (pll/8)%1000000); - - fin=((u64)src_decimation*pll)>>12; - v4l_dbg(1, cx25840_debug, client, "ADC Sampling freq = " - "%d.%06d MHz\n", - fin/1000000,fin%1000000); - - fsc= (((u64)sc)*pll) >> 24L; - v4l_dbg(1, cx25840_debug, client, "Chroma sub-carrier freq = " - "%d.%06d MHz\n", - fsc/1000000,fsc%1000000); - - v4l_dbg(1, cx25840_debug, client, "hblank %i, hactive %i, " - "vblank %i, vactive %i, vblank656 %i, src_dec %i, " - "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," - " sc 0x%06x\n", - hblank, hactive, vblank, vactive, vblank656, - src_decimation, burst, luma_lpf, uv_lpf, comb, sc); - } - - /* Sets horizontal blanking delay and active lines */ - cx25840_write(client, 0x470, hblank); - cx25840_write(client, 0x471, 0xff&(((hblank>>8)&0x3)|(hactive <<4))); - cx25840_write(client, 0x472, hactive>>4); - - /* Sets burst gate delay */ - cx25840_write(client, 0x473, burst); - - /* Sets vertical blanking delay and active duration */ - cx25840_write(client, 0x474, vblank); - cx25840_write(client, 0x475, 0xff&(((vblank>>8)&0x3)|(vactive <<4))); - cx25840_write(client, 0x476, vactive>>4); - cx25840_write(client, 0x477, vblank656); - - /* Sets src decimation rate */ - cx25840_write(client, 0x478, 0xff&src_decimation); - cx25840_write(client, 0x479, 0xff&(src_decimation>>8)); - - /* Sets Luma and UV Low pass filters */ - cx25840_write(client, 0x47a, luma_lpf<<6|((uv_lpf<<4)&0x30)); - - /* Enables comb filters */ - cx25840_write(client, 0x47b, comb); - - /* Sets SC Step*/ - cx25840_write(client, 0x47c, sc); - cx25840_write(client, 0x47d, 0xff&sc>>8); - cx25840_write(client, 0x47e, 0xff&sc>>16); - - /* Sets VBI parameters */ - if (std & V4L2_STD_625_50) { - cx25840_write(client, 0x47f, 0x01); - state->vbi_line_offset = 5; - } else { - cx25840_write(client, 0x47f, 0x00); - state->vbi_line_offset = 8; - } -} - int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) { struct cx25840_state *state = i2c_get_clientdata(client); @@ -292,8 +148,8 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) /* raw VBI */ memset(svbi, 0, sizeof(*svbi)); - /* Setup VBI */ - cx25840_vbi_setup(client); + /* Setup standard */ + cx25840_std_setup(client); /* VBI Offset */ cx25840_write(client, 0x47f, vbi_offset); @@ -304,8 +160,8 @@ int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg) for (x = 0; x <= 23; x++) lcr[x] = 0x00; - /* Setup VBI */ - cx25840_vbi_setup(client); + /* Setup standard */ + cx25840_std_setup(client); /* Sliced VBI */ cx25840_write(client, 0x404, 0x32); /* Ancillary data */ -- cgit v1.2.3 From ca130eef2ca185739a440b893e69fe36038b87c9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 12:26:45 -0300 Subject: V4L/DVB (8377): ivtv/cx18: ensure the default control values are correct For several MPEG controls and the volume control the default as returned by VIDIOC_QUERYCTRL was incorrect and did not match the actual initial value. This is now fixed for cx18 and ivtv. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 5 + drivers/media/video/cx18/cx18-av-core.h | 1 + drivers/media/video/cx2341x.c | 151 ++++++++++++++++------------- drivers/media/video/cx25840/cx25840-core.c | 4 + drivers/media/video/cx25840/cx25840-core.h | 1 + 5 files changed, 92 insertions(+), 70 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 3ccdf613bce0..124014253569 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -80,6 +80,7 @@ static void log_video_status(struct cx18 *cx); static void cx18_av_initialize(struct cx18 *cx) { + struct cx18_av_state *state = &cx->av_state; u32 v; cx18_av_loadfw(cx); @@ -159,6 +160,8 @@ static void cx18_av_initialize(struct cx18 *cx) /* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ /* } */ cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); + state->default_volume = 228 - cx18_av_read(cx, 0x8d4); + state->default_volume = ((state->default_volume / 2) + 23) << 9; } /* ----------------------------------------------------------------------- */ @@ -559,6 +562,8 @@ int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) switch (qc->id) { case V4L2_CID_AUDIO_VOLUME: + return v4l2_ctrl_query_fill(qc, 0, 65535, + 65535 / 100, state->default_volume); case V4L2_CID_AUDIO_MUTE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index b54239959a68..49e31bccc557 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -79,6 +79,7 @@ struct cx18_av_state { u32 audclk_freq; int audmode; int vbi_line_offset; + int default_volume; u32 id; u32 rev; int is_initialized; diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c index 5e40c6bd69b6..22847a0444f5 100644 --- a/drivers/media/video/cx2341x.c +++ b/drivers/media/video/cx2341x.c @@ -77,6 +77,61 @@ const u32 cx2341x_mpeg_ctrls[] = { }; EXPORT_SYMBOL(cx2341x_mpeg_ctrls); +static const struct cx2341x_mpeg_params default_params = { + /* misc */ + .capabilities = 0, + .port = CX2341X_PORT_MEMORY, + .width = 720, + .height = 480, + .is_50hz = 0, + + /* stream */ + .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS, + .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE, + .stream_insert_nav_packets = 0, + + /* audio */ + .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, + .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, + .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K, + .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO, + .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, + .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, + .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE, + .audio_mute = 0, + + /* video */ + .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2, + .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, + .video_b_frames = 2, + .video_gop_size = 12, + .video_gop_closure = 1, + .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, + .video_bitrate = 6000000, + .video_bitrate_peak = 8000000, + .video_temporal_decimation = 0, + .video_mute = 0, + .video_mute_yuv = 0x008080, /* YCbCr value for black */ + + /* encoding filters */ + .video_spatial_filter_mode = + V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, + .video_spatial_filter = 0, + .video_luma_spatial_filter_type = + V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR, + .video_chroma_spatial_filter_type = + V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, + .video_temporal_filter_mode = + V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, + .video_temporal_filter = 8, + .video_median_filter_type = + V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, + .video_luma_median_filter_top = 255, + .video_luma_median_filter_bottom = 0, + .video_chroma_median_filter_top = 255, + .video_chroma_median_filter_bottom = 0, +}; + /* Map the control ID to the correct field in the cx2341x_mpeg_params struct. Return -EINVAL if the ID is unknown, else return 0. */ @@ -430,13 +485,13 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1, - V4L2_MPEG_AUDIO_ENCODING_LAYER_2); + default_params.audio_encoding); case V4L2_CID_MPEG_AUDIO_L2_BITRATE: return v4l2_ctrl_query_fill(qctrl, V4L2_MPEG_AUDIO_L2_BITRATE_192K, V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, - V4L2_MPEG_AUDIO_L2_BITRATE_224K); + default_params.audio_l2_bitrate); case V4L2_CID_MPEG_AUDIO_L1_BITRATE: case V4L2_CID_MPEG_AUDIO_L3_BITRATE: @@ -479,17 +534,22 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return cx2341x_ctrl_query_fill(qctrl, V4L2_MPEG_STREAM_VBI_FMT_NONE, V4L2_MPEG_STREAM_VBI_FMT_NONE, 1, - V4L2_MPEG_STREAM_VBI_FMT_NONE); + default_params.stream_vbi_fmt); + + case V4L2_CID_MPEG_VIDEO_GOP_SIZE: + return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, + params->is_50hz ? 12 : 15); /* CX23415/6 specific */ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE: return cx2341x_ctrl_query_fill(qctrl, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1, - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL); + default_params.video_spatial_filter_mode); case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER: - cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0); + cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, + default_params.video_spatial_filter); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) @@ -501,7 +561,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF, V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1, - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF); + default_params.video_luma_spatial_filter_type); if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; @@ -512,7 +572,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF, V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1, - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF); + default_params.video_chroma_spatial_filter_type); if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO) qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE; @@ -522,10 +582,11 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return cx2341x_ctrl_query_fill(qctrl, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1, - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL); + default_params.video_temporal_filter_mode); case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER: - cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0); + cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, + default_params.video_temporal_filter); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO) @@ -536,10 +597,11 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return cx2341x_ctrl_query_fill(qctrl, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1, - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF); + default_params.video_median_filter_type); case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); + cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, + default_params.video_luma_median_filter_top); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) @@ -547,7 +609,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return 0; case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); + cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, + default_params.video_luma_median_filter_bottom); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) @@ -555,7 +618,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return 0; case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255); + cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, + default_params.video_chroma_median_filter_top); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) @@ -563,7 +627,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return 0; case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM: - cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0); + cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, + default_params.video_chroma_median_filter_bottom); qctrl->flags |= V4L2_CTRL_FLAG_SLIDER; if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF) @@ -571,7 +636,8 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params, return 0; case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS: - return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0); + return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, + default_params.stream_insert_nav_packets); default: return v4l2_ctrl_query_fill_std(qctrl); @@ -725,61 +791,6 @@ EXPORT_SYMBOL(cx2341x_ext_ctrls); void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p) { - static struct cx2341x_mpeg_params default_params = { - /* misc */ - .capabilities = 0, - .port = CX2341X_PORT_MEMORY, - .width = 720, - .height = 480, - .is_50hz = 0, - - /* stream */ - .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS, - .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE, - .stream_insert_nav_packets = 0, - - /* audio */ - .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000, - .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2, - .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K, - .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO, - .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4, - .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE, - .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE, - .audio_mute = 0, - - /* video */ - .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2, - .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3, - .video_b_frames = 2, - .video_gop_size = 12, - .video_gop_closure = 1, - .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - .video_bitrate = 6000000, - .video_bitrate_peak = 8000000, - .video_temporal_decimation = 0, - .video_mute = 0, - .video_mute_yuv = 0x008080, /* YCbCr value for black */ - - /* encoding filters */ - .video_spatial_filter_mode = - V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL, - .video_spatial_filter = 0, - .video_luma_spatial_filter_type = - V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR, - .video_chroma_spatial_filter_type = - V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, - .video_temporal_filter_mode = - V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL, - .video_temporal_filter = 8, - .video_median_filter_type = - V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF, - .video_luma_median_filter_top = 255, - .video_luma_median_filter_bottom = 0, - .video_chroma_median_filter_top = 255, - .video_chroma_median_filter_bottom = 0, - }; - *p = default_params; cx2341x_calc_audio_properties(p); } diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 120c498cb60c..e7bf4f4c1319 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1204,6 +1204,8 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, switch (qc->id) { case V4L2_CID_AUDIO_VOLUME: + return v4l2_ctrl_query_fill(qc, 0, 65535, + 65535 / 100, state->default_volume); case V4L2_CID_AUDIO_MUTE: case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_BASS: @@ -1411,6 +1413,8 @@ static int cx25840_probe(struct i2c_client *client, state->pvr150_workaround = 0; state->audmode = V4L2_TUNER_MODE_LANG1; state->unmute_volume = -1; + state->default_volume = 228 - cx25840_read(client, 0x8d4); + state->default_volume = ((state->default_volume / 2) + 23) << 9; state->vbi_line_offset = 8; state->id = id; state->rev = device_id; diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 27d8e52cd67e..72916ba975a8 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h @@ -44,6 +44,7 @@ struct cx25840_state { u32 audclk_freq; int audmode; int unmute_volume; /* -1 if not muted */ + int default_volume; int vbi_line_offset; u32 id; u32 rev; -- cgit v1.2.3 From 03b52c36a38eb72548b9408c497ffabd1519eabe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 12:33:08 -0300 Subject: V4L/DVB (8378): cx18: move cx18_av_vbi_setup to av-core.c and rename to cx18_av_std_setup Same issue as for cx25840: this function sets up the standard timings and has nothing to do with VBI setup. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-core.c | 143 ++++++++++++++++++++++++++++++- drivers/media/video/cx18/cx18-av-core.h | 2 +- drivers/media/video/cx18/cx18-av-vbi.c | 147 +------------------------------- 3 files changed, 147 insertions(+), 145 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c index 124014253569..3b0a2c450605 100644 --- a/drivers/media/video/cx18/cx18-av-core.c +++ b/drivers/media/video/cx18/cx18-av-core.c @@ -166,6 +166,147 @@ static void cx18_av_initialize(struct cx18 *cx) /* ----------------------------------------------------------------------- */ +void cx18_av_std_setup(struct cx18 *cx) +{ + struct cx18_av_state *state = &cx->av_state; + v4l2_std_id std = state->std; + int hblank, hactive, burst, vblank, vactive, sc; + int vblank656, src_decimation; + int luma_lpf, uv_lpf, comb; + u32 pll_int, pll_frac, pll_post; + + /* datasheet startup, step 8d */ + if (std & ~V4L2_STD_NTSC) + cx18_av_write(cx, 0x49f, 0x11); + else + cx18_av_write(cx, 0x49f, 0x14); + + if (std & V4L2_STD_625_50) { + hblank = 132; + hactive = 720; + burst = 93; + vblank = 36; + vactive = 580; + vblank656 = 40; + src_decimation = 0x21f; + + luma_lpf = 2; + if (std & V4L2_STD_PAL) { + uv_lpf = 1; + comb = 0x20; + sc = 688739; + } else if (std == V4L2_STD_PAL_Nc) { + uv_lpf = 1; + comb = 0x20; + sc = 556453; + } else { /* SECAM */ + uv_lpf = 0; + comb = 0; + sc = 672351; + } + } else { + hactive = 720; + hblank = 122; + vactive = 487; + luma_lpf = 1; + uv_lpf = 1; + vblank = 26; + vblank656 = 26; + + src_decimation = 0x21f; + if (std == V4L2_STD_PAL_60) { + burst = 0x5b; + luma_lpf = 2; + comb = 0x20; + sc = 688739; + } else if (std == V4L2_STD_PAL_M) { + burst = 0x61; + comb = 0x20; + sc = 555452; + } else { + burst = 0x5b; + comb = 0x66; + sc = 556063; + } + } + + /* DEBUG: Displays configured PLL frequency */ + pll_int = cx18_av_read(cx, 0x108); + pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff; + pll_post = cx18_av_read(cx, 0x109); + CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n", + pll_int, pll_frac, pll_post); + + if (pll_post) { + int fin, fsc; + int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac); + + pll >>= 25; + pll /= pll_post; + CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", + pll / 1000000, pll % 1000000); + CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n", + pll / 8000000, (pll / 8) % 1000000); + + fin = ((u64)src_decimation * pll) >> 12; + CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n", + fin / 1000000, fin % 1000000); + + fsc = (((u64)sc) * pll) >> 24L; + CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n", + fsc / 1000000, fsc % 1000000); + + CX18_DEBUG_INFO("hblank %i, hactive %i, " + "vblank %i , vactive %i, vblank656 %i, src_dec %i," + "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," + " sc 0x%06x\n", + hblank, hactive, vblank, vactive, vblank656, + src_decimation, burst, luma_lpf, uv_lpf, comb, sc); + } + + /* Sets horizontal blanking delay and active lines */ + cx18_av_write(cx, 0x470, hblank); + cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) | + (hactive << 4))); + cx18_av_write(cx, 0x472, hactive >> 4); + + /* Sets burst gate delay */ + cx18_av_write(cx, 0x473, burst); + + /* Sets vertical blanking delay and active duration */ + cx18_av_write(cx, 0x474, vblank); + cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) | + (vactive << 4))); + cx18_av_write(cx, 0x476, vactive >> 4); + cx18_av_write(cx, 0x477, vblank656); + + /* Sets src decimation rate */ + cx18_av_write(cx, 0x478, 0xff & src_decimation); + cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8)); + + /* Sets Luma and UV Low pass filters */ + cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); + + /* Enables comb filters */ + cx18_av_write(cx, 0x47b, comb); + + /* Sets SC Step*/ + cx18_av_write(cx, 0x47c, sc); + cx18_av_write(cx, 0x47d, 0xff & sc >> 8); + cx18_av_write(cx, 0x47e, 0xff & sc >> 16); + + /* Sets VBI parameters */ + if (std & V4L2_STD_625_50) { + cx18_av_write(cx, 0x47f, 0x01); + state->vbi_line_offset = 5; + } else { + cx18_av_write(cx, 0x47f, 0x00); + state->vbi_line_offset = 8; + } +} + +/* ----------------------------------------------------------------------- */ + static void input_change(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; @@ -323,7 +464,7 @@ static int set_v4lstd(struct cx18 *cx) } cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20); cx18_av_and_or(cx, 0x403, ~0x3, pal_m); - cx18_av_vbi_setup(cx); + cx18_av_std_setup(cx); input_change(cx); return 0; } diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h index 49e31bccc557..eb61fa1e0965 100644 --- a/drivers/media/video/cx18/cx18-av-core.h +++ b/drivers/media/video/cx18/cx18-av-core.h @@ -306,6 +306,7 @@ u32 cx18_av_read4(struct cx18 *cx, u16 addr); int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); +void cx18_av_std_setup(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-firmware.c */ @@ -318,7 +319,6 @@ void cx18_av_audio_set_path(struct cx18 *cx); /* ----------------------------------------------------------------------- */ /* cx18_av-vbi.c */ -void cx18_av_vbi_setup(struct cx18 *cx); int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg); #endif diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c index 0c92f123686f..02fdf57bb678 100644 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ b/drivers/media/video/cx18/cx18-av-vbi.c @@ -83,145 +83,6 @@ static int decode_vps(u8 *dst, u8 *p) return err & 0xf0; } -void cx18_av_vbi_setup(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - v4l2_std_id std = state->std; - int hblank, hactive, burst, vblank, vactive, sc; - int vblank656, src_decimation; - int luma_lpf, uv_lpf, comb; - u32 pll_int, pll_frac, pll_post; - - /* datasheet startup, step 8d */ - if (std & ~V4L2_STD_NTSC) - cx18_av_write(cx, 0x49f, 0x11); - else - cx18_av_write(cx, 0x49f, 0x14); - - if (std & V4L2_STD_625_50) { - hblank = 0x084; - hactive = 0x2d0; - burst = 0x5d; - vblank = 0x024; - vactive = 0x244; - vblank656 = 0x28; - src_decimation = 0x21f; - - luma_lpf = 2; - if (std & V4L2_STD_PAL) { - uv_lpf = 1; - comb = 0x20; - sc = 0x0a8263; - } else if (std == V4L2_STD_PAL_Nc) { - uv_lpf = 1; - comb = 0x20; - sc = 0x087da5; - } else { /* SECAM */ - uv_lpf = 0; - comb = 0; - sc = 0x0a425f; - } - } else { - hactive = 720; - hblank = 122; - vactive = 487; - luma_lpf = 1; - uv_lpf = 1; - vblank = 26; - vblank656 = 26; - - src_decimation = 0x21f; - if (std == V4L2_STD_PAL_60) { - burst = 0x5b; - luma_lpf = 2; - comb = 0x20; - sc = 0x0a8263; - } else if (std == V4L2_STD_PAL_M) { - burst = 0x61; - comb = 0x20; - sc = 555452; - } else { - burst = 0x5b; - comb = 0x66; - sc = 556063; - } - } - - /* DEBUG: Displays configured PLL frequency */ - pll_int = cx18_av_read(cx, 0x108); - pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff; - pll_post = cx18_av_read(cx, 0x109); - CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n", - pll_int, pll_frac, pll_post); - - if (pll_post) { - int fin, fsc; - int pll = 28636363L * ((((u64)pll_int) << 25) + pll_frac); - - pll >>= 25; - pll /= pll_post; - CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", - pll / 1000000, pll % 1000000); - CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n", - pll / 8000000, (pll / 8) % 1000000); - - fin = ((u64)src_decimation * pll) >> 12; - CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n", - fin / 1000000, fin % 1000000); - - fsc = (((u64)sc) * pll) >> 24L; - CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n", - fsc / 1000000, fsc % 1000000); - - CX18_DEBUG_INFO("hblank %i, hactive %i, " - "vblank %i , vactive %i, vblank656 %i, src_dec %i," - "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," - " sc 0x%06x\n", - hblank, hactive, vblank, vactive, vblank656, - src_decimation, burst, luma_lpf, uv_lpf, comb, sc); - } - - /* Sets horizontal blanking delay and active lines */ - cx18_av_write(cx, 0x470, hblank); - cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) | - (hactive << 4))); - cx18_av_write(cx, 0x472, hactive >> 4); - - /* Sets burst gate delay */ - cx18_av_write(cx, 0x473, burst); - - /* Sets vertical blanking delay and active duration */ - cx18_av_write(cx, 0x474, vblank); - cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) | - (vactive << 4))); - cx18_av_write(cx, 0x476, vactive >> 4); - cx18_av_write(cx, 0x477, vblank656); - - /* Sets src decimation rate */ - cx18_av_write(cx, 0x478, 0xff & src_decimation); - cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8)); - - /* Sets Luma and UV Low pass filters */ - cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); - - /* Enables comb filters */ - cx18_av_write(cx, 0x47b, comb); - - /* Sets SC Step*/ - cx18_av_write(cx, 0x47c, sc); - cx18_av_write(cx, 0x47d, 0xff & sc >> 8); - cx18_av_write(cx, 0x47e, 0xff & sc >> 16); - - /* Sets VBI parameters */ - if (std & V4L2_STD_625_50) { - cx18_av_write(cx, 0x47f, 0x01); - state->vbi_line_offset = 5; - } else { - cx18_av_write(cx, 0x47f, 0x00); - state->vbi_line_offset = 8; - } -} - int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) { struct cx18_av_state *state = &cx->av_state; @@ -287,8 +148,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) /* raw VBI */ memset(svbi, 0, sizeof(*svbi)); - /* Setup VBI */ - cx18_av_vbi_setup(cx); + /* Setup standard */ + cx18_av_std_setup(cx); /* VBI Offset */ cx18_av_write(cx, 0x47f, vbi_offset); @@ -299,8 +160,8 @@ int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) for (x = 0; x <= 23; x++) lcr[x] = 0x00; - /* Setup VBI */ - cx18_av_vbi_setup(cx); + /* Setup standard */ + cx18_av_std_setup(cx); /* Sliced VBI */ cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ -- cgit v1.2.3 From 5daed07401ed27bb2684e803f3f01e3a424ea282 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 17 Jul 2008 13:18:31 -0300 Subject: V4L/DVB (8379): saa7127: Make device detection optional The saa7127 driver supports all of SAA7126, SAA7127, SAA7128 and SAA1729 devices. Declare all these devices, so that board drivers can tell which device is present, instead of always relying on auto-detection (which needs to write to the chip, eek!). We still need the detection for ivtv, so a special device name "saa7127_auto" can be used when the caller doesn't know exactly which device is present. Signed-off-by: Jean Delvare Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-i2c.c | 2 +- drivers/media/video/saa7127.c | 42 ++++++++++++++++++++++++------------- 2 files changed, 28 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c index a1b37ff8669c..af154238fb9a 100644 --- a/drivers/media/video/ivtv/ivtv-i2c.c +++ b/drivers/media/video/ivtv/ivtv-i2c.c @@ -135,7 +135,7 @@ static const u8 hw_addrs[] = { static const char * const hw_devicenames[] = { "cx25840", "saa7115", - "saa7127", + "saa7127_auto", /* saa7127 or saa7129 */ "msp3400", "tuner", "wm8775", diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 7ba10e56c609..d0e83fe0ff51 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -666,7 +666,6 @@ static int saa7127_probe(struct i2c_client *client, { struct saa7127_state *state; struct v4l2_sliced_vbi_data vbi = { 0, 0, 0, 0 }; /* set to disabled */ - int read_result = 0; /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) @@ -710,20 +709,29 @@ static int saa7127_probe(struct i2c_client *client, saa7127_set_input_type(client, SAA7127_INPUT_TYPE_NORMAL); saa7127_set_video_enable(client, 1); - /* Detect if it's an saa7129 */ - read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); - saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); - if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { - v4l_info(client, "saa7129 found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); - saa7127_write_inittab(client, saa7129_init_config_extra); - state->ident = V4L2_IDENT_SAA7129; - } else { - v4l_info(client, "saa7127 found @ 0x%x (%s)\n", - client->addr << 1, client->adapter->name); - state->ident = V4L2_IDENT_SAA7127; + if (id->driver_data) { /* Chip type is already known */ + state->ident = id->driver_data; + } else { /* Needs detection */ + int read_result; + + /* Detect if it's an saa7129 */ + read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); + saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); + if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { + saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, + read_result); + state->ident = V4L2_IDENT_SAA7129; + strlcpy(client->name, "saa7129", I2C_NAME_SIZE); + } else { + state->ident = V4L2_IDENT_SAA7127; + strlcpy(client->name, "saa7127", I2C_NAME_SIZE); + } } + + v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, + client->addr << 1, client->adapter->name); + if (state->ident == V4L2_IDENT_SAA7129) + saa7127_write_inittab(client, saa7129_init_config_extra); return 0; } @@ -740,7 +748,11 @@ static int saa7127_remove(struct i2c_client *client) /* ----------------------------------------------------------------------- */ static struct i2c_device_id saa7127_id[] = { - { "saa7127", 0 }, + { "saa7127_auto", 0 }, /* auto-detection */ + { "saa7126", V4L2_IDENT_SAA7127 }, + { "saa7127", V4L2_IDENT_SAA7127 }, + { "saa7128", V4L2_IDENT_SAA7129 }, + { "saa7129", V4L2_IDENT_SAA7129 }, { } }; MODULE_DEVICE_TABLE(i2c, saa7127_id); -- cgit v1.2.3 From 9edd350f51a1e81f7f01308a99800cad7770e5cd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 13:22:51 -0300 Subject: V4L/DVB (8380): saa7115: use saa7115_auto instead of saa711x as the autodetect driver name. Having an _auto suffix is less ambiguous than a 'saa711x' identifier. It's also used like this in the saa7127 driver. Thanks to Jean Delvare for suggesting this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7115.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c index f0baca71dd3e..bcd1c8f6cf6b 100644 --- a/drivers/media/video/saa7115.c +++ b/drivers/media/video/saa7115.c @@ -1557,7 +1557,7 @@ static int saa7115_remove(struct i2c_client *client) } static const struct i2c_device_id saa7115_id[] = { - { "saa711x", 1 }, /* autodetect */ + { "saa7115_auto", 1 }, /* autodetect */ { "saa7111", 0 }, { "saa7113", 0 }, { "saa7114", 0 }, -- cgit v1.2.3 From e3bf20de33b016ac73424a5574177ed46c754be3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 13:29:49 -0300 Subject: V4L/DVB (8381): ov7670: fix compile warnings Signed-off-by: Hans Verkuil Acked-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ov7670.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 5e0d4e2ee510..ea032f5f2f41 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -833,7 +833,7 @@ static int ov7670_store_cmatrix(struct i2c_client *client, int matrix[CMATRIX_LEN]) { int i, ret; - unsigned char signbits; + unsigned char signbits = 0; /* * Weird crap seems to exist in the upper part of @@ -1009,7 +1009,7 @@ static unsigned char ov7670_abs_to_sm(unsigned char v) static int ov7670_t_brightness(struct i2c_client *client, int value) { - unsigned char com8, v; + unsigned char com8 = 0, v; int ret; ov7670_read(client, REG_COM8, &com8); @@ -1022,7 +1022,7 @@ static int ov7670_t_brightness(struct i2c_client *client, int value) static int ov7670_q_brightness(struct i2c_client *client, __s32 *value) { - unsigned char v; + unsigned char v = 0; int ret = ov7670_read(client, REG_BRIGHT, &v); *value = ov7670_sm_to_abs(v); @@ -1036,7 +1036,7 @@ static int ov7670_t_contrast(struct i2c_client *client, int value) static int ov7670_q_contrast(struct i2c_client *client, __s32 *value) { - unsigned char v; + unsigned char v = 0; int ret = ov7670_read(client, REG_CONTRAS, &v); *value = v; @@ -1046,7 +1046,7 @@ static int ov7670_q_contrast(struct i2c_client *client, __s32 *value) static int ov7670_q_hflip(struct i2c_client *client, __s32 *value) { int ret; - unsigned char v; + unsigned char v = 0; ret = ov7670_read(client, REG_MVFP, &v); *value = (v & MVFP_MIRROR) == MVFP_MIRROR; @@ -1056,7 +1056,7 @@ static int ov7670_q_hflip(struct i2c_client *client, __s32 *value) static int ov7670_t_hflip(struct i2c_client *client, int value) { - unsigned char v; + unsigned char v = 0; int ret; ret = ov7670_read(client, REG_MVFP, &v); @@ -1074,7 +1074,7 @@ static int ov7670_t_hflip(struct i2c_client *client, int value) static int ov7670_q_vflip(struct i2c_client *client, __s32 *value) { int ret; - unsigned char v; + unsigned char v = 0; ret = ov7670_read(client, REG_MVFP, &v); *value = (v & MVFP_FLIP) == MVFP_FLIP; @@ -1084,7 +1084,7 @@ static int ov7670_q_vflip(struct i2c_client *client, __s32 *value) static int ov7670_t_vflip(struct i2c_client *client, int value) { - unsigned char v; + unsigned char v = 0; int ret; ret = ov7670_read(client, REG_MVFP, &v); -- cgit v1.2.3 From 2bc93aa304f10bf94c377a487b09df75eaf88ab6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 16:45:00 -0300 Subject: V4L/DVB (8387): Some cosmetic changes Those changes, together with some proper patches, will allow out-of-tree compilation for for kernels < 2.6.19 Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 22 ++++++++++------------ include/media/v4l2-dev.h | 2 +- 2 files changed, 11 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index d54ca6c802db..c24d91897099 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -392,6 +392,12 @@ static ssize_t show_name(struct device *cd, return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); } +static struct device_attribute video_device_attrs[] = { + __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(index, S_IRUGO, show_index, NULL), + __ATTR_NULL +}; + struct video_device *video_device_alloc(void) { struct video_device *vfd; @@ -420,12 +426,6 @@ static void video_release(struct device *cd) vfd->release(vfd); } -static struct device_attribute video_device_attrs[] = { - __ATTR(name, S_IRUGO, show_name, NULL), - __ATTR(index, S_IRUGO, show_index, NULL), - __ATTR_NULL -}; - static struct class video_class = { .name = VIDEO_NAME, .dev_attrs = video_device_attrs, @@ -2173,8 +2173,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, ret = get_index(vfd, index); if (ret < 0) { - printk(KERN_ERR "%s: get_index failed\n", - __func__); + printk(KERN_ERR "%s: get_index failed\n", __func__); goto fail_minor; } @@ -2185,15 +2184,14 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, /* sysfs class */ memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); - if (vfd->dev) - vfd->class_dev.parent = vfd->dev; vfd->class_dev.class = &video_class; vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); + if (vfd->dev) + vfd->class_dev.parent = vfd->dev; sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); ret = device_register(&vfd->class_dev); if (ret < 0) { - printk(KERN_ERR "%s: device_register failed\n", - __func__); + printk(KERN_ERR "%s: device_register failed\n", __func__); goto fail_minor; } diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 3c934142f7f9..33f379b1ecfe 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -375,7 +375,7 @@ video_device_create_file(struct video_device *vfd, { int ret = device_create_file(&vfd->class_dev, attr); if (ret < 0) - printk(KERN_WARNING "%s error: %d\n", __FUNCTION__, ret); + printk(KERN_WARNING "%s error: %d\n", __func__, ret); return ret; } static inline void -- cgit v1.2.3 From 8373a3e512c8ea8e93981d42b0d1efb252be17fa Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 24 Jun 2008 22:58:25 -0300 Subject: V4L/DVB (8389): videodev: simplify get_index() Use Hans Verkuil's suggested method of implementing get_index which doesn't depend on class_for_each_device and instead uses the video_device array. This simplifies the code and reduces its memory footprint. Signed-off-by: Brandon Philips Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 65 +++++++++++------------------------------- 1 file changed, 17 insertions(+), 48 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index c24d91897099..bf12b5f850e2 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -2011,25 +2011,8 @@ out: } EXPORT_SYMBOL(video_ioctl2); -struct index_info { - struct device *dev; - unsigned int used[VIDEO_NUM_DEVICES]; -}; - -static int __fill_index_info(struct device *cd, void *data) -{ - struct index_info *info = data; - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); - - if (info->dev == vfd->dev) - info->used[vfd->index] = 1; - - return 0; -} - /** - * assign_index - assign stream number based on parent device + * get_index - assign stream number based on parent device * @vdev: video_device to assign index number to, vdev->dev should be assigned * @num: -1 if auto assign, requested number otherwise * @@ -2039,44 +2022,30 @@ static int __fill_index_info(struct device *cd, void *data) */ static int get_index(struct video_device *vdev, int num) { - struct index_info *info; + u32 used = 0; int i; - int ret = 0; - if (num >= VIDEO_NUM_DEVICES) + if (num >= 32) { + printk(KERN_ERR "videodev: %s num is too large\n", __func__); return -EINVAL; - - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->dev = vdev->dev; - - ret = class_for_each_device(&video_class, info, - __fill_index_info); - - if (ret < 0) - goto out; - - if (num >= 0) { - if (!info->used[num]) - ret = num; - else - ret = -ENFILE; - - goto out; } for (i = 0; i < VIDEO_NUM_DEVICES; i++) { - if (info->used[i]) - continue; - ret = i; - goto out; + if (video_device[i] != NULL && + video_device[i] != vdev && + video_device[i]->dev == vdev->dev) { + used |= 1 << video_device[i]->index; + } } -out: - kfree(info); - return ret; + if (num >= 0) { + if (used & (1 << num)) + return -ENFILE; + return num; + } + + i = ffz(used); + return i >= 32 ? -ENFILE : i; } static const struct file_operations video_fops; -- cgit v1.2.3 From c3fb62bf927cee771c3bcd5053e393e7df518f28 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 17 Jul 2008 17:48:38 -0300 Subject: V4L/DVB (8390): videodev: add comment and remove magic number. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videodev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index bf12b5f850e2..aca36dec6746 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -2023,9 +2023,13 @@ EXPORT_SYMBOL(video_ioctl2); static int get_index(struct video_device *vdev, int num) { u32 used = 0; + const unsigned max_index = sizeof(used) * 8 - 1; int i; - if (num >= 32) { + /* Currently a single v4l driver instance cannot create more than + 32 devices. + Increase to u64 or an array of u32 if more are needed. */ + if (num > max_index) { printk(KERN_ERR "videodev: %s num is too large\n", __func__); return -EINVAL; } @@ -2045,7 +2049,7 @@ static int get_index(struct video_device *vdev, int num) } i = ffz(used); - return i >= 32 ? -ENFILE : i; + return i > max_index ? -ENFILE : i; } static const struct file_operations video_fops; -- cgit v1.2.3 From d4216488c0ccf7b659411023903bac7207f0dfb7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:25:53 -0300 Subject: V4L/DVB (8392): media/Kconfig: Convert V4L1_COMPAT select into "depends on" Signed-off-by: Mauro Carvalho Chehab --- drivers/media/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 7a7803b5d497..93ea201f426c 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig @@ -38,7 +38,6 @@ config VIDEO_ALLOW_V4L1 bool "Enable Video For Linux API 1 (DEPRECATED)" depends on VIDEO_DEV && VIDEO_V4L2_COMMON default VIDEO_DEV && VIDEO_V4L2_COMMON - select VIDEO_V4L1_COMPAT ---help--- Enables drivers based on the legacy V4L1 API. @@ -49,9 +48,9 @@ config VIDEO_ALLOW_V4L1 If you are unsure as to whether this is required, answer Y. config VIDEO_V4L1_COMPAT - bool "Enable Video For Linux API 1 compatible Layer" + bool "Enable Video For Linux API 1 compatible Layer" if !VIDEO_ALLOW_V4L1 depends on VIDEO_DEV - default VIDEO_DEV + default y ---help--- Enables a compatibility API used by most V4L2 devices to allow its usage with legacy applications that supports only V4L1 api. -- cgit v1.2.3 From 432aa3b64d08f1453e2742d20c5fe6946ca22549 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:27:50 -0300 Subject: V4L/DVB (8393): media/video: Fix depencencies for VIDEOBUF VIDEOBUF_DVB depends on VIDEOBUF_CORE, not on VIDEOBUF_DMA_SG Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 1 - drivers/media/video/cx23885/Kconfig | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 1199a1a2e6f5..424cef1eca3b 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -32,7 +32,6 @@ config VIDEOBUF_DMA_CONTIG config VIDEOBUF_DVB tristate select VIDEOBUF_GEN - select VIDEOBUF_DMA_SG config VIDEO_BTCX tristate diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 04e9640c2ca4..5cfb46bbdaa9 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -9,6 +9,7 @@ config VIDEO_CX23885 select VIDEO_TVEEPROM select VIDEO_IR select VIDEOBUF_DVB + select VIDEOBUF_DMA_SG select VIDEO_CX25840 select VIDEO_CX2341X select DVB_DIB7000P if !DVB_FE_CUSTOMISE -- cgit v1.2.3 From 4db16db4f60ce063435bd08b71c82aad1254cd95 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:28:56 -0300 Subject: V4L/DVB (8394): ir-common: CodingStyle fix: move EXPORT_SYMBOL_GPL to their proper places Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/ir-functions.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 03b1165eacbc..16792a68a449 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c @@ -77,6 +77,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, if (repeat) set_bit(EV_REP, dev->evbit); } +EXPORT_SYMBOL_GPL(ir_input_init); void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) { @@ -85,6 +86,7 @@ void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) ir_input_key_event(dev,ir); } } +EXPORT_SYMBOL_GPL(ir_input_nokey); void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, u32 ir_key, u32 ir_raw) @@ -103,6 +105,7 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, ir_input_key_event(dev,ir); } } +EXPORT_SYMBOL_GPL(ir_input_keydown); /* -------------------------------------------------------------------------- */ /* extract mask bits out of data and pack them into the result */ @@ -121,6 +124,7 @@ u32 ir_extract_bits(u32 data, u32 mask) return value; } +EXPORT_SYMBOL_GPL(ir_extract_bits); static int inline getbit(u32 *samples, int bit) { @@ -145,6 +149,7 @@ int ir_dump_samples(u32 *samples, int count) printk("\n"); return 0; } +EXPORT_SYMBOL_GPL(ir_dump_samples); /* decode raw samples, pulse distance coding used by NEC remotes */ int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) @@ -211,6 +216,7 @@ int ir_decode_pulsedistance(u32 *samples, int count, int low, int high) return value; } +EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); /* decode raw samples, biphase coding, used by rc5 for example */ int ir_decode_biphase(u32 *samples, int count, int low, int high) @@ -252,6 +258,7 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high) } return value; } +EXPORT_SYMBOL_GPL(ir_decode_biphase); /* RC5 decoding stuff, moved from bttv-input.c to share it with * saa7134 */ @@ -352,6 +359,7 @@ void ir_rc5_timer_end(unsigned long data) } } } +EXPORT_SYMBOL_GPL(ir_rc5_timer_end); void ir_rc5_timer_keyup(unsigned long data) { @@ -360,21 +368,4 @@ void ir_rc5_timer_keyup(unsigned long data) dprintk(1, "ir-common: key released\n"); ir_input_nokey(ir->dev, &ir->ir); } - -EXPORT_SYMBOL_GPL(ir_input_init); -EXPORT_SYMBOL_GPL(ir_input_nokey); -EXPORT_SYMBOL_GPL(ir_input_keydown); - -EXPORT_SYMBOL_GPL(ir_extract_bits); -EXPORT_SYMBOL_GPL(ir_dump_samples); -EXPORT_SYMBOL_GPL(ir_decode_biphase); -EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); - -EXPORT_SYMBOL_GPL(ir_rc5_timer_end); EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From 1c22dad8ab86caef7a1f01cf3e9bb446a448aac5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:31:29 -0300 Subject: V4L/DVB (8395): saa7134: Fix Kbuild dependency of ir-kbd-i2c Currently, saa7134 is dependent of ir-kbd-i2c, since it uses a symbol that is defined there. However, as this symbol is used only on saa7134, there's no sense on keeping it defined there (or on ir-commons). So, let's move it to saa7134 and remove one symbol for being exported. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ir-kbd-i2c.c | 82 ----------------------------- drivers/media/video/saa7134/saa7134-input.c | 78 +++++++++++++++++++++++++++ include/media/ir-kbd-i2c.h | 3 -- 3 files changed, 78 insertions(+), 85 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 7b65f5e537f8..a30254bed311 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -194,88 +194,6 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } -/* Common (grey or coloured) pinnacle PCTV remote handling - * - */ -static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, - int parity_offset, int marker, int code_modulo) -{ - unsigned char b[4]; - unsigned int start = 0,parity = 0,code = 0; - - /* poll IR chip */ - if (4 != i2c_master_recv(&ir->c,b,4)) { - dprintk(2,"read error\n"); - return -EIO; - } - - for (start = 0; start < ARRAY_SIZE(b); start++) { - if (b[start] == marker) { - code=b[(start+parity_offset+1)%4]; - parity=b[(start+parity_offset)%4]; - } - } - - /* Empty Request */ - if (parity==0) - return 0; - - /* Repeating... */ - if (ir->old == parity) - return 0; - - ir->old = parity; - - /* drop special codes when a key is held down a long time for the grey controller - In this case, the second bit of the code is asserted */ - if (marker == 0xfe && (code & 0x40)) - return 0; - - code %= code_modulo; - - *ir_raw = code; - *ir_key = code; - - dprintk(1,"Pinnacle PCTV key %02x\n", code); - - return 1; -} - -/* The grey pinnacle PCTV remote - * - * There are one issue with this remote: - * - I2c packet does not change when the same key is pressed quickly. The workaround - * is to hold down each key for about half a second, so that another code is generated - * in the i2c packet, and the function can distinguish key presses. - * - * Sylvain Pasche - */ -int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - - return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); -} - -EXPORT_SYMBOL_GPL(get_key_pinnacle_grey); - - -/* The new pinnacle PCTV remote (with the colored buttons) - * - * Ricardo Cerqueira - */ -int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) -{ - /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE - * - * this is the only value that results in 42 unique - * codes < 128 - */ - - return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); -} - -EXPORT_SYMBOL_GPL(get_key_pinnacle_color); - /* ----------------------------------------------------------------------- */ static void ir_key_poll(struct IR_i2c *ir) diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index e6217fe13339..ad08d13dffdd 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -198,6 +198,84 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +/* Common (grey or coloured) pinnacle PCTV remote handling + * + */ +static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw, + int parity_offset, int marker, int code_modulo) +{ + unsigned char b[4]; + unsigned int start = 0,parity = 0,code = 0; + + /* poll IR chip */ + if (4 != i2c_master_recv(&ir->c, b, 4)) { + i2cdprintk("read error\n"); + return -EIO; + } + + for (start = 0; start < ARRAY_SIZE(b); start++) { + if (b[start] == marker) { + code=b[(start+parity_offset + 1) % 4]; + parity=b[(start+parity_offset) % 4]; + } + } + + /* Empty Request */ + if (parity == 0) + return 0; + + /* Repeating... */ + if (ir->old == parity) + return 0; + + ir->old = parity; + + /* drop special codes when a key is held down a long time for the grey controller + In this case, the second bit of the code is asserted */ + if (marker == 0xfe && (code & 0x40)) + return 0; + + code %= code_modulo; + + *ir_raw = code; + *ir_key = code; + + i2cdprintk("Pinnacle PCTV key %02x\n", code); + + return 1; +} + +/* The grey pinnacle PCTV remote + * + * There are one issue with this remote: + * - I2c packet does not change when the same key is pressed quickly. The workaround + * is to hold down each key for about half a second, so that another code is generated + * in the i2c packet, and the function can distinguish key presses. + * + * Sylvain Pasche + */ +static int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + + return get_key_pinnacle(ir, ir_key, ir_raw, 1, 0xfe, 0xff); +} + + +/* The new pinnacle PCTV remote (with the colored buttons) + * + * Ricardo Cerqueira + */ +static int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + /* code_modulo parameter (0x88) is used to reduce code value to fit inside IR_KEYTAB_SIZE + * + * this is the only value that results in 42 unique + * codes < 128 + */ + + return get_key_pinnacle(ir, ir_key, ir_raw, 2, 0x80, 0x88); +} + void saa7134_input_irq(struct saa7134_dev *dev) { struct card_ir *ir = dev->remote; diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h index a455f7ce5ee8..00fa57eb9fde 100644 --- a/include/media/ir-kbd-i2c.h +++ b/include/media/ir-kbd-i2c.h @@ -19,7 +19,4 @@ struct IR_i2c { char phys[32]; int (*get_key)(struct IR_i2c*, u32*, u32*); }; - -int get_key_pinnacle_grey(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); -int get_key_pinnacle_color(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); #endif -- cgit v1.2.3 From 367394ac5cce83d40e605b5c75ee27dbe3d42d92 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:34:27 -0300 Subject: V4L/DVB (8396): video: Fix Kbuild dependency for VIDEO_IR_I2C Instead of letting VIDEO_IR_I2C to be selected by VIDEO_IR, if I2C, convert it into a symbol that depends on both VIDEO_IR and I2C. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 424cef1eca3b..f268dbeeb700 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -36,13 +36,9 @@ config VIDEOBUF_DVB config VIDEO_BTCX tristate -config VIDEO_IR_I2C - tristate - config VIDEO_IR tristate depends on INPUT - select VIDEO_IR_I2C if I2C config VIDEO_TVEEPROM tristate @@ -88,6 +84,19 @@ config VIDEO_HELPER_CHIPS_AUTO In doubt, say Y. +config VIDEO_IR_I2C + tristate "I2C module for IR" if !VIDEO_HELPER_CHIPS_AUTO + depends on I2C && VIDEO_IR + default y + ---help--- + Most boards have an IR chip directly connected via GPIO. However, + some video boards have the IR connected via I2C bus. + + If your board doesn't have an I2C IR chip, you may disable this + option. + + In doubt, say Y. + # # Encoder / Decoder module configuration # -- cgit v1.2.3 From af8b303e96ed5a6882419c8e632df166bde85d7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 17 Jul 2008 22:36:08 -0300 Subject: V4L/DVB (8397): video: convert select VIDEO_ZORAN_ZR36060 into depends on Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f268dbeeb700..f606d2951fde 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -613,9 +613,6 @@ config VIDEO_STRADIS driver for PCI. There is a product page at . -config VIDEO_ZORAN_ZR36060 - tristate - config VIDEO_ZORAN tristate "Zoran ZR36057/36067 Video For Linux" depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS @@ -629,61 +626,64 @@ config VIDEO_ZORAN To compile this driver as a module, choose M here: the module will be called zr36067. +config VIDEO_ZORAN_DC30 + tristate "Pinnacle/Miro DC30(+) support" + depends on VIDEO_ZORAN + select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO + select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO + help + Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback + card. This also supports really old DC10 cards based on the + zr36050 MJPEG codec and zr36016 VFE. + +config VIDEO_ZORAN_ZR36060 + tristate "Zoran ZR36060" + depends on VIDEO_ZORAN + help + Say Y to support Zoran boards based on 36060 chips. + This includes Iomega Bus, Pinnacle DC10, Linux media Labs 33 + and 33 R10 and AverMedia 6 boards. + config VIDEO_ZORAN_BUZ tristate "Iomega Buz support" - depends on VIDEO_ZORAN + depends on VIDEO_ZORAN_ZR36060 select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ZORAN_ZR36060 help Support for the Iomega Buz MJPEG capture/playback card. config VIDEO_ZORAN_DC10 tristate "Pinnacle/Miro DC10(+) support" - depends on VIDEO_ZORAN - select VIDEO_SAA7110 + depends on VIDEO_ZORAN_ZR36060 + select VIDEO_SAA7110 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ZORAN_ZR36060 help Support for the Pinnacle/Miro DC10(+) MJPEG capture/playback card. -config VIDEO_ZORAN_DC30 - tristate "Pinnacle/Miro DC30(+) support" - depends on VIDEO_ZORAN - select VIDEO_ADV7175 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_VPX3220 if VIDEO_HELPER_CHIPS_AUTO - help - Support for the Pinnacle/Miro DC30(+) MJPEG capture/playback - card. This also supports really old DC10 cards based on the - zr36050 MJPEG codec and zr36016 VFE. - config VIDEO_ZORAN_LML33 tristate "Linux Media Labs LML33 support" - depends on VIDEO_ZORAN + depends on VIDEO_ZORAN_ZR36060 select VIDEO_BT819 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ZORAN_ZR36060 help Support for the Linux Media Labs LML33 MJPEG capture/playback card. config VIDEO_ZORAN_LML33R10 tristate "Linux Media Labs LML33R10 support" - depends on VIDEO_ZORAN + depends on VIDEO_ZORAN_ZR36060 select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ZORAN_ZR36060 help support for the Linux Media Labs LML33R10 MJPEG capture/playback card. config VIDEO_ZORAN_AVS6EYES tristate "AverMedia 6 Eyes support (EXPERIMENTAL)" - depends on VIDEO_ZORAN && EXPERIMENTAL && VIDEO_V4L1 + depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1 select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO - select VIDEO_ZORAN_ZR36060 help Support for the AverMedia 6 Eyes video surveillance card. -- cgit v1.2.3 From 86751b016ff4eb4741b602933e5e6d74ac6cc377 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 Jul 2008 01:35:14 -0300 Subject: V4L/DVB (8410): sh_mobile_ceu_camera: fix 64-bit compiler warnings Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 6560ff496989..012005e1a77b 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -142,7 +142,7 @@ static void free_buffer(struct videobuf_queue *vq, { struct soc_camera_device *icd = vq->priv_data; - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, &buf->vb, buf->vb.baddr, buf->vb.bsize); if (in_interrupt()) @@ -179,7 +179,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, vb, vb->baddr, vb->bsize); /* Added list head initialization on alloc */ @@ -232,7 +232,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq, struct sh_mobile_ceu_dev *pcdev = ici->priv; unsigned long flags; - dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, vb, vb->baddr, vb->bsize); vb->state = VIDEOBUF_ACTIVE; -- cgit v1.2.3 From f19ad390146e7745cbc529f3bef8469cf21f3a6b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 Jul 2008 02:02:50 -0300 Subject: V4L/DVB (8411): videobuf-dma-contig.c: fix 64-bit build for pre-2.6.24 kernels Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-dma-contig.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 2475535cbe7f..03f20acb668c 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -16,6 +16,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From fac3639d886ae577d74e2da16e6a448620d432c9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 Jul 2008 10:07:10 -0300 Subject: V4L/DVB (8414): videodev/cx18: fix get_index bug and error-handling lock-ups Fix a bug in get_index that was introduced earlier. Also fix two error handling lock-ups in videodev and cx18 that where found thanks to that bug. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-streams.c | 4 +++- drivers/media/video/videodev.c | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index f3d20509a8bd..1728b1d832a9 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -311,8 +311,10 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) /* Teardown all streams */ for (type = 0; type < CX18_MAX_STREAMS; type++) { - if (cx->streams[type].dvb.enabled) + if (cx->streams[type].dvb.enabled) { cx18_dvb_unregister(&cx->streams[type]); + cx->streams[type].dvb.enabled = false; + } vdev = cx->streams[type].v4l2dev; diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index aca36dec6746..6616e6570557 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -2023,7 +2023,7 @@ EXPORT_SYMBOL(video_ioctl2); static int get_index(struct video_device *vdev, int num) { u32 used = 0; - const unsigned max_index = sizeof(used) * 8 - 1; + const int max_index = sizeof(used) * 8 - 1; int i; /* Currently a single v4l driver instance cannot create more than @@ -2145,14 +2145,15 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, vfd->minor=i; ret = get_index(vfd, index); + vfd->index = ret; + + mutex_unlock(&videodev_lock); + if (ret < 0) { printk(KERN_ERR "%s: get_index failed\n", __func__); goto fail_minor; } - vfd->index = ret; - - mutex_unlock(&videodev_lock); mutex_init(&vfd->lock); /* sysfs class */ -- cgit v1.2.3 From d20b27478d6ccf7c4c8de4f09db2bdbaec82a6c0 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 18 Jul 2008 05:52:04 -0300 Subject: V4L/DVB (8415): gspca: Infinite loop in i2c_w() of etoms. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/etoms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 5bb8dc1adbb7..8ab4ea7201a9 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -292,7 +292,7 @@ static void reg_w(struct gspca_dev *gspca_dev, static int i2c_w(struct gspca_dev *gspca_dev, __u8 reg, const __u8 *buffer, - __u16 len, __u8 mode) + int len, __u8 mode) { /* buffer should be [D0..D7] */ __u8 ptchcount; -- cgit v1.2.3 From e282959ef3ebae0d72ac0b24242c376fa34da585 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 21 May 2008 12:52:33 -0700 Subject: device create: dvb: convert device_create to device_create_drvdata device_create() is race-prone, so use the race-free device_create_drvdata() instead as device_create() is going away. Signed-off-by: Greg Kroah-Hartman --- drivers/media/dvb/dvb-core/dvbdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index e208a60c048a..e7132770a3bf 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -233,9 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, mutex_unlock(&dvbdev_register_lock); - clsdev = device_create(dvb_class, adap->device, + clsdev = device_create_drvdata(dvb_class, adap->device, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), - "dvb%d.%s%d", adap->num, dnames[type], id); + NULL, "dvb%d.%s%d", adap->num, dnames[type], id); if (IS_ERR(clsdev)) { printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); -- cgit v1.2.3 From 89f9257c06cb635ef140bd1acf21fb067ed4ed34 Mon Sep 17 00:00:00 2001 From: Henk Vergonet Date: Thu, 9 Aug 2007 11:02:30 -0300 Subject: V4L/DVB (7736): This patch adds support for the Micronas DRX3975D/DRX3977D DVB-T demodulator The module needs an external firmware file. The module has been tested on a Pinnacle 330e, but with modules that are currently not part of the linux-dvb tree. So consider this highly experimental, don't use this code unless you are an experienced kernel developer. create mode 100644 drivers/media/dvb/frontends/drx397xD.c create mode 100644 drivers/media/dvb/frontends/drx397xD.h create mode 100644 drivers/media/dvb/frontends/drx397xD_fw.h Signed-off-by: Henk Vergonet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/Kconfig | 14 + drivers/media/dvb/frontends/Makefile | 1 + drivers/media/dvb/frontends/drx397xD.c | 1505 +++++++++++++++++++++++++++++ drivers/media/dvb/frontends/drx397xD.h | 130 +++ drivers/media/dvb/frontends/drx397xD_fw.h | 40 + 5 files changed, 1690 insertions(+) create mode 100644 drivers/media/dvb/frontends/drx397xD.c create mode 100644 drivers/media/dvb/frontends/drx397xD.h create mode 100644 drivers/media/dvb/frontends/drx397xD_fw.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index c20553c4da1f..fa7f0c563770 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -135,6 +135,20 @@ config DVB_CX22702 help A DVB-T tuner module. Say Y when you want to support this frontend. +config DVB_DRX397XD + tristate "Micronas DRX3975D/DRX3977D based" + depends on DVB_CORE && I2C && HOTPLUG + default m if DVB_FE_CUSTOMISE + select FW_LOADER + help + A DVB-T tuner module. Say Y when you want to support this frontend. + + TODO: + This driver needs external firmware. Please use the command + "/Documentation/dvb/get_dvb_firmware drx397xD" to + download/extract them, and then copy them to /usr/lib/hotplug/firmware + or /lib/firmware (depending on configuration of firmware hotplug). + config DVB_L64781 tristate "LSI L64781" depends on DVB_CORE && I2C diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index a89dc0fc4c6f..028da55611c0 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_DVB_NXT6000) += nxt6000.o obj-$(CONFIG_DVB_MT352) += mt352.o obj-$(CONFIG_DVB_ZL10353) += zl10353.o obj-$(CONFIG_DVB_CX22702) += cx22702.o +obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o obj-$(CONFIG_DVB_TDA10021) += tda10021.o obj-$(CONFIG_DVB_TDA10023) += tda10023.o obj-$(CONFIG_DVB_STV0297) += stv0297.o diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c new file mode 100644 index 000000000000..b0ff77ffc88b --- /dev/null +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -0,0 +1,1505 @@ +/* + * Driver for Micronas drx397xD demodulator + * + * Copyright (C) 2007 Henk Vergonet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see . + */ + +#define DEBUG /* uncomment if you want debugging output */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "drx397xD.h" + +static const char mod_name[] = "drx397xD"; + +#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */ + +#define F_SET_0D0h 1 +#define F_SET_0D4h 2 + +typedef enum fw_ix { +#define _FW_ENTRY(a, b) b +#include "drx397xD_fw.h" +} fw_ix_t; + +/* chip specifics */ +struct drx397xD_state { + struct i2c_adapter *i2c; + struct dvb_frontend frontend; + struct drx397xD_config config; + fw_ix_t chip_rev; + int flags; + u32 bandwidth_parm; /* internal bandwidth conversions */ + u32 f_osc; /* w90: actual osc frequency [Hz] */ +}; + +/******************************************************************************* + * Firmware + ******************************************************************************/ + +static const char *blob_name[] = { +#define _BLOB_ENTRY(a, b) a +#include "drx397xD_fw.h" +}; + +typedef enum blob_ix { +#define _BLOB_ENTRY(a, b) b +#include "drx397xD_fw.h" +} blob_ix_t; + +static struct { + const char *name; + const struct firmware *file; + rwlock_t lock; + int refcnt; + u8 *data[ARRAY_SIZE(blob_name)]; +} fw[] = { +#define _FW_ENTRY(a, b) { \ + .name = a, \ + .file = 0, \ + .lock = RW_LOCK_UNLOCKED, \ + .refcnt = 0, \ + .data = { } } +#include "drx397xD_fw.h" +}; + +/* use only with writer lock aquired */ +static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) +{ + memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); + if (fw[ix].file) + release_firmware(fw[ix].file); +} + +static void drx_release_fw(struct drx397xD_state *s) +{ + fw_ix_t ix = s->chip_rev; + + pr_debug("%s\n", __FUNCTION__); + + write_lock(&fw[ix].lock); + if (fw[ix].refcnt) { + fw[ix].refcnt--; + if (fw[ix].refcnt == 0) + _drx_release_fw(s, ix); + } + write_unlock(&fw[ix].lock); +} + +static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) +{ + u8 *data; + size_t size, len; + int i = 0, j, rc = -EINVAL; + + pr_debug("%s\n", __FUNCTION__); + + if (ix < 0 || ix >= ARRAY_SIZE(fw)) + return -EINVAL; + s->chip_rev = ix; + + write_lock(&fw[ix].lock); + if (fw[ix].file) { + rc = 0; + goto exit_ok; + } + memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); + + if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { + printk(KERN_ERR "%s: Firmware \"%s\" not available\n", + mod_name, fw[ix].name); + rc = -ENOENT; + goto exit_err; + } + + if (!fw[ix].file->data || fw[ix].file->size < 10) + goto exit_corrupt; + + data = fw[ix].file->data; + size = fw[ix].file->size; + + if (data[i++] != 2) /* check firmware version */ + goto exit_corrupt; + + do { + switch (data[i++]) { + case 0x00: /* bytecode */ + if (i >= size) + break; + i += data[i]; + case 0x01: /* reset */ + case 0x02: /* sleep */ + i++; + break; + case 0xfe: /* name */ + len = strnlen(&data[i], size - i); + if (i + len + 1 >= size) + goto exit_corrupt; + if (data[i + len + 1] != 0) + goto exit_corrupt; + for (j = 0; j < ARRAY_SIZE(blob_name); j++) { + if (strcmp(blob_name[j], &data[i]) == 0) { + fw[ix].data[j] = &data[i + len + 1]; + pr_debug("Loading %s\n", blob_name[j]); + } + } + i += len + 1; + break; + case 0xff: /* file terminator */ + if (i == size) { + rc = 0; + goto exit_ok; + } + default: + goto exit_corrupt; + } + } while (i < size); + exit_corrupt: + printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); + exit_err: + _drx_release_fw(s, ix); + fw[ix].refcnt--; + exit_ok: + fw[ix].refcnt++; + write_unlock(&fw[ix].lock); + return rc; +} + +/******************************************************************************* + * i2c bus IO + ******************************************************************************/ + +static int write_fw(struct drx397xD_state *s, blob_ix_t ix) +{ + struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 }; + u8 *data; + int len, rc = 0, i = 0; + + if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { + pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__); + return -EINVAL; + } + pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]); + + read_lock(&fw[s->chip_rev].lock); + data = fw[s->chip_rev].data[ix]; + if (!data) { + rc = -EINVAL; + goto exit_rc; + } + + for (;;) { + switch (data[i++]) { + case 0: /* bytecode */ + len = data[i++]; + msg.len = len; + msg.buf = &data[i]; + if (i2c_transfer(s->i2c, &msg, 1) != 1) { + rc = -EIO; + goto exit_rc; + } + i += len; + break; + case 1: /* reset */ + case 2: /* sleep */ + i++; + break; + default: + goto exit_rc; + } + } + exit_rc: + read_unlock(&fw[s->chip_rev].lock); + return 0; +} + +/* Function is not endian safe, use the RD16 wrapper below */ +static int _read16(struct drx397xD_state *s, u32 i2c_adr) +{ + int rc; + u8 a[4]; + u16 v; + struct i2c_msg msg[2] = { + { + .addr = s->config.demod_address, + .flags = 0, + .buf = a, + .len = sizeof(a) + } + , { + .addr = s->config.demod_address, + .flags = I2C_M_RD, + .buf = (u8 *) & v, + .len = sizeof(v) + } + }; + + *(u32 *) a = i2c_adr; + + rc = i2c_transfer(s->i2c, msg, 2); + if (rc != 2) + return -EIO; + + return le16_to_cpu(v); +} + +/* Function is not endian safe, use the WR16.. wrappers below */ +static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) +{ + u8 a[6]; + int rc; + struct i2c_msg msg = { + .addr = s->config.demod_address, + .flags = 0, + .buf = a, + .len = sizeof(a) + }; + + *(u32 *) a = i2c_adr; + *(u16 *) & a[4] = val; + + rc = i2c_transfer(s->i2c, &msg, 1); + if (rc != 1) + return -EIO; + return 0; +} + +#define WR16(ss,adr, val) \ + _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) +#define WR16_E0(ss,adr, val) \ + _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) +#define RD16(ss,adr) \ + _read16(ss, I2C_ADR_C0(adr)) + +#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc + +/******************************************************************************* + * Tuner callback + ******************************************************************************/ + +static int PLL_Set(struct drx397xD_state *s, + struct dvb_frontend_parameters *fep, int *df_tuner) +{ + struct dvb_frontend *fe = &s->frontend; + u32 f_tuner, f = fep->frequency; + int rc; + + pr_debug("%s\n", __FUNCTION__); + + if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || + (f < s->frontend.ops.tuner_ops.info.frequency_min)) + return -EINVAL; + + *df_tuner = 0; + if (!s->frontend.ops.tuner_ops.set_params || + !s->frontend.ops.tuner_ops.get_frequency) + return -ENOSYS; + + rc = s->frontend.ops.tuner_ops.set_params(fe, fep); + if (rc < 0) + return rc; + + rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner); + if (rc < 0) + return rc; + + *df_tuner = f_tuner - f; + pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f, + f_tuner); + + return 0; +} + +/******************************************************************************* + * Demodulator helper functions + ******************************************************************************/ + +static int SC_WaitForReady(struct drx397xD_state *s) +{ + int cnt = 1000; + int rc; + + pr_debug("%s\n", __FUNCTION__); + + while (cnt--) { + rc = RD16(s, 0x820043); + if (rc == 0) + return 0; + } + return -1; +} + +static int SC_SendCommand(struct drx397xD_state *s, int cmd) +{ + int rc; + + pr_debug("%s\n", __FUNCTION__); + + WR16(s, 0x820043, cmd); + SC_WaitForReady(s); + rc = RD16(s, 0x820042); + if ((rc & 0xffff) == 0xffff) + return -1; + return 0; +} + +static int HI_Command(struct drx397xD_state *s, u16 cmd) +{ + int rc, cnt = 1000; + + pr_debug("%s\n", __FUNCTION__); + + rc = WR16(s, 0x420032, cmd); + if (rc < 0) + return rc; + + do { + rc = RD16(s, 0x420032); + if (rc == 0) { + rc = RD16(s, 0x420031); + return rc; + } + if (rc < 0) + return rc; + } while (--cnt); + return rc; +} + +static int HI_CfgCommand(struct drx397xD_state *s) +{ + + pr_debug("%s\n", __FUNCTION__); + + WR16(s, 0x420033, 0x3973); + WR16(s, 0x420034, s->config.w50); // code 4, log 4 + WR16(s, 0x420035, s->config.w52); // code 15, log 9 + WR16(s, 0x420036, s->config.demod_address << 1); + WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1 +// WR16(s, 0x420033, 0x3973); + if ((s->config.w56 & 8) == 0) + return HI_Command(s, 3); + return WR16(s, 0x420032, 0x3); +} + +static const u8 fastIncrDecLUT_15273[] = { + 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f +}; + +static const u8 slowIncrDecLUT_15272[] = { + 3, 4, 4, 5, 6 +}; + +static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) +{ + u16 w06 = agc->w06; + u16 w08 = agc->w08; + u16 w0A = agc->w0A; + u16 w0C = agc->w0C; + int quot, rem, i, rc = -EINVAL; + + pr_debug("%s\n", __FUNCTION__); + + if (agc->w04 > 0x3ff) + goto exit_rc; + + if (agc->d00 == 1) { + EXIT_RC(RD16(s, 0x0c20010)); + rc &= ~0x10; + EXIT_RC(WR16(s, 0x0c20010, rc)); + return WR16(s, 0x0c20030, agc->w04 & 0x7ff); + } + + if (agc->d00 != 0) + goto exit_rc; + if (w0A < w08) + goto exit_rc; + if (w0A > 0x3ff) + goto exit_rc; + if (w0C > 0x3ff) + goto exit_rc; + if (w06 > 0x3ff) + goto exit_rc; + + EXIT_RC(RD16(s, 0x0c20010)); + rc |= 0x10; + EXIT_RC(WR16(s, 0x0c20010, rc)); + + EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff)); + EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1)); + EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff)); + + quot = w0C / 113; + rem = w0C % 113; + if (quot <= 8) { + quot = 8 - quot; + } else { + quot = 0; + rem += 113; + } + + EXIT_RC(WR16(s, 0x0c20024, quot)); + + i = fastIncrDecLUT_15273[rem / 8]; + EXIT_RC(WR16(s, 0x0c2002d, i)); + EXIT_RC(WR16(s, 0x0c2002e, i)); + + i = slowIncrDecLUT_15272[rem / 28]; + EXIT_RC(WR16(s, 0x0c2002b, i)); + rc = WR16(s, 0x0c2002c, i); + exit_rc: + return rc; +} + +static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) +{ + u16 w04 = agc->w04; + u16 w06 = agc->w06; + int rc = -1; + + pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06); + + if (w04 > 0x3ff) + goto exit_rc; + + switch (agc->d00) { + case 1: + if (w04 == 0x3ff) + w04 = 0x400; + + EXIT_RC(WR16(s, 0x0c20036, w04)); + s->config.w9C &= ~2; + EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); + EXIT_RC(RD16(s, 0x0c20010)); + rc &= 0xbfdf; + EXIT_RC(WR16(s, 0x0c20010, rc)); + EXIT_RC(RD16(s, 0x0c20013)); + rc &= ~2; + break; + case 0: + // loc_8000659 + s->config.w9C &= ~2; + EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); + EXIT_RC(RD16(s, 0x0c20010)); + rc &= 0xbfdf; + rc |= 0x4000; + EXIT_RC(WR16(s, 0x0c20010, rc)); + EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f)); + EXIT_RC(RD16(s, 0x0c20013)); + rc &= ~2; + break; + default: + s->config.w9C |= 2; + EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); + EXIT_RC(RD16(s, 0x0c20010)); + rc &= 0xbfdf; + EXIT_RC(WR16(s, 0x0c20010, rc)); + + EXIT_RC(WR16(s, 0x0c20036, 0)); + + EXIT_RC(RD16(s, 0x0c20013)); + rc |= 2; + } + rc = WR16(s, 0x0c20013, rc); + exit_rc: + return rc; +} + +static int GetLockStatus(struct drx397xD_state *s, int *lockstat) +{ + int rc; + + *lockstat = 0; + + rc = RD16(s, 0x082004b); + if (rc < 0) + return rc; + + if (s->config.d60 != 2) + return 0; + + if ((rc & 7) == 7) + *lockstat |= 1; + if ((rc & 3) == 3) + *lockstat |= 2; + if (rc & 1) + *lockstat |= 4; + return 0; +} + +static int CorrectSysClockDeviation(struct drx397xD_state *s) +{ + int rc = -EINVAL; + int lockstat; + u32 clk, clk_limit; + + pr_debug("%s\n", __FUNCTION__); + + if (s->config.d5C == 0) { + EXIT_RC(WR16(s, 0x08200e8, 0x010)); + EXIT_RC(WR16(s, 0x08200e9, 0x113)); + s->config.d5C = 1; + return rc; + } + if (s->config.d5C != 1) + goto exit_rc; + + rc = RD16(s, 0x0820048); + + rc = GetLockStatus(s, &lockstat); + if (rc < 0) + goto exit_rc; + if ((lockstat & 1) == 0) + goto exit_rc; + + EXIT_RC(WR16(s, 0x0420033, 0x200)); + EXIT_RC(WR16(s, 0x0420034, 0xc5)); + EXIT_RC(WR16(s, 0x0420035, 0x10)); + EXIT_RC(WR16(s, 0x0420036, 0x1)); + EXIT_RC(WR16(s, 0x0420037, 0xa)); + EXIT_RC(HI_Command(s, 6)); + EXIT_RC(RD16(s, 0x0420040)); + clk = rc; + EXIT_RC(RD16(s, 0x0420041)); + clk |= rc << 16; + + if (clk <= 0x26ffff) + goto exit_rc; + if (clk > 0x610000) + goto exit_rc; + + if (!s->bandwidth_parm) + return -EINVAL; + + /* round & convert to Hz */ + clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21; + clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000; + + if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { + s->f_osc = clk; + pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__, + s->config.f_osc * 1000, clk - s->config.f_osc * 1000); + } + rc = WR16(s, 0x08200e8, 0); + exit_rc: + return rc; +} + +static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) +{ + int rc, si, bp; + + pr_debug("%s\n", __FUNCTION__); + + si = s->config.wA0; + if (s->config.w98 == 0) { + si |= 1; + bp = 0; + } else { + si &= ~1; + bp = 0x200; + } + if (s->config.w9A == 0) { + si |= 0x80; + } else { + si &= ~0x80; + } + + EXIT_RC(WR16(s, 0x2150045, 0)); + EXIT_RC(WR16(s, 0x2150010, si)); + EXIT_RC(WR16(s, 0x2150011, bp)); + rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); + exit_rc: + return rc; +} + +static int drx_tune(struct drx397xD_state *s, + struct dvb_frontend_parameters *fep) +{ + u16 v22 = 0; + u16 v1C = 0; + u16 v1A = 0; + u16 v18 = 0; + u32 edi = 0, ebx = 0, ebp = 0, edx = 0; + u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0; + + int rc, df_tuner; + int a, b, c, d; + pr_debug("%s %d\n", __FUNCTION__, s->config.d60); + + if (s->config.d60 != 2) + goto set_tuner; + rc = CorrectSysClockDeviation(s); + if (rc < 0) + goto set_tuner; + + s->config.d60 = 1; + rc = ConfigureMPEGOutput(s, 0); + if (rc < 0) + goto set_tuner; + set_tuner: + + rc = PLL_Set(s, fep, &df_tuner); + if (rc < 0) { + printk(KERN_ERR "Error in pll_set\n"); + goto exit_rc; + } + msleep(200); + + a = rc = RD16(s, 0x2150016); + if (rc < 0) + goto exit_rc; + b = rc = RD16(s, 0x2150010); + if (rc < 0) + goto exit_rc; + c = rc = RD16(s, 0x2150034); + if (rc < 0) + goto exit_rc; + d = rc = RD16(s, 0x2150035); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2150014, c); + rc = WR16(s, 0x2150015, d); + rc = WR16(s, 0x2150010, 0); + rc = WR16(s, 0x2150000, 2); + rc = WR16(s, 0x2150036, 0x0fff); + rc = WR16(s, 0x2150016, a); + + rc = WR16(s, 0x2150010, 2); + rc = WR16(s, 0x2150007, 0); + rc = WR16(s, 0x2150000, 1); + rc = WR16(s, 0x2110000, 0); + rc = WR16(s, 0x0800000, 0); + rc = WR16(s, 0x2800000, 0); + rc = WR16(s, 0x2110010, 0x664); + + rc = write_fw(s, DRXD_ResetECRAM); + rc = WR16(s, 0x2110000, 1); + + rc = write_fw(s, DRXD_InitSC); + if (rc < 0) + goto exit_rc; + + rc = SetCfgIfAgc(s, &s->config.ifagc); + if (rc < 0) + goto exit_rc; + + rc = SetCfgRfAgc(s, &s->config.rfagc); + if (rc < 0) + goto exit_rc; + + if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K) + v22 = 1; + switch (fep->u.ofdm.transmission_mode) { + case TRANSMISSION_MODE_8K: + edi = 1; + if (s->chip_rev == DRXD_FW_B1) + break; + + rc = WR16(s, 0x2010010, 0); + if (rc < 0) + break; + v1C = 0x63; + v1A = 0x53; + v18 = 0x43; + break; + default: + edi = 0; + if (s->chip_rev == DRXD_FW_B1) + break; + + rc = WR16(s, 0x2010010, 1); + if (rc < 0) + break; + + v1C = 0x61; + v1A = 0x47; + v18 = 0x41; + } + + switch (fep->u.ofdm.guard_interval) { + case GUARD_INTERVAL_1_4: + edi |= 0x0c; + break; + case GUARD_INTERVAL_1_8: + edi |= 0x08; + break; + case GUARD_INTERVAL_1_16: + edi |= 0x04; + break; + case GUARD_INTERVAL_1_32: + break; + default: + v22 |= 2; + } + + ebx = 0; + ebp = 0; + v20 = 0; + v1E = 0; + v16 = 0; + v14 = 0; + v12 = 0; + v10 = 0; + v0E = 0; + + switch (fep->u.ofdm.hierarchy_information) { + case HIERARCHY_1: + edi |= 0x40; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x1c10047, 1); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010012, 1); + if (rc < 0) + goto exit_rc; + ebx = 0x19f; + ebp = 0x1fb; + v20 = 0x0c0; + v1E = 0x195; + v16 = 0x1d6; + v14 = 0x1ef; + v12 = 4; + v10 = 5; + v0E = 5; + break; + case HIERARCHY_2: + edi |= 0x80; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x1c10047, 2); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010012, 2); + if (rc < 0) + goto exit_rc; + ebx = 0x08f; + ebp = 0x12f; + v20 = 0x0c0; + v1E = 0x11e; + v16 = 0x1d6; + v14 = 0x15e; + v12 = 4; + v10 = 5; + v0E = 5; + break; + case HIERARCHY_4: + edi |= 0xc0; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x1c10047, 3); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010012, 3); + if (rc < 0) + goto exit_rc; + ebx = 0x14d; + ebp = 0x197; + v20 = 0x0c0; + v1E = 0x1ce; + v16 = 0x1d6; + v14 = 0x11a; + v12 = 4; + v10 = 6; + v0E = 5; + break; + default: + v22 |= 8; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x1c10047, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010012, 0); + if (rc < 0) + goto exit_rc; + // QPSK QAM16 QAM64 + ebx = 0x19f; // 62 + ebp = 0x1fb; // 15 + v20 = 0x16a; // 62 + v1E = 0x195; // 62 + v16 = 0x1bb; // 15 + v14 = 0x1ef; // 15 + v12 = 5; // 16 + v10 = 5; // 16 + v0E = 5; // 16 + } + + switch (fep->u.ofdm.constellation) { + default: + v22 |= 4; + case QPSK: + if (s->chip_rev == DRXD_FW_B1) + break; + + rc = WR16(s, 0x1c10046, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010011, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001a, 0x10); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001b, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001c, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10062, v20); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c1002a, v1C); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10015, v16); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10016, v12); + if (rc < 0) + goto exit_rc; + break; + case QAM_16: + edi |= 0x10; + if (s->chip_rev == DRXD_FW_B1) + break; + + rc = WR16(s, 0x1c10046, 1); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010011, 1); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001a, 0x10); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001b, 4); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001c, 0); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10062, v1E); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c1002a, v1A); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10015, v14); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10016, v10); + if (rc < 0) + goto exit_rc; + break; + case QAM_64: + edi |= 0x20; + rc = WR16(s, 0x1c10046, 2); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x2010011, 2); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001a, 0x20); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001b, 8); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x201001c, 2); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10062, ebx); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c1002a, v18); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10015, ebp); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x1c10016, v0E); + if (rc < 0) + goto exit_rc; + break; + } + + if (s->config.s20d24 == 1) { + rc = WR16(s, 0x2010013, 0); + } else { + rc = WR16(s, 0x2010013, 1); + edi |= 0x1000; + } + + switch (fep->u.ofdm.code_rate_HP) { + default: + v22 |= 0x10; + case FEC_1_2: + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x2090011, 0); + break; + case FEC_2_3: + edi |= 0x200; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x2090011, 1); + break; + case FEC_3_4: + edi |= 0x400; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x2090011, 2); + break; + case FEC_5_6: /* 5 */ + edi |= 0x600; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x2090011, 3); + break; + case FEC_7_8: /* 7 */ + edi |= 0x800; + if (s->chip_rev == DRXD_FW_B1) + break; + rc = WR16(s, 0x2090011, 4); + break; + }; + if (rc < 0) + goto exit_rc; + + switch (fep->u.ofdm.bandwidth) { + default: + rc = -EINVAL; + goto exit_rc; + case BANDWIDTH_8_MHZ: /* 0 */ + case BANDWIDTH_AUTO: + rc = WR16(s, 0x0c2003f, 0x32); + s->bandwidth_parm = ebx = 0x8b8249; // 9142857 + edx = 0; + break; + case BANDWIDTH_7_MHZ: + rc = WR16(s, 0x0c2003f, 0x3b); + s->bandwidth_parm = ebx = 0x7a1200; // 8000000 + edx = 0x4807; + break; + case BANDWIDTH_6_MHZ: + rc = WR16(s, 0x0c2003f, 0x47); + s->bandwidth_parm = ebx = 0x68a1b6; // 6857142 + edx = 0x0f07; + break; + }; + + if (rc < 0) + goto exit_rc; + + rc = WR16(s, 0x08200ec, edx); + if (rc < 0) + goto exit_rc; + + rc = RD16(s, 0x0820050); + if (rc < 0) + goto exit_rc; + rc = WR16(s, 0x0820050, rc); + + { + long dummy; + + /* Configure bandwidth specific factor */ + ebx = div_ll_X_l_rem(((u64) (s->f_osc) << 21) + (ebx >> 1), + ebx, &dummy) - 0x800000; + EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff)); + EXIT_RC(WR16(s, 0x0c50011, ebx >> 16)); + + /* drx397xD oscillator calibration */ + ebx = div_ll_X_l_rem(((u64) (s->config.f_if + df_tuner) << 28) + + (s->f_osc >> 1), s->f_osc, &dummy); + } + ebx &= 0xfffffff; + if (fep->inversion == INVERSION_ON) + ebx = 0x10000000 - ebx; + + EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff)); + EXIT_RC(WR16(s, 0x0c30011, ebx >> 16)); + + EXIT_RC(WR16(s, 0x0800000, 1)); + EXIT_RC(RD16(s, 0x0800000)); + + + EXIT_RC(SC_WaitForReady(s)); + EXIT_RC(WR16(s, 0x0820042, 0)); + EXIT_RC(WR16(s, 0x0820041, v22)); + EXIT_RC(WR16(s, 0x0820040, edi)); + EXIT_RC(SC_SendCommand(s, 3)); + + rc = RD16(s, 0x0800000); + + SC_WaitForReady(s); + WR16(s, 0x0820042, 0); + WR16(s, 0x0820041, 1); + WR16(s, 0x0820040, 1); + SC_SendCommand(s, 1); + +// rc = WR16(s, 0x2150000, 1); +// if (rc < 0) goto exit_rc; + + rc = WR16(s, 0x2150000, 2); + rc = WR16(s, 0x2150016, a); + rc = WR16(s, 0x2150010, 4); + rc = WR16(s, 0x2150036, 0); + rc = WR16(s, 0x2150000, 1); + s->config.d60 = 2; + exit_rc: + return rc; +} + +/******************************************************************************* + * DVB interface + ******************************************************************************/ + +static int drx397x_init(struct dvb_frontend *fe) +{ + struct drx397xD_state *s = fe->demodulator_priv; + int rc; + + pr_debug("%s\n", __FUNCTION__); + + s->config.rfagc.d00 = 2; /* 0x7c */ + s->config.rfagc.w04 = 0; + s->config.rfagc.w06 = 0x3ff; + + s->config.ifagc.d00 = 0; /* 0x68 */ + s->config.ifagc.w04 = 0; + s->config.ifagc.w06 = 140; + s->config.ifagc.w08 = 0; + s->config.ifagc.w0A = 0x3ff; + s->config.ifagc.w0C = 0x388; + + /* for signal strenght calculations */ + s->config.ss76 = 820; + s->config.ss78 = 2200; + s->config.ss7A = 150; + + /* HI_CfgCommand */ + s->config.w50 = 4; + s->config.w52 = 9; // 0xf; + + s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ + s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ + s->config.w92 = 12000; // 20000; + + s->config.w9C = 0x000e; + s->config.w9E = 0x0000; + + /* ConfigureMPEGOutput params */ + s->config.wA0 = 4; + s->config.w98 = 1; // 0; + s->config.w9A = 1; + + /* get chip revision */ + rc = RD16(s, 0x2410019); + if (rc < 0) + return -ENODEV; + + if (rc == 0) { + printk(KERN_INFO "%s: chip revision A2\n", mod_name); + rc = drx_load_fw(s, DRXD_FW_A2); + } else { + + rc = (rc >> 12) - 3; + switch (rc) { + case 1: + s->flags |= F_SET_0D4h; + case 0: + case 4: + s->flags |= F_SET_0D0h; + break; + case 2: + case 5: + break; + case 3: + s->flags |= F_SET_0D4h; + break; + default: + return -ENODEV; + }; + printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc); + rc = drx_load_fw(s, DRXD_FW_B1); + } + if (rc < 0) + goto error; + + rc = WR16(s, 0x0420033, 0x3973); + if (rc < 0) + goto error; + + rc = HI_Command(s, 2); + + msleep(1); + + if (s->chip_rev == DRXD_FW_A2) { + rc = WR16(s, 0x043012d, 0x47F); + if (rc < 0) + goto error; + } + rc = WR16_E0(s, 0x0400000, 0); + if (rc < 0) + goto error; + + if (s->config.w92 > 20000 || s->config.w92 % 4000) { + printk(KERN_ERR "%s: invalid osc frequency\n", mod_name); + rc = -1; + goto error; + } + + rc = WR16(s, 0x2410010, 1); + if (rc < 0) + goto error; + rc = WR16(s, 0x2410011, 0x15); + if (rc < 0) + goto error; + rc = WR16(s, 0x2410012, s->config.w92 / 4000); + if (rc < 0) + goto error; +#ifdef ORIG_FW + rc = WR16(s, 0x2410015, 2); + if (rc < 0) + goto error; +#endif + rc = WR16(s, 0x2410017, 0x3973); + if (rc < 0) + goto error; + + s->f_osc = s->config.f_osc * 1000; /* initial estimator */ + + s->config.w56 = 1; + + rc = HI_CfgCommand(s); + if (rc < 0) + goto error; + + rc = write_fw(s, DRXD_InitAtomicRead); + if (rc < 0) + goto error; + + if (s->chip_rev == DRXD_FW_A2) { + rc = WR16(s, 0x2150013, 0); + if (rc < 0) + goto error; + } + + rc = WR16_E0(s, 0x0400002, 0); + if (rc < 0) + goto error; + rc = WR16(s, 0x0400002, 0); + if (rc < 0) + goto error; + + if (s->chip_rev == DRXD_FW_A2) { + rc = write_fw(s, DRXD_ResetCEFR); + if (rc < 0) + goto error; + } + rc = write_fw(s, DRXD_microcode); + if (rc < 0) + goto error; + + s->config.w9C = 0x0e; + if (s->flags & F_SET_0D0h) { + s->config.w9C = 0; + rc = RD16(s, 0x0c20010); + if (rc < 0) + goto write_DRXD_InitFE_1; + + rc &= ~0x1000; + rc = WR16(s, 0x0c20010, rc); + if (rc < 0) + goto write_DRXD_InitFE_1; + + rc = RD16(s, 0x0c20011); + if (rc < 0) + goto write_DRXD_InitFE_1; + + rc &= ~0x8; + rc = WR16(s, 0x0c20011, rc); + if (rc < 0) + goto write_DRXD_InitFE_1; + + rc = WR16(s, 0x0c20012, 1); + } + + write_DRXD_InitFE_1: + + rc = write_fw(s, DRXD_InitFE_1); + if (rc < 0) + goto error; + + rc = 1; + if (s->chip_rev == DRXD_FW_B1) { + if (s->flags & F_SET_0D0h) + rc = 0; + } else { + if (s->flags & F_SET_0D0h) + rc = 4; + } + + rc = WR16(s, 0x0C20012, rc); + if (rc < 0) + goto error; + + rc = WR16(s, 0x0C20013, s->config.w9E); + if (rc < 0) + goto error; + rc = WR16(s, 0x0C20015, s->config.w9C); + if (rc < 0) + goto error; + + rc = write_fw(s, DRXD_InitFE_2); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitFT); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitCP); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitCE); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitEQ); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitEC); + if (rc < 0) + goto error; + rc = write_fw(s, DRXD_InitSC); + if (rc < 0) + goto error; + + rc = SetCfgIfAgc(s, &s->config.ifagc); + if (rc < 0) + goto error; + + rc = SetCfgRfAgc(s, &s->config.rfagc); + if (rc < 0) + goto error; + + rc = ConfigureMPEGOutput(s, 1); + rc = WR16(s, 0x08201fe, 0x0017); + rc = WR16(s, 0x08201ff, 0x0101); + + s->config.d5C = 0; + s->config.d60 = 1; + s->config.d48 = 1; + error: + return rc; +} + +static int drx397x_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + return 0; +} + +static int drx397x_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct drx397xD_state *s = fe->demodulator_priv; + + s->config.s20d24 = 1; // 0; + return drx_tune(s, params); +} + +static int drx397x_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings + *fe_tune_settings) +{ + fe_tune_settings->min_delay_ms = 10000; + fe_tune_settings->step_size = 0; + fe_tune_settings->max_drift = 0; + return 0; +} + +static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) +{ + struct drx397xD_state *s = fe->demodulator_priv; + int lockstat; + + GetLockStatus(s, &lockstat); + /* TODO */ +// if (lockstat & 1) +// CorrectSysClockDeviation(s); + + *status = 0; + if (lockstat & 2) { + CorrectSysClockDeviation(s); + ConfigureMPEGOutput(s, 1); + *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; + } + if (lockstat & 4) { + *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; + } + + return 0; +} + +static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) +{ + *ber = 0; + return 0; +} + +static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr) +{ + *snr = 0; + return 0; +} + +static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) +{ + struct drx397xD_state *s = fe->demodulator_priv; + int rc; + + if (s->config.ifagc.d00 == 2) { + *strength = 0xffff; + return 0; + } + rc = RD16(s, 0x0c20035); + if (rc < 0) { + *strength = 0; + return 0; + } + rc &= 0x3ff; + /* Signal strength is calculated using the following formula: + * + * a = 2200 * 150 / (2200 + 150); + * a = a * 3300 / (a + 820); + * b = 2200 * 3300 / (2200 + 820); + * c = (((b-a) * rc) >> 10 + a) << 4; + * strength = ~c & 0xffff; + * + * The following does the same but with less rounding errors: + */ + *strength = ~(7720 + (rc * 30744 >> 10)); + return 0; +} + +static int drx397x_read_ucblocks(struct dvb_frontend *fe, + unsigned int *ucblocks) +{ + *ucblocks = 0; + return 0; +} + +static int drx397x_sleep(struct dvb_frontend *fe) +{ + return 0; +} + +static void drx397x_release(struct dvb_frontend *fe) +{ + struct drx397xD_state *s = fe->demodulator_priv; + printk(KERN_INFO "%s: release demodulator\n", mod_name); + if (s) { + drx_release_fw(s); + kfree(s); + } + +} + +static struct dvb_frontend_ops drx397x_ops = { + + .info = { + .name = "Micronas DRX397xD DVB-T Frontend", + .type = FE_OFDM, + .frequency_min = 47125000, + .frequency_max = 855250000, + .frequency_stepsize = 166667, + .frequency_tolerance = 0, + .caps = /* 0x0C01B2EAE */ + FE_CAN_FEC_1_2 | // = 0x2, + FE_CAN_FEC_2_3 | // = 0x4, + FE_CAN_FEC_3_4 | // = 0x8, + FE_CAN_FEC_5_6 | // = 0x20, + FE_CAN_FEC_7_8 | // = 0x80, + FE_CAN_FEC_AUTO | // = 0x200, + FE_CAN_QPSK | // = 0x400, + FE_CAN_QAM_16 | // = 0x800, + FE_CAN_QAM_64 | // = 0x2000, + FE_CAN_QAM_AUTO | // = 0x10000, + FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000, + FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000, + FE_CAN_HIERARCHY_AUTO | // = 0x100000, + FE_CAN_RECOVER | // = 0x40000000, + FE_CAN_MUTE_TS // = 0x80000000 + }, + + .release = drx397x_release, + .init = drx397x_init, + .sleep = drx397x_sleep, + + .set_frontend = drx397x_set_frontend, + .get_tune_settings = drx397x_get_tune_settings, + .get_frontend = drx397x_get_frontend, + + .read_status = drx397x_read_status, + .read_snr = drx397x_read_snr, + .read_signal_strength = drx397x_read_signal_strength, + .read_ber = drx397x_read_ber, + .read_ucblocks = drx397x_read_ucblocks, +}; + +struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, + struct i2c_adapter *i2c) +{ + struct drx397xD_state *s = NULL; + + /* allocate memory for the internal state */ + s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); + if (s == NULL) + goto error; + + /* setup the state */ + s->i2c = i2c; + memcpy(&s->config, config, sizeof(struct drx397xD_config)); + + /* check if the demod is there */ + if (RD16(s, 0x2410019) < 0) + goto error; + + /* create dvb_frontend */ + memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); + s->frontend.demodulator_priv = s; + + return &s->frontend; + error: + kfree(s); + return NULL; +} + +MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); +MODULE_AUTHOR("Henk Vergonet"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(drx397xD_attach); diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h new file mode 100644 index 000000000000..ddc7a07971b7 --- /dev/null +++ b/drivers/media/dvb/frontends/drx397xD.h @@ -0,0 +1,130 @@ +/* + * Driver for Micronas DVB-T drx397xD demodulator + * + * Copyright (C) 2007 Henk vergonet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef _DRX397XD_H_INCLUDED +#define _DRX397XD_H_INCLUDED + +#include + +#define DRX_F_STEPSIZE 166667 +#define DRX_F_OFFSET 36000000 + +#define I2C_ADR_C0(x) \ +( (u32)cpu_to_le32( \ + (u32)( \ + (((u32)(x) & (u32)0x000000ffUL) ) | \ + (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ + (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ + ( (u32)0x00c00000UL) \ + )) \ +) + +#define I2C_ADR_E0(x) \ +( (u32)cpu_to_le32( \ + (u32)( \ + (((u32)(x) & (u32)0x000000ffUL) ) | \ + (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ + (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ + ( (u32)0x00e00000UL) \ + )) \ +) + +struct drx397xD_CfgRfAgc /* 0x7c */ +{ + int d00; /* 2 */ + u16 w04; + u16 w06; +}; + +struct drx397xD_CfgIfAgc /* 0x68 */ +{ + int d00; /* 0 */ + u16 w04; /* 0 */ + u16 w06; + u16 w08; + u16 w0A; + u16 w0C; +}; + +struct drx397xD_s20 { + int d04; + u32 d18; + u32 d1C; + u32 d20; + u32 d14; + u32 d24; + u32 d0C; + u32 d08; +}; + +struct drx397xD_config +{ + /* demodulator's I2C address */ + u8 demod_address; /* 0x0f */ + + struct drx397xD_CfgIfAgc ifagc; /* 0x68 */ + struct drx397xD_CfgRfAgc rfagc; /* 0x7c */ + u32 s20d24; + + /* HI_CfgCommand parameters */ + u16 w50, w52, /* w54, */ w56; + + int d5C; + int d60; + int d48; + int d28; + + u32 f_if; /* d14: intermediate frequency [Hz] */ + /* 36000000 on Cinergy 2400i DT */ + /* 42800000 on Pinnacle Hybrid PRO 330e */ + + u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */ + + u16 w92; /* 20000 */ + + u16 wA0; + u16 w98; + u16 w9A; + + u16 w9C; /* 0xe0 */ + u16 w9E; /* 0x00 */ + + /* used for signal strength calculations in + drx397x_read_signal_strength + */ + u16 ss78; // 2200 + u16 ss7A; // 150 + u16 ss76; // 820 +}; + +#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE)) +extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif /* CONFIG_DVB_DRX397XD */ + +#endif /* _DRX397XD_H_INCLUDED */ diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h new file mode 100644 index 000000000000..01de02a81cd4 --- /dev/null +++ b/drivers/media/dvb/frontends/drx397xD_fw.h @@ -0,0 +1,40 @@ +/* + * Firmware definitions for Micronas drx397xD + * + * Copyright (C) 2007 Henk Vergonet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see . + */ + +#ifdef _FW_ENTRY + _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0 ), + _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1 ), +#undef _FW_ENTRY +#endif /* _FW_ENTRY */ + +#ifdef _BLOB_ENTRY + _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ), + _BLOB_ENTRY("InitCE", DRXD_InitCE ), + _BLOB_ENTRY("InitCP", DRXD_InitCP ), + _BLOB_ENTRY("InitEC", DRXD_InitEC ), + _BLOB_ENTRY("InitEQ", DRXD_InitEQ ), + _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ), + _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ), + _BLOB_ENTRY("InitFT", DRXD_InitFT ), + _BLOB_ENTRY("InitSC", DRXD_InitSC ), + _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ), + _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ), + _BLOB_ENTRY("microcode", DRXD_microcode ), +#undef _BLOB_ENTRY +#endif /* _BLOB_ENTRY */ -- cgit v1.2.3 From 29e031d5b09ae60d0ecdb6a1d869d591d63e893a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Apr 2008 21:43:23 -0300 Subject: V4L/DVB (7737): drx397xD: fix math usage The previous code were using a div64 math specific to i386. Replace for an asm-generic one. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drx397xD.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index b0ff77ffc88b..af4354662124 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "drx397xD.h" @@ -1024,17 +1025,15 @@ static int drx_tune(struct drx397xD_state *s, rc = WR16(s, 0x0820050, rc); { - long dummy; - /* Configure bandwidth specific factor */ - ebx = div_ll_X_l_rem(((u64) (s->f_osc) << 21) + (ebx >> 1), - ebx, &dummy) - 0x800000; + ebx = div64_64(((u64) (s->f_osc) << 21) + (ebx >> 1), + (u64)ebx) - 0x800000; EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff)); EXIT_RC(WR16(s, 0x0c50011, ebx >> 16)); /* drx397xD oscillator calibration */ - ebx = div_ll_X_l_rem(((u64) (s->config.f_if + df_tuner) << 28) + - (s->f_osc >> 1), s->f_osc, &dummy); + ebx = div64_64(((u64) (s->config.f_if + df_tuner) << 28) + + (s->f_osc >> 1), (u64)s->f_osc); } ebx &= 0xfffffff; if (fep->inversion == INVERSION_ON) -- cgit v1.2.3 From 22b0119e09d6e7d671535c61de27753a5e1a0a63 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Wed, 30 Apr 2008 09:52:50 -0300 Subject: V4L/DVB (7812): 2.6.25-rc5-mm1 specifc div64_u64 fixes Rename a few more div64_u64 which are only in -mm. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drx397xD.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index af4354662124..d71cce93d08e 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -1026,13 +1026,13 @@ static int drx_tune(struct drx397xD_state *s, { /* Configure bandwidth specific factor */ - ebx = div64_64(((u64) (s->f_osc) << 21) + (ebx >> 1), + ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1), (u64)ebx) - 0x800000; EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff)); EXIT_RC(WR16(s, 0x0c50011, ebx >> 16)); /* drx397xD oscillator calibration */ - ebx = div64_64(((u64) (s->config.f_if + df_tuner) << 28) + + ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) + (s->f_osc >> 1), (u64)s->f_osc); } ebx &= 0xfffffff; -- cgit v1.2.3 From e272ae088fccf0e98ee0042392bd52a3455f28bd Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 8 Jul 2008 12:56:04 -0300 Subject: V4L/DVB (8247): Fix a const pointer assignment error in the drx397xD demodulator driver Fix an assignment of a const pointer to a non-const pointer in the drx397xD demodulator driver. This was introduced in patch eb9bd0e567365d4f607d32d8c41e201da65aa971. Signed-off-by: David Howells Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drx397xD.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c index d71cce93d08e..3cbed874a6f8 100644 --- a/drivers/media/dvb/frontends/drx397xD.c +++ b/drivers/media/dvb/frontends/drx397xD.c @@ -73,7 +73,7 @@ static struct { const struct firmware *file; rwlock_t lock; int refcnt; - u8 *data[ARRAY_SIZE(blob_name)]; + const u8 *data[ARRAY_SIZE(blob_name)]; } fw[] = { #define _FW_ENTRY(a, b) { \ .name = a, \ @@ -109,7 +109,7 @@ static void drx_release_fw(struct drx397xD_state *s) static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) { - u8 *data; + const u8 *data; size_t size, len; int i = 0, j, rc = -EINVAL; @@ -193,7 +193,7 @@ static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) static int write_fw(struct drx397xD_state *s, blob_ix_t ix) { struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 }; - u8 *data; + const u8 *data; int len, rc = 0, i = 0; if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { @@ -214,7 +214,7 @@ static int write_fw(struct drx397xD_state *s, blob_ix_t ix) case 0: /* bytecode */ len = data[i++]; msg.len = len; - msg.buf = &data[i]; + msg.buf = (__u8 *) &data[i]; if (i2c_transfer(s->i2c, &msg, 1) != 1) { rc = -EIO; goto exit_rc; -- cgit v1.2.3 From 7fd4828f6cc5bd4339ff58e372ccb5f528548b30 Mon Sep 17 00:00:00 2001 From: Igor M Liplianin Date: Sun, 20 Jul 2008 08:05:50 -0300 Subject: V4L/DVB (8421): Adds support for Dvbworld DVB-S 2102 USB card Signed-off-by: Igor M Liplianin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 8 + drivers/media/dvb/dvb-usb/Makefile | 3 + drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 1 + drivers/media/dvb/dvb-usb/dw2102.c | 425 ++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/dw2102.h | 9 + drivers/media/dvb/frontends/z0194a.h | 97 ++++++++ 6 files changed, 543 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/dw2102.c create mode 100644 drivers/media/dvb/dvb-usb/dw2102.h create mode 100644 drivers/media/dvb/frontends/z0194a.h (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index a577c0f89f67..3c663c65ef66 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -246,6 +246,14 @@ config DVB_USB_AF9005_REMOTE Say Y here to support the default remote control decoding for the Afatech AF9005 based receiver. +config DVB_USB_DW2102 + tristate "DvbWorld 2102 DVB-S USB2.0 receiver" + depends on DVB_USB + select DVB_STV0299 if !DVB_FE_CUSTOMISE + select DVB_PLL if !DVB_FE_CUSTOMISE + help + Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver. + config DVB_USB_ANYSEE tristate "Anysee DVB-T/C USB2.0 support" depends on DVB_USB diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 44c11e45e564..e206f1ea0027 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o dvb-usb-anysee-objs = anysee.o obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o +dvb-usb-dw2102-objs = dw2102.o +obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o + EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index e5238b31e946..029b437caf9a 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -204,5 +204,6 @@ #define USB_PID_ASUS_U3000 0x171f #define USB_PID_ASUS_U3100 0x173f #define USB_PID_YUAN_EC372S 0x1edc +#define USB_PID_DW2102 0x2102 #endif diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c new file mode 100644 index 000000000000..a4d898b44e55 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -0,0 +1,425 @@ +/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card +* +* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* see Documentation/dvb/README.dvb-usb for more information +*/ +#include +#include "dw2102.h" +#include "stv0299.h" +#include "z0194a.h" + +#ifndef USB_PID_DW2102 +#define USB_PID_DW2102 0x2102 +#endif + +#define DW2102_READ_MSG 0 +#define DW2102_WRITE_MSG 1 + +#define REG_1F_SYMBOLRATE_BYTE0 0x1f +#define REG_20_SYMBOLRATE_BYTE1 0x20 +#define REG_21_SYMBOLRATE_BYTE2 0x21 + +#define DW2102_VOLTAGE_CTRL (0x1800) +#define DW2102_RC_QUERY (0x1a00) + +struct dw2102_state { + u32 last_key_pressed; +}; +struct dw2102_rc_keys { + u32 keycode; + u32 event; +}; + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + +static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value, + u8 *data, u16 len, int flags) +{ + int ret; + u8 u8buf[len]; + + unsigned int pipe = (flags == DW2102_READ_MSG) ? + usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); + u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; + + if (flags == DW2102_WRITE_MSG) + memcpy(u8buf, data, len); + ret = usb_control_msg(dev, pipe, request, + request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000); + + if (flags == DW2102_READ_MSG) + memcpy(data, u8buf, len); + return ret; +} + +/* I2C */ + +static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], + int num) +{ +struct dvb_usb_device *d = i2c_get_adapdata(adap); + int i = 0, ret = 0; + u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; + u8 request; + u16 value; + + if (!d) + return -ENODEV; + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + + switch (num) { + case 2: + /* read stv0299 register */ + request = 0xb5; + value = msg[0].buf[0];/* register */ + for (i = 0; i < msg[1].len; i++) { + value = value + i; + ret = dw2102_op_rw(d->udev, 0xb5, + value, buf6, 2, DW2102_READ_MSG); + msg[1].buf[i] = buf6[0]; + + } + break; + case 1: + switch (msg[0].addr) { + case 0x68: + /* write to stv0299 register */ + buf6[0] = 0x2a; + buf6[1] = msg[0].buf[0]; + buf6[2] = msg[0].buf[1]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 3, DW2102_WRITE_MSG); + break; + case 0x60: + if (msg[0].flags == 0) { + /* write to tuner pll */ + buf6[0] = 0x2c; + buf6[1] = 5; + buf6[2] = 0xc0; + buf6[3] = msg[0].buf[0]; + buf6[4] = msg[0].buf[1]; + buf6[5] = msg[0].buf[2]; + buf6[6] = msg[0].buf[3]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 7, DW2102_WRITE_MSG); + } else { + /* write to tuner pll */ + ret = dw2102_op_rw(d->udev, 0xb5, + 0, buf6, 1, DW2102_READ_MSG); + msg[0].buf[0] = buf6[0]; + } + break; + case (DW2102_RC_QUERY): + ret = dw2102_op_rw(d->udev, 0xb8, + 0, buf6, 2, DW2102_READ_MSG); + msg[0].buf[0] = buf6[0]; + msg[0].buf[1] = buf6[1]; + break; + case (DW2102_VOLTAGE_CTRL): + buf6[0] = 0x30; + buf6[1] = msg[0].buf[0]; + ret = dw2102_op_rw(d->udev, 0xb2, + 0, buf6, 2, DW2102_WRITE_MSG); + break; + } + + break; + } + + mutex_unlock(&d->i2c_mutex); + return num; +} + +static u32 dw2102_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm dw2102_i2c_algo = { + .master_xfer = dw2102_i2c_transfer, + .functionality = dw2102_i2c_func, +}; + +static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) +{ + static u8 command_13v[1] = {0x00}; + static u8 command_18v[1] = {0x01}; + struct i2c_msg msg[] = { + {.addr = DW2102_VOLTAGE_CTRL, .flags = 0, + .buf = command_13v, .len = 1}, + }; + + struct dvb_usb_adapter *udev_adap = + (struct dvb_usb_adapter *)(fe->dvb->priv); + if (voltage == SEC_VOLTAGE_18) + msg[0].buf = command_18v; + i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); + return 0; +} + +static int dw2102_frontend_attach(struct dvb_usb_adapter *d) +{ + d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, + &d->dev->i2c_adap); + if (d->fe != NULL) { + d->fe->ops.set_voltage = dw2102_set_voltage; + info("Attached stv0299!\n"); + return 0; + } + return -EIO; +} + +static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) +{ + dvb_attach(dvb_pll_attach, adap->fe, 0x60, + &adap->dev->i2c_adap, DVB_PLL_OPERA1); + return 0; +} + +static struct dvb_usb_rc_key dw2102_rc_keys[] = { + { 0xf8, 0x0a, KEY_Q }, /*power*/ + { 0xf8, 0x0c, KEY_M }, /*mute*/ + { 0xf8, 0x11, KEY_1 }, + { 0xf8, 0x12, KEY_2 }, + { 0xf8, 0x13, KEY_3 }, + { 0xf8, 0x14, KEY_4 }, + { 0xf8, 0x15, KEY_5 }, + { 0xf8, 0x16, KEY_6 }, + { 0xf8, 0x17, KEY_7 }, + { 0xf8, 0x18, KEY_8 }, + { 0xf8, 0x19, KEY_9 }, + { 0xf8, 0x10, KEY_0 }, + { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/ + { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/ + { 0xf8, 0x1a, KEY_O }, /*vol+*/ + { 0xf8, 0x0e, KEY_Z }, /*vol-*/ + { 0xf8, 0x04, KEY_R }, /*rec*/ + { 0xf8, 0x09, KEY_D }, /*fav*/ + { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/ + { 0xf8, 0x07, KEY_A }, /*fast*/ + { 0xf8, 0x0b, KEY_P }, /*pause*/ + { 0xf8, 0x02, KEY_ESC }, /*cancel*/ + { 0xf8, 0x03, KEY_G }, /*tab*/ + { 0xf8, 0x00, KEY_UP }, /*up*/ + { 0xf8, 0x1f, KEY_ENTER }, /*ok*/ + { 0xf8, 0x01, KEY_DOWN }, /*down*/ + { 0xf8, 0x05, KEY_C }, /*cap*/ + { 0xf8, 0x06, KEY_S }, /*stop*/ + { 0xf8, 0x40, KEY_F }, /*full*/ + { 0xf8, 0x1e, KEY_W }, /*tvmode*/ + { 0xf8, 0x1b, KEY_B }, /*recall*/ + +}; + + + +static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + struct dw2102_state *st = d->priv; + u8 key[2]; + struct i2c_msg msg[] = { + {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, + .len = 2}, + }; + int i; + + *state = REMOTE_NO_KEY_PRESSED; + if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { + for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) { + if (dw2102_rc_keys[i].data == msg[0].buf[0]) { + *state = REMOTE_KEY_PRESSED; + *event = dw2102_rc_keys[i].event; + st->last_key_pressed = + dw2102_rc_keys[i].event; + break; + } + st->last_key_pressed = 0; + } + } + /* info("key: %x %x\n",key[0],key[1]); */ + return 0; +} + +static struct usb_device_id dw2102_table[] = { + {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, + {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, + { } +}; + +MODULE_DEVICE_TABLE(usb, dw2102_table); + +static int dw2102_load_firmware(struct usb_device *dev, + const struct firmware *frmwr) +{ + u8 *b, *p; + int ret = 0, i; + u8 reset; + u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0}; + const struct firmware *fw; + const char *filename = "dvb-usb-dw2101.fw"; + switch (dev->descriptor.idProduct) { + case 0x2101: + ret = request_firmware(&fw, filename, &dev->dev); + if (ret != 0) { + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more details " + "on firmware-problems.", filename); + return ret; + } + break; + case USB_PID_DW2102: + fw = frmwr; + break; + } + info("start downloading DW2102 firmware"); + p = kmalloc(fw->size, GFP_KERNEL); + reset = 1; + /*stop the CPU*/ + dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG); + dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG); + + if (p != NULL) { + memcpy(p, fw->data, fw->size); + for (i = 0; i < fw->size; i += 0x40) { + b = (u8 *) p + i; + if (dw2102_op_rw + (dev, 0xa0, i, b , 0x40, + DW2102_WRITE_MSG) != 0x40 + ) { + err("error while transferring firmware"); + ret = -EINVAL; + break; + } + } + /* restart the CPU */ + reset = 0; + if (ret || dw2102_op_rw + (dev, 0xa0, 0x7f92, &reset, 1, + DW2102_WRITE_MSG) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + if (ret || dw2102_op_rw + (dev, 0xa0, 0xe600, &reset, 1, + DW2102_WRITE_MSG) != 1) { + err("could not restart the USB controller CPU."); + ret = -EINVAL; + } + /* init registers */ + switch (dev->descriptor.idProduct) { + case USB_PID_DW2102: + dw2102_op_rw + (dev, 0xbf, 0x0040, &reset, 0, + DW2102_WRITE_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); + break; + case 0x2101: + dw2102_op_rw + (dev, 0xbc, 0x0030, &reset16[0], 2, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xba, 0x0000, &reset16[0], 7, + DW2102_READ_MSG); + dw2102_op_rw + (dev, 0xb9, 0x0000, &reset16[0], 2, + DW2102_READ_MSG); + break; + } + kfree(p); + } + return ret; +} + +static struct dvb_usb_device_properties dw2102_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = DEVICE_SPECIFIC, + .firmware = "dvb-usb-dw2102.fw", + .size_of_priv = sizeof(struct dw2102_state), + .no_reconnect = 1, + + .i2c_algo = &dw2102_i2c_algo, + .rc_key_map = dw2102_rc_keys, + .rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys), + .rc_interval = 150, + .rc_query = dw2102_rc_query, + + .generic_bulk_ctrl_endpoint = 0x81, + /* parameter for the MPEG2-data transfer */ + .num_adapters = 1, + .download_firmware = dw2102_load_firmware, + .adapter = { + { + .frontend_attach = dw2102_frontend_attach, + .streaming_ctrl = NULL, + .tuner_attach = dw2102_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + } + }, + .num_device_descs = 2, + .devices = { + {"DVBWorld DVB-S 2102 USB2.0", + {&dw2102_table[0], NULL}, + {NULL}, + }, + {"DVBWorld DVB-S 2101 USB2.0", + {&dw2102_table[1], NULL}, + {NULL}, + }, + } +}; + +static int dw2102_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return dvb_usb_device_init(intf, &dw2102_properties, + THIS_MODULE, NULL, adapter_nr); +} + +static struct usb_driver dw2102_driver = { + .name = "dw2102", + .probe = dw2102_probe, + .disconnect = dvb_usb_device_exit, + .id_table = dw2102_table, +}; + +static int __init dw2102_module_init(void) +{ + int ret = usb_register(&dw2102_driver); + if (ret) + err("usb_register failed. Error number %d", ret); + + return ret; +} + +static void __exit dw2102_module_exit(void) +{ + usb_deregister(&dw2102_driver); +} + +module_init(dw2102_module_init); +module_exit(dw2102_module_exit); + +MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); +MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device"); +MODULE_VERSION("0.1"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h new file mode 100644 index 000000000000..cb5873752e46 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/dw2102.h @@ -0,0 +1,9 @@ +#ifndef _DW2102_H_ +#define _DW2102_H_ + +#define DVB_USB_LOG_PREFIX "dw2102" +#include + +extern int dvb_usb_dw2102_debug; +#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) +#endif diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h new file mode 100644 index 000000000000..b5ca9e754218 --- /dev/null +++ b/drivers/media/dvb/frontends/z0194a.h @@ -0,0 +1,97 @@ +/* z0194a.h Sharp z0194a tuner support +* +* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation, version 2. +* +* see Documentation/dvb/README.dvb-usb for more information +*/ + +#ifndef Z0194A +#define Z0194A + +static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe, + u32 srate, u32 ratio) +{ + u8 aclk = 0; + u8 bclk = 0; + + if (srate < 1500000) { + aclk = 0xb7; bclk = 0x47; } + else if (srate < 3000000) { + aclk = 0xb7; bclk = 0x4b; } + else if (srate < 7000000) { + aclk = 0xb7; bclk = 0x4f; } + else if (srate < 14000000) { + aclk = 0xb7; bclk = 0x53; } + else if (srate < 30000000) { + aclk = 0xb6; bclk = 0x53; } + else if (srate < 45000000) { + aclk = 0xb4; bclk = 0x51; } + + stv0299_writereg(fe, 0x13, aclk); + stv0299_writereg(fe, 0x14, bclk); + stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); + stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); + stv0299_writereg(fe, 0x21, (ratio) & 0xf0); + + return 0; +} + +static u8 sharp_z0194a__inittab[] = { + 0x01, 0x15, + 0x02, 0x00, + 0x03, 0x00, + 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ + 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ + 0x06, 0x40, /* DAC not used, set to high impendance mode */ + 0x07, 0x00, /* DAC LSB */ + 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ + 0x09, 0x00, /* FIFO */ + 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ + 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ + 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ + 0x10, 0x3f, /* AGC2 0x3d */ + 0x11, 0x84, + 0x12, 0xb9, + 0x15, 0xc9, /* lock detector threshold */ + 0x16, 0x00, + 0x17, 0x00, + 0x18, 0x00, + 0x19, 0x00, + 0x1a, 0x00, + 0x1f, 0x50, + 0x20, 0x00, + 0x21, 0x00, + 0x22, 0x00, + 0x23, 0x00, + 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */ + 0x29, 0x1e, /* 1/2 threshold */ + 0x2a, 0x14, /* 2/3 threshold */ + 0x2b, 0x0f, /* 3/4 threshold */ + 0x2c, 0x09, /* 5/6 threshold */ + 0x2d, 0x05, /* 7/8 threshold */ + 0x2e, 0x01, + 0x31, 0x1f, /* test all FECs */ + 0x32, 0x19, /* viterbi and synchro search */ + 0x33, 0xfc, /* rs control */ + 0x34, 0x93, /* error control */ + 0x0f, 0x52, + 0xff, 0xff +}; + +static struct stv0299_config sharp_z0194a_config = { + .demod_address = 0x68, + .inittab = sharp_z0194a__inittab, + .mclk = 88000000UL, + .invert = 1, + .skip_reinit = 0, + .lock_output = STV0229_LOCKOUTPUT_1, + .volt13_op0_op1 = STV0299_VOLT13_OP1, + .min_delay_ms = 100, + .set_symbol_rate = sharp_z0194a__set_symbol_rate, +}; + +#endif -- cgit v1.2.3 From bcf4562ecbc35dabacc562fdf6c92218ca59ca94 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 18 Jul 2008 20:14:31 -0300 Subject: V4L/DVB (8422): cs5345: fix incorrect mask with VIDIOC_DBG_S_REGISTER Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cs5345.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c index 1c3fa3a7470a..61d14d26686f 100644 --- a/drivers/media/video/cs5345.c +++ b/drivers/media/video/cs5345.c @@ -111,7 +111,7 @@ static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg) if (cmd == VIDIOC_DBG_G_REGISTER) reg->val = cs5345_read(client, reg->reg & 0x1f); else - cs5345_write(client, reg->reg & 0x1f, reg->val & 0x1f); + cs5345_write(client, reg->reg & 0x1f, reg->val & 0xff); break; } #endif -- cgit v1.2.3 From 82fc52a886aaff8a1605f9d16240e74ddac8570c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 19 Jul 2008 08:34:12 -0300 Subject: V4L/DVB (8423): cx18: remove firmware size check This check was an ivtv leftover that served no purpose for the cx18. Removed it, as this allows the user to load different firmware versions. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-firmware.c | 54 ++++++++------------------------ 1 file changed, 13 insertions(+), 41 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 2d630d9f7496..78fadd2ada5d 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -86,10 +86,6 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C -/* Encoder/decoder firmware sizes */ -#define CX18_FW_CPU_SIZE (158332) -#define CX18_FW_APU_SIZE (141200) - #define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ #define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ @@ -100,35 +96,22 @@ struct cx18_apu_rom_seghdr { u32 size; }; -static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx, long size) +static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) { const struct firmware *fw = NULL; - int retries = 3; int i, j; + unsigned size; u32 __iomem *dst = (u32 __iomem *)mem; const u32 *src; -retry: - if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("Unable to open firmware %s (must be %ld bytes)\n", - fn, size); + if (request_firmware(&fw, fn, &cx->dev->dev)) { + CX18_ERR("Unable to open firmware %s\n", fn); CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } src = (const u32 *)fw->data; - if (fw->size != size) { - /* Due to race conditions in firmware loading (esp. with - udev <0.95) the wrong file was sometimes loaded. So we check - filesizes to see if at least the right-sized file was - loaded. If not, then we retry. */ - CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", - fn, size, fw->size); - release_firmware(fw); - retries--; - goto retry; - } for (i = 0; i < fw->size; i += 4096) { setup_page(i); for (j = i; j < fw->size && j < i + 4096; j += 4) { @@ -145,15 +128,16 @@ retry: } if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); + size = fw->size; release_firmware(fw); return size; } -static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, long size) +static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx) { const struct firmware *fw = NULL; - int retries = 3; int i, j; + unsigned size; const u32 *src; struct cx18_apu_rom_seghdr seghdr; const u8 *vers; @@ -161,10 +145,8 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, u32 apu_version = 0; int sz; -retry: - if (!retries || request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("unable to open firmware %s (must be %ld bytes)\n", - fn, size); + if (request_firmware(&fw, fn, &cx->dev->dev)) { + CX18_ERR("unable to open firmware %s\n", fn); CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); return -ENOMEM; } @@ -173,19 +155,8 @@ retry: vers = fw->data + sizeof(seghdr); sz = fw->size; - if (fw->size != size) { - /* Due to race conditions in firmware loading (esp. with - udev <0.95) the wrong file was sometimes loaded. So we check - filesizes to see if at least the right-sized file was - loaded. If not, then we retry. */ - CX18_INFO("retry: file loaded was not %s (expected size %ld, got %zd)\n", - fn, size, fw->size); - release_firmware(fw); - retries--; - goto retry; - } apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; - while (offset + sizeof(seghdr) < size) { + while (offset + sizeof(seghdr) < fw->size) { /* TODO: byteswapping */ memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); offset += sizeof(seghdr); @@ -215,6 +186,7 @@ retry: if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", fn, apu_version, fw->size); + size = fw->size; release_firmware(fw); /* Clear bit0 for APU to start from 0 */ write_reg(read_reg(0xc72030) & ~1, 0xc72030); @@ -340,7 +312,7 @@ int cx18_firmware_init(struct cx18 *cx) /* Only if the processor is not running */ if (read_reg(CX18_PROC_SOFT_RESET) & 8) { int sz = load_apu_fw_direct("v4l-cx23418-apu.fw", - cx->enc_mem, cx, CX18_FW_APU_SIZE); + cx->enc_mem, cx); write_enc(0xE51FF004, 0); write_enc(0xa00000, 4); /* todo: not hardcoded */ @@ -348,7 +320,7 @@ int cx18_firmware_init(struct cx18 *cx) cx18_msleep_timeout(500, 0); sz = sz <= 0 ? sz : load_cpu_fw_direct("v4l-cx23418-cpu.fw", - cx->enc_mem, cx, CX18_FW_CPU_SIZE); + cx->enc_mem, cx); if (sz > 0) { int retries = 0; -- cgit v1.2.3 From c60f2b5c1defb6b1345968e1c65c2008c221d57d Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 17 Jul 2008 17:30:47 -0300 Subject: V4L/DVB (8425): v4l: fix checkpatch errors introduced by recent commits Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/sh_mobile_ceu_camera.c | 1 + drivers/media/video/videobuf-dma-contig.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 012005e1a77b..f7ca3cb9340a 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -91,6 +91,7 @@ struct sh_mobile_ceu_dev { void __iomem *base; unsigned long video_limit; + /* lock used to protect videobuf */ spinlock_t lock; struct list_head capture; struct videobuf_buffer *active; diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 03f20acb668c..31944b11e6ea 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c @@ -28,10 +28,10 @@ struct videobuf_dma_contig_memory { }; #define MAGIC_DC_MEM 0x0733ac61 -#define MAGIC_CHECK(is, should) \ - if (unlikely((is) != (should))) { \ - pr_err("magic mismatch: %x expected %x\n", is, should); \ - BUG(); \ +#define MAGIC_CHECK(is, should) \ + if (unlikely((is) != (should))) { \ + pr_err("magic mismatch: %x expected %x\n", (is), (should)); \ + BUG(); \ } static void -- cgit v1.2.3 From 27a5e6d3fcce73ceeee8f3bdc9a30c4564233800 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Jul 2008 08:43:17 -0300 Subject: V4L/DVB (8427): videodev: split off the ioctl handling into v4l2-ioctl.c videodev.c became top-heavy so all the ioctl processing has been split off into v4l2-ioctl.c. This means videodev.c is back to its original purpose: creating and registering v4l devices. Since videodev.c and v4l2-ioctl.c should still remain one module (as least for now) I also had to rename videodev.c to v4l2-dev.c to prevent a circular dependency when building a videodev.ko module. This is not a bad thing, since the source and header now have the same name. And the v4l2- prefix is useful to see which sources are generic v4l2 support code. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Makefile | 2 + drivers/media/video/v4l2-dev.c | 424 ++++++++ drivers/media/video/videodev.c | 2262 ---------------------------------------- 3 files changed, 426 insertions(+), 2262 deletions(-) create mode 100644 drivers/media/video/v4l2-dev.c (limited to 'drivers/media') diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 45d5db5abb1e..9de1e4885246 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -10,6 +10,8 @@ msp3400-objs := msp3400-driver.o msp3400-kthreads.o stkwebcam-objs := stk-webcam.o stk-sensor.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o + obj-$(CONFIG_VIDEO_DEV) += videodev.o compat_ioctl32.o v4l2-int-device.o obj-$(CONFIG_VIDEO_V4L2_COMMON) += v4l2-common.o diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c new file mode 100644 index 000000000000..2dd82b16bc35 --- /dev/null +++ b/drivers/media/video/v4l2-dev.c @@ -0,0 +1,424 @@ +/* + * Video capture interface for Linux version 2 + * + * A generic video device interface for the LINUX operating system + * using a set of device structures/vectors for low level operations. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Alan Cox, (version 1) + * Mauro Carvalho Chehab (version 2) + * + * Fixes: 20000516 Claudio Matsuoka + * - Added procfs support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define VIDEO_NUM_DEVICES 256 +#define VIDEO_NAME "video4linux" + +/* + * sysfs stuff + */ + +static ssize_t show_index(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + return sprintf(buf, "%i\n", vfd->index); +} + +static ssize_t show_name(struct device *cd, + struct device_attribute *attr, char *buf) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); +} + +static struct device_attribute video_device_attrs[] = { + __ATTR(name, S_IRUGO, show_name, NULL), + __ATTR(index, S_IRUGO, show_index, NULL), + __ATTR_NULL +}; + +struct video_device *video_device_alloc(void) +{ + struct video_device *vfd; + + vfd = kzalloc(sizeof(*vfd), GFP_KERNEL); + return vfd; +} +EXPORT_SYMBOL(video_device_alloc); + +void video_device_release(struct video_device *vfd) +{ + kfree(vfd); +} +EXPORT_SYMBOL(video_device_release); + +static void video_release(struct device *cd) +{ + struct video_device *vfd = container_of(cd, struct video_device, + class_dev); + +#if 1 + /* needed until all drivers are fixed */ + if (!vfd->release) + return; +#endif + vfd->release(vfd); +} + +static struct class video_class = { + .name = VIDEO_NAME, + .dev_attrs = video_device_attrs, + .dev_release = video_release, +}; + +/* + * Active devices + */ + +static struct video_device *video_device[VIDEO_NUM_DEVICES]; +static DEFINE_MUTEX(videodev_lock); + +struct video_device *video_devdata(struct file *file) +{ + return video_device[iminor(file->f_path.dentry->d_inode)]; +} +EXPORT_SYMBOL(video_devdata); + +/* + * Open a video device - FIXME: Obsoleted + */ +static int video_open(struct inode *inode, struct file *file) +{ + unsigned int minor = iminor(inode); + int err = 0; + struct video_device *vfl; + const struct file_operations *old_fops; + + if (minor >= VIDEO_NUM_DEVICES) + return -ENODEV; + lock_kernel(); + mutex_lock(&videodev_lock); + vfl = video_device[minor]; + if (vfl == NULL) { + mutex_unlock(&videodev_lock); + request_module("char-major-%d-%d", VIDEO_MAJOR, minor); + mutex_lock(&videodev_lock); + vfl = video_device[minor]; + if (vfl == NULL) { + mutex_unlock(&videodev_lock); + unlock_kernel(); + return -ENODEV; + } + } + old_fops = file->f_op; + file->f_op = fops_get(vfl->fops); + if (file->f_op->open) + err = file->f_op->open(inode, file); + if (err) { + fops_put(file->f_op); + file->f_op = fops_get(old_fops); + } + fops_put(old_fops); + mutex_unlock(&videodev_lock); + unlock_kernel(); + return err; +} + +/* + * open/release helper functions -- handle exclusive opens + * Should be removed soon + */ +int video_exclusive_open(struct inode *inode, struct file *file) +{ + struct video_device *vfl = video_devdata(file); + int retval = 0; + + mutex_lock(&vfl->lock); + if (vfl->users) + retval = -EBUSY; + else + vfl->users++; + mutex_unlock(&vfl->lock); + return retval; +} +EXPORT_SYMBOL(video_exclusive_open); + +int video_exclusive_release(struct inode *inode, struct file *file) +{ + struct video_device *vfl = video_devdata(file); + + vfl->users--; + return 0; +} +EXPORT_SYMBOL(video_exclusive_release); + +/** + * get_index - assign stream number based on parent device + * @vdev: video_device to assign index number to, vdev->dev should be assigned + * @num: -1 if auto assign, requested number otherwise + * + * + * returns -ENFILE if num is already in use, a free index number if + * successful. + */ +static int get_index(struct video_device *vdev, int num) +{ + u32 used = 0; + const int max_index = sizeof(used) * 8 - 1; + int i; + + /* Currently a single v4l driver instance cannot create more than + 32 devices. + Increase to u64 or an array of u32 if more are needed. */ + if (num > max_index) { + printk(KERN_ERR "videodev: %s num is too large\n", __func__); + return -EINVAL; + } + + for (i = 0; i < VIDEO_NUM_DEVICES; i++) { + if (video_device[i] != NULL && + video_device[i] != vdev && + video_device[i]->dev == vdev->dev) { + used |= 1 << video_device[i]->index; + } + } + + if (num >= 0) { + if (used & (1 << num)) + return -ENFILE; + return num; + } + + i = ffz(used); + return i > max_index ? -ENFILE : i; +} + +static const struct file_operations video_fops; + +int video_register_device(struct video_device *vfd, int type, int nr) +{ + return video_register_device_index(vfd, type, nr, -1); +} +EXPORT_SYMBOL(video_register_device); + +/** + * video_register_device - register video4linux devices + * @vfd: video device structure we want to register + * @type: type of device to register + * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... + * -1 == first free) + * + * The registration code assigns minor numbers based on the type + * requested. -ENFILE is returned in all the device slots for this + * category are full. If not then the minor field is set and the + * driver initialize function is called (if non %NULL). + * + * Zero is returned on success. + * + * Valid types are + * + * %VFL_TYPE_GRABBER - A frame grabber + * + * %VFL_TYPE_VTX - A teletext device + * + * %VFL_TYPE_VBI - Vertical blank data (undecoded) + * + * %VFL_TYPE_RADIO - A radio card + */ + +int video_register_device_index(struct video_device *vfd, int type, int nr, + int index) +{ + int i = 0; + int base; + int end; + int ret; + char *name_base; + + switch (type) { + case VFL_TYPE_GRABBER: + base = MINOR_VFL_TYPE_GRABBER_MIN; + end = MINOR_VFL_TYPE_GRABBER_MAX+1; + name_base = "video"; + break; + case VFL_TYPE_VTX: + base = MINOR_VFL_TYPE_VTX_MIN; + end = MINOR_VFL_TYPE_VTX_MAX+1; + name_base = "vtx"; + break; + case VFL_TYPE_VBI: + base = MINOR_VFL_TYPE_VBI_MIN; + end = MINOR_VFL_TYPE_VBI_MAX+1; + name_base = "vbi"; + break; + case VFL_TYPE_RADIO: + base = MINOR_VFL_TYPE_RADIO_MIN; + end = MINOR_VFL_TYPE_RADIO_MAX+1; + name_base = "radio"; + break; + default: + printk(KERN_ERR "%s called with unknown type: %d\n", + __func__, type); + return -1; + } + + /* pick a minor number */ + mutex_lock(&videodev_lock); + if (nr >= 0 && nr < end-base) { + /* use the one the driver asked for */ + i = base + nr; + if (NULL != video_device[i]) { + mutex_unlock(&videodev_lock); + return -ENFILE; + } + } else { + /* use first free */ + for (i = base; i < end; i++) + if (NULL == video_device[i]) + break; + if (i == end) { + mutex_unlock(&videodev_lock); + return -ENFILE; + } + } + video_device[i] = vfd; + vfd->minor = i; + + ret = get_index(vfd, index); + vfd->index = ret; + + mutex_unlock(&videodev_lock); + + if (ret < 0) { + printk(KERN_ERR "%s: get_index failed\n", __func__); + goto fail_minor; + } + + mutex_init(&vfd->lock); + + /* sysfs class */ + memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); + vfd->class_dev.class = &video_class; + vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); + if (vfd->dev) + vfd->class_dev.parent = vfd->dev; + sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); + ret = device_register(&vfd->class_dev); + if (ret < 0) { + printk(KERN_ERR "%s: device_register failed\n", __func__); + goto fail_minor; + } + +#if 1 + /* needed until all drivers are fixed */ + if (!vfd->release) + printk(KERN_WARNING "videodev: \"%s\" has no release callback. " + "Please fix your driver for proper sysfs support, see " + "http://lwn.net/Articles/36850/\n", vfd->name); +#endif + return 0; + +fail_minor: + mutex_lock(&videodev_lock); + video_device[vfd->minor] = NULL; + vfd->minor = -1; + mutex_unlock(&videodev_lock); + return ret; +} +EXPORT_SYMBOL(video_register_device_index); + +/** + * video_unregister_device - unregister a video4linux device + * @vfd: the device to unregister + * + * This unregisters the passed device and deassigns the minor + * number. Future open calls will be met with errors. + */ + +void video_unregister_device(struct video_device *vfd) +{ + mutex_lock(&videodev_lock); + if (video_device[vfd->minor] != vfd) + panic("videodev: bad unregister"); + + video_device[vfd->minor] = NULL; + device_unregister(&vfd->class_dev); + mutex_unlock(&videodev_lock); +} +EXPORT_SYMBOL(video_unregister_device); + +/* + * Video fs operations + */ +static const struct file_operations video_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = video_open, +}; + +/* + * Initialise video for linux + */ + +static int __init videodev_init(void) +{ + int ret; + + printk(KERN_INFO "Linux video capture interface: v2.00\n"); + if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { + printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); + return -EIO; + } + + ret = class_register(&video_class); + if (ret < 0) { + unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); + printk(KERN_WARNING "video_dev: class_register failed\n"); + return -EIO; + } + + return 0; +} + +static void __exit videodev_exit(void) +{ + class_unregister(&video_class); + unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); +} + +module_init(videodev_init) +module_exit(videodev_exit) + +MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); +MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); +MODULE_LICENSE("GPL"); + + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c index 6616e6570557..e69de29bb2d1 100644 --- a/drivers/media/video/videodev.c +++ b/drivers/media/video/videodev.c @@ -1,2262 +0,0 @@ -/* - * Video capture interface for Linux version 2 - * - * A generic video device interface for the LINUX operating system - * using a set of device structures/vectors for low level operations. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Authors: Alan Cox, (version 1) - * Mauro Carvalho Chehab (version 2) - * - * Fixes: 20000516 Claudio Matsuoka - * - Added procfs support - */ - -#define dbgarg(cmd, fmt, arg...) \ - do { \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ - printk(KERN_DEBUG "%s: ", vfd->name); \ - v4l_printk_ioctl(cmd); \ - printk(" " fmt, ## arg); \ - } \ - } while (0) - -#define dbgarg2(fmt, arg...) \ - do { \ - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ - printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ - } while (0) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define __OLD_VIDIOC_ /* To allow fixing old calls*/ -#include - -#ifdef CONFIG_VIDEO_V4L1 -#include -#endif -#include -#include - -#define VIDEO_NUM_DEVICES 256 -#define VIDEO_NAME "video4linux" - -struct std_descr { - v4l2_std_id std; - const char *descr; -}; - -static const struct std_descr standards[] = { - { V4L2_STD_NTSC, "NTSC" }, - { V4L2_STD_NTSC_M, "NTSC-M" }, - { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, - { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, - { V4L2_STD_NTSC_443, "NTSC-443" }, - { V4L2_STD_PAL, "PAL" }, - { V4L2_STD_PAL_BG, "PAL-BG" }, - { V4L2_STD_PAL_B, "PAL-B" }, - { V4L2_STD_PAL_B1, "PAL-B1" }, - { V4L2_STD_PAL_G, "PAL-G" }, - { V4L2_STD_PAL_H, "PAL-H" }, - { V4L2_STD_PAL_I, "PAL-I" }, - { V4L2_STD_PAL_DK, "PAL-DK" }, - { V4L2_STD_PAL_D, "PAL-D" }, - { V4L2_STD_PAL_D1, "PAL-D1" }, - { V4L2_STD_PAL_K, "PAL-K" }, - { V4L2_STD_PAL_M, "PAL-M" }, - { V4L2_STD_PAL_N, "PAL-N" }, - { V4L2_STD_PAL_Nc, "PAL-Nc" }, - { V4L2_STD_PAL_60, "PAL-60" }, - { V4L2_STD_SECAM, "SECAM" }, - { V4L2_STD_SECAM_B, "SECAM-B" }, - { V4L2_STD_SECAM_G, "SECAM-G" }, - { V4L2_STD_SECAM_H, "SECAM-H" }, - { V4L2_STD_SECAM_DK, "SECAM-DK" }, - { V4L2_STD_SECAM_D, "SECAM-D" }, - { V4L2_STD_SECAM_K, "SECAM-K" }, - { V4L2_STD_SECAM_K1, "SECAM-K1" }, - { V4L2_STD_SECAM_L, "SECAM-L" }, - { V4L2_STD_SECAM_LC, "SECAM-Lc" }, - { 0, "Unknown" } -}; - -/* video4linux standard ID conversion to standard name - */ -const char *v4l2_norm_to_name(v4l2_std_id id) -{ - u32 myid = id; - int i; - - /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle - 64 bit comparations. So, on that architecture, with some gcc - variants, compilation fails. Currently, the max value is 30bit wide. - */ - BUG_ON(myid != id); - - for (i = 0; standards[i].std; i++) - if (myid == standards[i].std) - break; - return standards[i].descr; -} -EXPORT_SYMBOL(v4l2_norm_to_name); - -/* Fill in the fields of a v4l2_standard structure according to the - 'id' and 'transmission' parameters. Returns negative on error. */ -int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, const char *name) -{ - u32 index = vs->index; - - memset(vs, 0, sizeof(struct v4l2_standard)); - vs->index = index; - vs->id = id; - if (id & V4L2_STD_525_60) { - vs->frameperiod.numerator = 1001; - vs->frameperiod.denominator = 30000; - vs->framelines = 525; - } else { - vs->frameperiod.numerator = 1; - vs->frameperiod.denominator = 25; - vs->framelines = 625; - } - strlcpy(vs->name, name, sizeof(vs->name)); - return 0; -} -EXPORT_SYMBOL(v4l2_video_std_construct); - -/* ----------------------------------------------------------------- */ -/* some arrays for pretty-printing debug messages of enum types */ - -const char *v4l2_field_names[] = { - [V4L2_FIELD_ANY] = "any", - [V4L2_FIELD_NONE] = "none", - [V4L2_FIELD_TOP] = "top", - [V4L2_FIELD_BOTTOM] = "bottom", - [V4L2_FIELD_INTERLACED] = "interlaced", - [V4L2_FIELD_SEQ_TB] = "seq-tb", - [V4L2_FIELD_SEQ_BT] = "seq-bt", - [V4L2_FIELD_ALTERNATE] = "alternate", - [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", - [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", -}; -EXPORT_SYMBOL(v4l2_field_names); - -const char *v4l2_type_names[] = { - [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", - [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", - [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", - [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", - [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", - [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", - [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", - [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", -}; -EXPORT_SYMBOL(v4l2_type_names); - -static const char *v4l2_memory_names[] = { - [V4L2_MEMORY_MMAP] = "mmap", - [V4L2_MEMORY_USERPTR] = "userptr", - [V4L2_MEMORY_OVERLAY] = "overlay", -}; - -#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ - arr[a] : "unknown") - -/* ------------------------------------------------------------------ */ -/* debug help functions */ - -#ifdef CONFIG_VIDEO_V4L1_COMPAT -static const char *v4l1_ioctls[] = { - [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", - [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", - [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", - [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", - [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", - [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", - [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", - [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", - [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", - [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", - [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", - [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", - [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", - [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", - [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", - [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", - [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", - [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", - [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", - [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", - [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", - [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", - [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", - [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", - [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", - [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", - [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", - [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", - [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" -}; -#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) -#endif - -static const char *v4l2_ioctls[] = { - [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", - [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", - [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", - [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", - [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", - [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", - [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", - [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", - [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", - [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", - [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", - [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", - [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", - [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", - [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", - [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", - [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", - [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", - [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", - [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", - [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", - [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", - [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", - [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", - [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", - [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", - [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", - [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", - [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", - [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", - [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", - [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", - [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", - [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", - [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", - [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", - [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", - [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", - [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", - [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", - [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", - [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", - [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", - [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", - [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", - [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", - [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", - [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", - [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", - [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", - [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", - [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", - [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", - [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", -#if 1 - [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", - [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", - [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", - [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", - [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", - - [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", - [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", - - [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", - [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", -#endif -}; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -static const char *v4l2_int_ioctls[] = { -#ifdef CONFIG_VIDEO_V4L1_COMPAT - [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", - [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", - [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", - [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", - [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", - [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", - [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", - [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", - [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", - [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", - [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", -#endif - [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", - - [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", - [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", - [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", - - [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", - [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", - [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", - [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", - [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", - [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", - [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", - [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", - [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", - [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", - [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", -}; -#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) - -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl */ -void v4l_printk_ioctl(unsigned int cmd) -{ - char *dir, *type; - - switch (_IOC_TYPE(cmd)) { - case 'd': - if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { - type = "v4l2_int"; - break; - } - printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); - return; -#ifdef CONFIG_VIDEO_V4L1_COMPAT - case 'v': - if (_IOC_NR(cmd) >= V4L1_IOCTLS) { - type = "v4l1"; - break; - } - printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); - return; -#endif - case 'V': - if (_IOC_NR(cmd) >= V4L2_IOCTLS) { - type = "v4l2"; - break; - } - printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); - return; - default: - type = "unknown"; - } - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } - printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", - type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); -} -EXPORT_SYMBOL(v4l_printk_ioctl); - -/* - * sysfs stuff - */ - -static ssize_t show_index(struct device *cd, - struct device_attribute *attr, char *buf) -{ - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); - return sprintf(buf, "%i\n", vfd->index); -} - -static ssize_t show_name(struct device *cd, - struct device_attribute *attr, char *buf) -{ - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); - return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); -} - -static struct device_attribute video_device_attrs[] = { - __ATTR(name, S_IRUGO, show_name, NULL), - __ATTR(index, S_IRUGO, show_index, NULL), - __ATTR_NULL -}; - -struct video_device *video_device_alloc(void) -{ - struct video_device *vfd; - - vfd = kzalloc(sizeof(*vfd),GFP_KERNEL); - return vfd; -} -EXPORT_SYMBOL(video_device_alloc); - -void video_device_release(struct video_device *vfd) -{ - kfree(vfd); -} -EXPORT_SYMBOL(video_device_release); - -static void video_release(struct device *cd) -{ - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); - -#if 1 - /* needed until all drivers are fixed */ - if (!vfd->release) - return; -#endif - vfd->release(vfd); -} - -static struct class video_class = { - .name = VIDEO_NAME, - .dev_attrs = video_device_attrs, - .dev_release = video_release, -}; - -/* - * Active devices - */ - -static struct video_device *video_device[VIDEO_NUM_DEVICES]; -static DEFINE_MUTEX(videodev_lock); - -struct video_device* video_devdata(struct file *file) -{ - return video_device[iminor(file->f_path.dentry->d_inode)]; -} -EXPORT_SYMBOL(video_devdata); - -/* - * Open a video device - FIXME: Obsoleted - */ -static int video_open(struct inode *inode, struct file *file) -{ - unsigned int minor = iminor(inode); - int err = 0; - struct video_device *vfl; - const struct file_operations *old_fops; - - if(minor>=VIDEO_NUM_DEVICES) - return -ENODEV; - lock_kernel(); - mutex_lock(&videodev_lock); - vfl=video_device[minor]; - if(vfl==NULL) { - mutex_unlock(&videodev_lock); - request_module("char-major-%d-%d", VIDEO_MAJOR, minor); - mutex_lock(&videodev_lock); - vfl=video_device[minor]; - if (vfl==NULL) { - mutex_unlock(&videodev_lock); - unlock_kernel(); - return -ENODEV; - } - } - old_fops = file->f_op; - file->f_op = fops_get(vfl->fops); - if(file->f_op->open) - err = file->f_op->open(inode,file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); - mutex_unlock(&videodev_lock); - unlock_kernel(); - return err; -} - -/* - * helper function -- handles userspace copying for ioctl arguments - */ - -#ifdef __OLD_VIDIOC_ -static unsigned int -video_fix_command(unsigned int cmd) -{ - switch (cmd) { - case VIDIOC_OVERLAY_OLD: - cmd = VIDIOC_OVERLAY; - break; - case VIDIOC_S_PARM_OLD: - cmd = VIDIOC_S_PARM; - break; - case VIDIOC_S_CTRL_OLD: - cmd = VIDIOC_S_CTRL; - break; - case VIDIOC_G_AUDIO_OLD: - cmd = VIDIOC_G_AUDIO; - break; - case VIDIOC_G_AUDOUT_OLD: - cmd = VIDIOC_G_AUDOUT; - break; - case VIDIOC_CROPCAP_OLD: - cmd = VIDIOC_CROPCAP; - break; - } - return cmd; -} -#endif - -/* - * Obsolete usercopy function - Should be removed soon - */ -int -video_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - int is_ext_ctrl; - size_t ctrls_size = 0; - void __user *user_ptr = NULL; - -#ifdef __OLD_VIDIOC_ - cmd = video_fix_command(cmd); -#endif - is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || - cmd == VIDIOC_TRY_EXT_CTRLS); - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - parg = NULL; - break; - case _IOC_READ: - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (_IOC_DIR(cmd) & _IOC_WRITE) - if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) - goto out; - break; - } - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - /* In case of an error, tell the caller that it wasn't - a specific control that caused it. */ - p->error_idx = p->count; - user_ptr = (void __user *)p->controls; - if (p->count) { - ctrls_size = sizeof(struct v4l2_ext_control) * p->count; - /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ - mbuf = kmalloc(ctrls_size, GFP_KERNEL); - err = -ENOMEM; - if (NULL == mbuf) - goto out_ext_ctrl; - err = -EFAULT; - if (copy_from_user(mbuf, user_ptr, ctrls_size)) - goto out_ext_ctrl; - p->controls = mbuf; - } - } - - /* call driver */ - err = func(inode, file, cmd, parg); - if (err == -ENOIOCTLCMD) - err = -EINVAL; - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - p->controls = (void *)user_ptr; - if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) - err = -EFAULT; - goto out_ext_ctrl; - } - if (err < 0) - goto out; - -out_ext_ctrl: - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - kfree(mbuf); - return err; -} -EXPORT_SYMBOL(video_usercopy); - -/* - * open/release helper functions -- handle exclusive opens - * Should be removed soon - */ -int video_exclusive_open(struct inode *inode, struct file *file) -{ - struct video_device *vfl = video_devdata(file); - int retval = 0; - - mutex_lock(&vfl->lock); - if (vfl->users) { - retval = -EBUSY; - } else { - vfl->users++; - } - mutex_unlock(&vfl->lock); - return retval; -} -EXPORT_SYMBOL(video_exclusive_open); - -int video_exclusive_release(struct inode *inode, struct file *file) -{ - struct video_device *vfl = video_devdata(file); - - vfl->users--; - return 0; -} -EXPORT_SYMBOL(video_exclusive_release); - -static void dbgbuf(unsigned int cmd, struct video_device *vfd, - struct v4l2_buffer *p) -{ - struct v4l2_timecode *tc=&p->timecode; - - dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " - "bytesused=%d, flags=0x%08d, " - "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n", - (p->timestamp.tv_sec/3600), - (int)(p->timestamp.tv_sec/60)%60, - (int)(p->timestamp.tv_sec%60), - p->timestamp.tv_usec, - p->index, - prt_names(p->type, v4l2_type_names), - p->bytesused, p->flags, - p->field, p->sequence, - prt_names(p->memory, v4l2_memory_names), - p->m.userptr, p->length); - dbgarg2("timecode=%02d:%02d:%02d type=%d, " - "flags=0x%08d, frames=%d, userbits=0x%08x\n", - tc->hours,tc->minutes,tc->seconds, - tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits); -} - -static inline void dbgrect(struct video_device *vfd, char *s, - struct v4l2_rect *r) -{ - dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, - r->width, r->height); -}; - -static inline void v4l_print_pix_fmt (struct video_device *vfd, - struct v4l2_pix_format *fmt) -{ - dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, " - "bytesperline=%d sizeimage=%d, colorspace=%d\n", - fmt->width,fmt->height, - (fmt->pixelformat & 0xff), - (fmt->pixelformat >> 8) & 0xff, - (fmt->pixelformat >> 16) & 0xff, - (fmt->pixelformat >> 24) & 0xff, - prt_names(fmt->field, v4l2_field_names), - fmt->bytesperline, fmt->sizeimage, fmt->colorspace); -}; - -static inline void v4l_print_ext_ctrls(unsigned int cmd, - struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) -{ - __u32 i; - - if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) - return; - dbgarg(cmd, ""); - printk(KERN_CONT "class=0x%x", c->ctrl_class); - for (i = 0; i < c->count; i++) { - if (show_vals) - printk(KERN_CONT " id/val=0x%x/0x%x", - c->controls[i].id, c->controls[i].value); - else - printk(KERN_CONT " id=0x%x", c->controls[i].id); - } - printk(KERN_CONT "\n"); -}; - -static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) -{ - __u32 i; - - /* zero the reserved fields */ - c->reserved[0] = c->reserved[1] = 0; - for (i = 0; i < c->count; i++) { - c->controls[i].reserved2[0] = 0; - c->controls[i].reserved2[1] = 0; - } - /* V4L2_CID_PRIVATE_BASE cannot be used as control class - when using extended controls. - Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL - is it allowed for backwards compatibility. - */ - if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) - return 0; - /* Check that all controls are from the same control class. */ - for (i = 0; i < c->count; i++) { - if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { - c->error_idx = i; - return 0; - } - } - return 1; -} - -static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) - return (0); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) - return (0); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) - return (0); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) - return (0); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) - return (0); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) - return (0); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) - return (0); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) - return (0); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - return (0); - break; - } - return (-EINVAL); -} - -static int __video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vfd = video_devdata(file); - void *fh = file->private_data; - int ret = -EINVAL; - - if ( (vfd->debug & V4L2_DEBUG_IOCTL) && - !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { - v4l_print_ioctl(vfd->name, cmd); - printk("\n"); - } - -#ifdef CONFIG_VIDEO_V4L1_COMPAT - /*********************************************************** - Handles calls to the obsoleted V4L1 API - Due to the nature of VIDIOCGMBUF, each driver that supports - V4L1 should implement its own handler for this ioctl. - ***********************************************************/ - - /* --- streaming capture ------------------------------------- */ - if (cmd == VIDIOCGMBUF) { - struct video_mbuf *p=arg; - - memset(p, 0, sizeof(*p)); - - if (!vfd->vidiocgmbuf) - return ret; - ret=vfd->vidiocgmbuf(file, fh, p); - if (!ret) - dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", - p->size, p->frames, - (unsigned long)p->offsets); - return ret; - } - - /******************************************************** - All other V4L1 calls are handled by v4l1_compat module. - Those calls will be translated into V4L2 calls, and - __video_do_ioctl will be called again, with one or more - V4L2 ioctls. - ********************************************************/ - if (_IOC_TYPE(cmd)=='v') - return v4l_compat_translate_ioctl(inode,file,cmd,arg, - __video_do_ioctl); -#endif - - switch(cmd) { - /* --- capabilities ------------------------------------------ */ - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = (struct v4l2_capability*)arg; - memset(cap, 0, sizeof(*cap)); - - if (!vfd->vidioc_querycap) - break; - - ret=vfd->vidioc_querycap(file, fh, cap); - if (!ret) - dbgarg (cmd, "driver=%s, card=%s, bus=%s, " - "version=0x%08x, " - "capabilities=0x%08x\n", - cap->driver,cap->card,cap->bus_info, - cap->version, - cap->capabilities); - break; - } - - /* --- priority ------------------------------------------ */ - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p=arg; - - if (!vfd->vidioc_g_priority) - break; - ret=vfd->vidioc_g_priority(file, fh, p); - if (!ret) - dbgarg(cmd, "priority is %d\n", *p); - break; - } - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *p=arg; - - if (!vfd->vidioc_s_priority) - break; - dbgarg(cmd, "setting priority to %d\n", *p); - ret=vfd->vidioc_s_priority(file, fh, *p); - break; - } - - /* --- capture ioctls ---------------------------------------- */ - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *f = arg; - enum v4l2_buf_type type; - unsigned int index; - - index = f->index; - type = f->type; - memset(f,0,sizeof(*f)); - f->index = index; - f->type = type; - - switch (type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_enum_fmt_vid_cap) - ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_enum_fmt_vid_overlay) - ret = vfd->vidioc_enum_fmt_vid_overlay(file, - fh, f); - break; -#if 1 - /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT - * according to the spec. The bttv and saa7134 drivers support - * it though, so just warn that this is deprecated and will be - * removed in the near future. */ - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi_cap) { - printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); - ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); - } - break; -#endif - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_enum_fmt_vid_out) - ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_enum_fmt_type_private) - ret = vfd->vidioc_enum_fmt_type_private(file, - fh, f); - break; - default: - break; - } - if (!ret) - dbgarg (cmd, "index=%d, type=%d, flags=%d, " - "pixelformat=%c%c%c%c, description='%s'\n", - f->index, f->type, f->flags, - (f->pixelformat & 0xff), - (f->pixelformat >> 8) & 0xff, - (f->pixelformat >> 16) & 0xff, - (f->pixelformat >> 24) & 0xff, - f->description); - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); - - /* FIXME: Should be one dump per type */ - dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_g_fmt_vid_cap) - ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd, &f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_g_fmt_vid_overlay) - ret = vfd->vidioc_g_fmt_vid_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_g_fmt_vid_out) - ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd, &f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_g_fmt_vid_out_overlay) - ret = vfd->vidioc_g_fmt_vid_out_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi_cap) - ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_out) - ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_sliced_vbi_cap) - ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_sliced_vbi_out) - ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_g_fmt_type_private) - ret = vfd->vidioc_g_fmt_type_private(file, - fh, f); - break; - } - - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - /* FIXME: Should be one dump per type */ - dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); - - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_cap) - ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_s_fmt_vid_overlay) - ret = vfd->vidioc_s_fmt_vid_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_out) - ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_s_fmt_vid_out_overlay) - ret = vfd->vidioc_s_fmt_vid_out_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi_cap) - ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_out) - ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_sliced_vbi_cap) - ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_sliced_vbi_out) - ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_s_fmt_type_private) - ret = vfd->vidioc_s_fmt_type_private(file, - fh, f); - break; - } - break; - } - case VIDIOC_TRY_FMT: - { - struct v4l2_format *f = (struct v4l2_format *)arg; - - /* FIXME: Should be one dump per type */ - dbgarg (cmd, "type=%s\n", prt_names(f->type, - v4l2_type_names)); - switch (f->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) - ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd, &f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) - ret = vfd->vidioc_try_fmt_vid_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) - ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); - if (!ret) - v4l_print_pix_fmt(vfd, &f->fmt.pix); - break; - case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) - ret = vfd->vidioc_try_fmt_vid_out_overlay(file, - fh, f); - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) - ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); - break; - case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) - ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) - ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, - fh, f); - break; - case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) - ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, - fh, f); - break; - case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - ret = vfd->vidioc_try_fmt_type_private(file, - fh, f); - break; - } - - break; - } - /* FIXME: Those buf reqs could be handled here, - with some changes on videobuf to allow its header to be included at - videodev2.h or being merged at videodev2. - */ - case VIDIOC_REQBUFS: - { - struct v4l2_requestbuffers *p=arg; - - if (!vfd->vidioc_reqbufs) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_reqbufs(file, fh, p); - dbgarg (cmd, "count=%d, type=%s, memory=%s\n", - p->count, - prt_names(p->type, v4l2_type_names), - prt_names(p->memory, v4l2_memory_names)); - break; - } - case VIDIOC_QUERYBUF: - { - struct v4l2_buffer *p=arg; - - if (!vfd->vidioc_querybuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_querybuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_QBUF: - { - struct v4l2_buffer *p=arg; - - if (!vfd->vidioc_qbuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_qbuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_DQBUF: - { - struct v4l2_buffer *p=arg; - if (!vfd->vidioc_dqbuf) - break; - ret = check_fmt (vfd, p->type); - if (ret) - break; - - ret=vfd->vidioc_dqbuf(file, fh, p); - if (!ret) - dbgbuf(cmd,vfd,p); - break; - } - case VIDIOC_OVERLAY: - { - int *i = arg; - - if (!vfd->vidioc_overlay) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_overlay(file, fh, *i); - break; - } - case VIDIOC_G_FBUF: - { - struct v4l2_framebuffer *p = arg; - - if (!vfd->vidioc_g_fbuf) - break; - ret = vfd->vidioc_g_fbuf(file, fh, arg); - if (!ret) { - dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", - p->capability, p->flags, - (unsigned long)p->base); - v4l_print_pix_fmt(vfd, &p->fmt); - } - break; - } - case VIDIOC_S_FBUF: - { - struct v4l2_framebuffer *p = arg; - - if (!vfd->vidioc_s_fbuf) - break; - dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", - p->capability, p->flags, (unsigned long)p->base); - v4l_print_pix_fmt(vfd, &p->fmt); - ret = vfd->vidioc_s_fbuf(file, fh, arg); - break; - } - case VIDIOC_STREAMON: - { - enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamon) - break; - dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret=vfd->vidioc_streamon(file, fh,i); - break; - } - case VIDIOC_STREAMOFF: - { - enum v4l2_buf_type i = *(int *)arg; - - if (!vfd->vidioc_streamoff) - break; - dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret=vfd->vidioc_streamoff(file, fh, i); - break; - } - /* ---------- tv norms ---------- */ - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *p = arg; - v4l2_std_id id = vfd->tvnorms, curr_id = 0; - unsigned int index = p->index, i, j = 0; - const char *descr = ""; - - /* Return norm array in a canonical way */ - for (i = 0; i <= index && id; i++) { - /* last std value in the standards array is 0, so this - while always ends there since (id & 0) == 0. */ - while ((id & standards[j].std) != standards[j].std) - j++; - curr_id = standards[j].std; - descr = standards[j].descr; - j++; - if (curr_id == 0) - break; - if (curr_id != V4L2_STD_PAL && - curr_id != V4L2_STD_SECAM && - curr_id != V4L2_STD_NTSC) - id &= ~curr_id; - } - if (i <= index) - return -EINVAL; - - v4l2_video_std_construct(p, curr_id, descr); - p->index = index; - - dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " - "framelines=%d\n", p->index, - (unsigned long long)p->id, p->name, - p->frameperiod.numerator, - p->frameperiod.denominator, - p->framelines); - - ret = 0; - break; - } - case VIDIOC_G_STD: - { - v4l2_std_id *id = arg; - - ret = 0; - /* Calls the specific handler */ - if (vfd->vidioc_g_std) - ret = vfd->vidioc_g_std(file, fh, id); - else - *id = vfd->current_norm; - - if (!ret) - dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); - break; - } - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg,norm; - - dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); - - norm = (*id) & vfd->tvnorms; - if ( vfd->tvnorms && !norm) /* Check if std is supported */ - break; - - /* Calls the specific handler */ - if (vfd->vidioc_s_std) - ret=vfd->vidioc_s_std(file, fh, &norm); - else - ret=-EINVAL; - - /* Updates standard information */ - if (ret>=0) - vfd->current_norm=norm; - - break; - } - case VIDIOC_QUERYSTD: - { - v4l2_std_id *p=arg; - - if (!vfd->vidioc_querystd) - break; - ret=vfd->vidioc_querystd(file, fh, arg); - if (!ret) - dbgarg (cmd, "detected std=%08Lx\n", - (unsigned long long)*p); - break; - } - /* ------ input switching ---------- */ - /* FIXME: Inputs can be handled inside videodev2 */ - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *p=arg; - int i=p->index; - - if (!vfd->vidioc_enum_input) - break; - memset(p, 0, sizeof(*p)); - p->index=i; - - ret=vfd->vidioc_enum_input(file, fh, p); - if (!ret) - dbgarg (cmd, "index=%d, name=%s, type=%d, " - "audioset=%d, " - "tuner=%d, std=%08Lx, status=%d\n", - p->index,p->name,p->type,p->audioset, - p->tuner, - (unsigned long long)p->std, - p->status); - break; - } - case VIDIOC_G_INPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_g_input) - break; - ret=vfd->vidioc_g_input(file, fh, i); - if (!ret) - dbgarg (cmd, "value=%d\n",*i); - break; - } - case VIDIOC_S_INPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_s_input) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_s_input(file, fh, *i); - break; - } - - /* ------ output switching ---------- */ - case VIDIOC_ENUMOUTPUT: - { - struct v4l2_output *p = arg; - int i = p->index; - - if (!vfd->vidioc_enum_output) - break; - memset(p, 0, sizeof(*p)); - p->index = i; - - ret = vfd->vidioc_enum_output(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, type=%d, " - "audioset=0x%x, " - "modulator=%d, std=0x%08Lx\n", - p->index, p->name, p->type, p->audioset, - p->modulator, (unsigned long long)p->std); - break; - } - case VIDIOC_G_OUTPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_g_output) - break; - ret=vfd->vidioc_g_output(file, fh, i); - if (!ret) - dbgarg (cmd, "value=%d\n",*i); - break; - } - case VIDIOC_S_OUTPUT: - { - unsigned int *i = arg; - - if (!vfd->vidioc_s_output) - break; - dbgarg (cmd, "value=%d\n",*i); - ret=vfd->vidioc_s_output(file, fh, *i); - break; - } - - /* --- controls ---------------------------------------------- */ - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *p = arg; - - if (!vfd->vidioc_queryctrl) - break; - ret = vfd->vidioc_queryctrl(file, fh, p); - if (!ret) - dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " - "step=%d, default=%d, flags=0x%08x\n", - p->id, p->type, p->name, - p->minimum, p->maximum, - p->step, p->default_value, p->flags); - else - dbgarg(cmd, "id=0x%x\n", p->id); - break; - } - case VIDIOC_G_CTRL: - { - struct v4l2_control *p = arg; - - if (vfd->vidioc_g_ctrl) - ret = vfd->vidioc_g_ctrl(file, fh, p); - else if (vfd->vidioc_g_ext_ctrls) { - struct v4l2_ext_controls ctrls; - struct v4l2_ext_control ctrl; - - ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); - ctrls.count = 1; - ctrls.controls = &ctrl; - ctrl.id = p->id; - ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) { - ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); - if (ret == 0) - p->value = ctrl.value; - } - } else - break; - if (!ret) - dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - else - dbgarg(cmd, "id=0x%x\n", p->id); - break; - } - case VIDIOC_S_CTRL: - { - struct v4l2_control *p = arg; - struct v4l2_ext_controls ctrls; - struct v4l2_ext_control ctrl; - - if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) - break; - - dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - - if (vfd->vidioc_s_ctrl) { - ret = vfd->vidioc_s_ctrl(file, fh, p); - break; - } - if (!vfd->vidioc_s_ext_ctrls) - break; - - ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); - ctrls.count = 1; - ctrls.controls = &ctrl; - ctrl.id = p->id; - ctrl.value = p->value; - if (check_ext_ctrls(&ctrls, 1)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); - break; - } - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - p->error_idx = p->count; - if (!vfd->vidioc_g_ext_ctrls) - break; - if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_g_ext_ctrls(file, fh, p); - v4l_print_ext_ctrls(cmd, vfd, p, !ret); - break; - } - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - p->error_idx = p->count; - if (!vfd->vidioc_s_ext_ctrls) - break; - v4l_print_ext_ctrls(cmd, vfd, p, 1); - if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, p); - break; - } - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *p = arg; - - p->error_idx = p->count; - if (!vfd->vidioc_try_ext_ctrls) - break; - v4l_print_ext_ctrls(cmd, vfd, p, 1); - if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_try_ext_ctrls(file, fh, p); - break; - } - case VIDIOC_QUERYMENU: - { - struct v4l2_querymenu *p = arg; - - if (!vfd->vidioc_querymenu) - break; - ret = vfd->vidioc_querymenu(file, fh, p); - if (!ret) - dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", - p->id, p->index, p->name); - else - dbgarg(cmd, "id=0x%x, index=%d\n", - p->id, p->index); - break; - } - /* --- audio ---------------------------------------------- */ - case VIDIOC_ENUMAUDIO: - { - struct v4l2_audio *p = arg; - - if (!vfd->vidioc_enumaudio) - break; - ret = vfd->vidioc_enumaudio(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " - "mode=0x%x\n", p->index, p->name, - p->capability, p->mode); - else - dbgarg(cmd, "index=%d\n", p->index); - break; - } - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *p = arg; - __u32 index = p->index; - - if (!vfd->vidioc_g_audio) - break; - - memset(p, 0, sizeof(*p)); - p->index = index; - ret = vfd->vidioc_g_audio(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " - "mode=0x%x\n", p->index, - p->name, p->capability, p->mode); - else - dbgarg(cmd, "index=%d\n", p->index); - break; - } - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *p = arg; - - if (!vfd->vidioc_s_audio) - break; - dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " - "mode=0x%x\n", p->index, p->name, - p->capability, p->mode); - ret = vfd->vidioc_s_audio(file, fh, p); - break; - } - case VIDIOC_ENUMAUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_enumaudout) - break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_enumaudout(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - break; - } - case VIDIOC_G_AUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_g_audout) - break; - dbgarg(cmd, "Enum for index=%d\n", p->index); - ret=vfd->vidioc_g_audout(file, fh, p); - if (!ret) - dbgarg2("index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - break; - } - case VIDIOC_S_AUDOUT: - { - struct v4l2_audioout *p=arg; - - if (!vfd->vidioc_s_audout) - break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "mode=%d\n", p->index, p->name, - p->capability,p->mode); - - ret=vfd->vidioc_s_audout(file, fh, p); - break; - } - case VIDIOC_G_MODULATOR: - { - struct v4l2_modulator *p=arg; - if (!vfd->vidioc_g_modulator) - break; - ret=vfd->vidioc_g_modulator(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, " - "capability=%d, rangelow=%d," - " rangehigh=%d, txsubchans=%d\n", - p->index, p->name,p->capability, - p->rangelow, p->rangehigh, - p->txsubchans); - break; - } - case VIDIOC_S_MODULATOR: - { - struct v4l2_modulator *p=arg; - if (!vfd->vidioc_s_modulator) - break; - dbgarg(cmd, "index=%d, name=%s, capability=%d, " - "rangelow=%d, rangehigh=%d, txsubchans=%d\n", - p->index, p->name,p->capability,p->rangelow, - p->rangehigh,p->txsubchans); - ret=vfd->vidioc_s_modulator(file, fh, p); - break; - } - case VIDIOC_G_CROP: - { - struct v4l2_crop *p=arg; - if (!vfd->vidioc_g_crop) - break; - dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret=vfd->vidioc_g_crop(file, fh, p); - if (!ret) { - dbgrect(vfd, "", &p->c); - } - break; - } - case VIDIOC_S_CROP: - { - struct v4l2_crop *p=arg; - if (!vfd->vidioc_s_crop) - break; - dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - dbgrect(vfd, "", &p->c); - ret=vfd->vidioc_s_crop(file, fh, p); - break; - } - case VIDIOC_CROPCAP: - { - struct v4l2_cropcap *p = arg; - - /*FIXME: Should also show v4l2_fract pixelaspect */ - if (!vfd->vidioc_cropcap) - break; - dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_cropcap(file, fh, p); - if (!ret) { - dbgrect(vfd, "bounds ", &p->bounds); - dbgrect(vfd, "defrect ", &p->defrect); - } - break; - } - case VIDIOC_G_JPEGCOMP: - { - struct v4l2_jpegcompression *p=arg; - if (!vfd->vidioc_g_jpegcomp) - break; - ret=vfd->vidioc_g_jpegcomp(file, fh, p); - if (!ret) - dbgarg (cmd, "quality=%d, APPn=%d, " - "APP_len=%d, COM_len=%d, " - "jpeg_markers=%d\n", - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - break; - } - case VIDIOC_S_JPEGCOMP: - { - struct v4l2_jpegcompression *p=arg; - if (!vfd->vidioc_g_jpegcomp) - break; - dbgarg (cmd, "quality=%d, APPn=%d, APP_len=%d, " - "COM_len=%d, jpeg_markers=%d\n", - p->quality,p->APPn,p->APP_len, - p->COM_len,p->jpeg_markers); - ret=vfd->vidioc_s_jpegcomp(file, fh, p); - break; - } - case VIDIOC_G_ENC_INDEX: - { - struct v4l2_enc_idx *p=arg; - - if (!vfd->vidioc_g_enc_index) - break; - ret=vfd->vidioc_g_enc_index(file, fh, p); - if (!ret) - dbgarg (cmd, "entries=%d, entries_cap=%d\n", - p->entries,p->entries_cap); - break; - } - case VIDIOC_ENCODER_CMD: - { - struct v4l2_encoder_cmd *p = arg; - - if (!vfd->vidioc_encoder_cmd) - break; - memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_encoder_cmd(file, fh, p); - if (!ret) - dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); - break; - } - case VIDIOC_TRY_ENCODER_CMD: - { - struct v4l2_encoder_cmd *p = arg; - - if (!vfd->vidioc_try_encoder_cmd) - break; - memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_try_encoder_cmd(file, fh, p); - if (!ret) - dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); - break; - } - case VIDIOC_G_PARM: - { - struct v4l2_streamparm *p=arg; - __u32 type=p->type; - - memset(p,0,sizeof(*p)); - p->type=type; - - if (vfd->vidioc_g_parm) { - ret=vfd->vidioc_g_parm(file, fh, p); - } else { - struct v4l2_standard s; - - if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - v4l2_video_std_construct(&s, vfd->current_norm, - v4l2_norm_to_name(vfd->current_norm)); - - p->parm.capture.timeperframe = s.frameperiod; - ret=0; - } - - dbgarg (cmd, "type=%d\n", p->type); - break; - } - case VIDIOC_S_PARM: - { - struct v4l2_streamparm *p=arg; - if (!vfd->vidioc_s_parm) - break; - dbgarg (cmd, "type=%d\n", p->type); - ret=vfd->vidioc_s_parm(file, fh, p); - break; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *p = arg; - __u32 index = p->index; - - if (!vfd->vidioc_g_tuner) - break; - - memset(p, 0, sizeof(*p)); - p->index = index; - - ret = vfd->vidioc_g_tuner(file, fh, p); - if (!ret) - dbgarg(cmd, "index=%d, name=%s, type=%d, " - "capability=0x%x, rangelow=%d, " - "rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=0x%x, audmode=%d\n", - p->index, p->name, p->type, - p->capability, p->rangelow, - p->rangehigh, p->signal, p->afc, - p->rxsubchans, p->audmode); - break; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *p = arg; - - if (!vfd->vidioc_s_tuner) - break; - dbgarg(cmd, "index=%d, name=%s, type=%d, " - "capability=0x%x, rangelow=%d, " - "rangehigh=%d, signal=%d, afc=%d, " - "rxsubchans=0x%x, audmode=%d\n", - p->index, p->name, p->type, - p->capability, p->rangelow, - p->rangehigh, p->signal, p->afc, - p->rxsubchans, p->audmode); - ret = vfd->vidioc_s_tuner(file, fh, p); - break; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *p = arg; - - if (!vfd->vidioc_g_frequency) - break; - - memset(p->reserved, 0, sizeof(p->reserved)); - - ret = vfd->vidioc_g_frequency(file, fh, p); - if (!ret) - dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", - p->tuner, p->type, p->frequency); - break; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *p=arg; - if (!vfd->vidioc_s_frequency) - break; - dbgarg (cmd, "tuner=%d, type=%d, frequency=%d\n", - p->tuner,p->type,p->frequency); - ret=vfd->vidioc_s_frequency(file, fh, p); - break; - } - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *p = arg; - __u32 type = p->type; - - if (!vfd->vidioc_g_sliced_vbi_cap) - break; - memset(p, 0, sizeof(*p)); - p->type = type; - dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); - if (!ret) - dbgarg2("service_set=%d\n", p->service_set); - break; - } - case VIDIOC_LOG_STATUS: - { - if (!vfd->vidioc_log_status) - break; - ret=vfd->vidioc_log_status(file, fh); - break; - } -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_DBG_G_REGISTER: - { - struct v4l2_register *p=arg; - if (!capable(CAP_SYS_ADMIN)) - ret=-EPERM; - else if (vfd->vidioc_g_register) - ret=vfd->vidioc_g_register(file, fh, p); - break; - } - case VIDIOC_DBG_S_REGISTER: - { - struct v4l2_register *p=arg; - if (!capable(CAP_SYS_ADMIN)) - ret=-EPERM; - else if (vfd->vidioc_s_register) - ret=vfd->vidioc_s_register(file, fh, p); - break; - } -#endif - case VIDIOC_G_CHIP_IDENT: - { - struct v4l2_chip_ident *p=arg; - if (!vfd->vidioc_g_chip_ident) - break; - ret=vfd->vidioc_g_chip_ident(file, fh, p); - if (!ret) - dbgarg (cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); - break; - } - default: - { - if (!vfd->vidioc_default) - break; - ret = vfd->vidioc_default(file, fh, cmd, arg); - break; - } - case VIDIOC_S_HW_FREQ_SEEK: - { - struct v4l2_hw_freq_seek *p = arg; - if (!vfd->vidioc_s_hw_freq_seek) - break; - dbgarg(cmd, - "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", - p->tuner, p->type, p->seek_upward, p->wrap_around); - ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); - break; - } - } /* switch */ - - if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { - if (ret < 0) { - v4l_print_ioctl(vfd->name, cmd); - printk(KERN_CONT " error %d\n", ret); - } - } - - return ret; -} - -int video_ioctl2 (struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - int is_ext_ctrl; - size_t ctrls_size = 0; - void __user *user_ptr = NULL; - -#ifdef __OLD_VIDIOC_ - cmd = video_fix_command(cmd); -#endif - is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || - cmd == VIDIOC_TRY_EXT_CTRLS); - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - parg = NULL; - break; - case _IOC_READ: - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (_IOC_DIR(cmd) & _IOC_WRITE) - if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) - goto out; - break; - } - - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - /* In case of an error, tell the caller that it wasn't - a specific control that caused it. */ - p->error_idx = p->count; - user_ptr = (void __user *)p->controls; - if (p->count) { - ctrls_size = sizeof(struct v4l2_ext_control) * p->count; - /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ - mbuf = kmalloc(ctrls_size, GFP_KERNEL); - err = -ENOMEM; - if (NULL == mbuf) - goto out_ext_ctrl; - err = -EFAULT; - if (copy_from_user(mbuf, user_ptr, ctrls_size)) - goto out_ext_ctrl; - p->controls = mbuf; - } - } - - /* Handles IOCTL */ - err = __video_do_ioctl(inode, file, cmd, parg); - if (err == -ENOIOCTLCMD) - err = -EINVAL; - if (is_ext_ctrl) { - struct v4l2_ext_controls *p = parg; - - p->controls = (void *)user_ptr; - if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) - err = -EFAULT; - goto out_ext_ctrl; - } - if (err < 0) - goto out; - -out_ext_ctrl: - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - kfree(mbuf); - return err; -} -EXPORT_SYMBOL(video_ioctl2); - -/** - * get_index - assign stream number based on parent device - * @vdev: video_device to assign index number to, vdev->dev should be assigned - * @num: -1 if auto assign, requested number otherwise - * - * - * returns -ENFILE if num is already in use, a free index number if - * successful. - */ -static int get_index(struct video_device *vdev, int num) -{ - u32 used = 0; - const int max_index = sizeof(used) * 8 - 1; - int i; - - /* Currently a single v4l driver instance cannot create more than - 32 devices. - Increase to u64 or an array of u32 if more are needed. */ - if (num > max_index) { - printk(KERN_ERR "videodev: %s num is too large\n", __func__); - return -EINVAL; - } - - for (i = 0; i < VIDEO_NUM_DEVICES; i++) { - if (video_device[i] != NULL && - video_device[i] != vdev && - video_device[i]->dev == vdev->dev) { - used |= 1 << video_device[i]->index; - } - } - - if (num >= 0) { - if (used & (1 << num)) - return -ENFILE; - return num; - } - - i = ffz(used); - return i > max_index ? -ENFILE : i; -} - -static const struct file_operations video_fops; - -int video_register_device(struct video_device *vfd, int type, int nr) -{ - return video_register_device_index(vfd, type, nr, -1); -} -EXPORT_SYMBOL(video_register_device); - -/** - * video_register_device - register video4linux devices - * @vfd: video device structure we want to register - * @type: type of device to register - * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... - * -1 == first free) - * - * The registration code assigns minor numbers based on the type - * requested. -ENFILE is returned in all the device slots for this - * category are full. If not then the minor field is set and the - * driver initialize function is called (if non %NULL). - * - * Zero is returned on success. - * - * Valid types are - * - * %VFL_TYPE_GRABBER - A frame grabber - * - * %VFL_TYPE_VTX - A teletext device - * - * %VFL_TYPE_VBI - Vertical blank data (undecoded) - * - * %VFL_TYPE_RADIO - A radio card - */ - -int video_register_device_index(struct video_device *vfd, int type, int nr, - int index) -{ - int i=0; - int base; - int end; - int ret; - char *name_base; - - switch(type) - { - case VFL_TYPE_GRABBER: - base=MINOR_VFL_TYPE_GRABBER_MIN; - end=MINOR_VFL_TYPE_GRABBER_MAX+1; - name_base = "video"; - break; - case VFL_TYPE_VTX: - base=MINOR_VFL_TYPE_VTX_MIN; - end=MINOR_VFL_TYPE_VTX_MAX+1; - name_base = "vtx"; - break; - case VFL_TYPE_VBI: - base=MINOR_VFL_TYPE_VBI_MIN; - end=MINOR_VFL_TYPE_VBI_MAX+1; - name_base = "vbi"; - break; - case VFL_TYPE_RADIO: - base=MINOR_VFL_TYPE_RADIO_MIN; - end=MINOR_VFL_TYPE_RADIO_MAX+1; - name_base = "radio"; - break; - default: - printk(KERN_ERR "%s called with unknown type: %d\n", - __func__, type); - return -1; - } - - /* pick a minor number */ - mutex_lock(&videodev_lock); - if (nr >= 0 && nr < end-base) { - /* use the one the driver asked for */ - i = base+nr; - if (NULL != video_device[i]) { - mutex_unlock(&videodev_lock); - return -ENFILE; - } - } else { - /* use first free */ - for(i=base;iminor=i; - - ret = get_index(vfd, index); - vfd->index = ret; - - mutex_unlock(&videodev_lock); - - if (ret < 0) { - printk(KERN_ERR "%s: get_index failed\n", __func__); - goto fail_minor; - } - - mutex_init(&vfd->lock); - - /* sysfs class */ - memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); - vfd->class_dev.class = &video_class; - vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); - if (vfd->dev) - vfd->class_dev.parent = vfd->dev; - sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); - ret = device_register(&vfd->class_dev); - if (ret < 0) { - printk(KERN_ERR "%s: device_register failed\n", __func__); - goto fail_minor; - } - -#if 1 - /* needed until all drivers are fixed */ - if (!vfd->release) - printk(KERN_WARNING "videodev: \"%s\" has no release callback. " - "Please fix your driver for proper sysfs support, see " - "http://lwn.net/Articles/36850/\n", vfd->name); -#endif - return 0; - -fail_minor: - mutex_lock(&videodev_lock); - video_device[vfd->minor] = NULL; - vfd->minor = -1; - mutex_unlock(&videodev_lock); - return ret; -} -EXPORT_SYMBOL(video_register_device_index); - -/** - * video_unregister_device - unregister a video4linux device - * @vfd: the device to unregister - * - * This unregisters the passed device and deassigns the minor - * number. Future open calls will be met with errors. - */ - -void video_unregister_device(struct video_device *vfd) -{ - mutex_lock(&videodev_lock); - if(video_device[vfd->minor]!=vfd) - panic("videodev: bad unregister"); - - video_device[vfd->minor]=NULL; - device_unregister(&vfd->class_dev); - mutex_unlock(&videodev_lock); -} -EXPORT_SYMBOL(video_unregister_device); - -/* - * Video fs operations - */ -static const struct file_operations video_fops= -{ - .owner = THIS_MODULE, - .llseek = no_llseek, - .open = video_open, -}; - -/* - * Initialise video for linux - */ - -static int __init videodev_init(void) -{ - int ret; - - printk(KERN_INFO "Linux video capture interface: v2.00\n"); - if (register_chrdev(VIDEO_MAJOR, VIDEO_NAME, &video_fops)) { - printk(KERN_WARNING "video_dev: unable to get major %d\n", VIDEO_MAJOR); - return -EIO; - } - - ret = class_register(&video_class); - if (ret < 0) { - unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); - printk(KERN_WARNING "video_dev: class_register failed\n"); - return -EIO; - } - - return 0; -} - -static void __exit videodev_exit(void) -{ - class_unregister(&video_class); - unregister_chrdev(VIDEO_MAJOR, VIDEO_NAME); -} - -module_init(videodev_init) -module_exit(videodev_exit) - -MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab "); -MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2"); -MODULE_LICENSE("GPL"); - - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ -- cgit v1.2.3 From 5e85e732f0ed56aa97a3ba26ac2b93ffe597a208 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Jul 2008 06:31:39 -0300 Subject: V4L/DVB (8428): videodev: rename 'dev' to 'parent' The field 'dev' is not the video device, but the parent of the video device. Rename accordingly. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 4 ++-- drivers/media/video/cafe_ccic.c | 2 +- drivers/media/video/cx18/cx18-streams.c | 2 +- drivers/media/video/cx23885/cx23885-417.c | 2 +- drivers/media/video/cx23885/cx23885-video.c | 2 +- drivers/media/video/cx88/cx88-core.c | 2 +- drivers/media/video/em28xx/em28xx-video.c | 2 +- drivers/media/video/gspca/gspca.c | 2 +- drivers/media/video/ivtv/ivtv-streams.c | 2 +- drivers/media/video/meye.c | 2 +- drivers/media/video/mt9m001.c | 2 +- drivers/media/video/ov511.c | 2 +- drivers/media/video/pwc/pwc-if.c | 2 +- drivers/media/video/s2255drv.c | 2 +- drivers/media/video/saa7134/saa7134-core.c | 2 +- drivers/media/video/saa7134/saa7134-empress.c | 2 +- drivers/media/video/soc_camera.c | 10 +++++----- drivers/media/video/stk-webcam.c | 2 +- drivers/media/video/stv680.c | 2 +- drivers/media/video/usbvideo/usbvideo.c | 2 +- drivers/media/video/usbvision/usbvision-video.c | 2 +- drivers/media/video/uvc/uvc_driver.c | 2 +- drivers/media/video/v4l2-dev.c | 6 +++--- drivers/media/video/w9968cf.c | 2 +- include/media/v4l2-dev.h | 2 +- 25 files changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 0ea559a7fe59..3dda84d115d1 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -164,7 +164,7 @@ static ssize_t show_card(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vfd = container_of(cd, struct video_device, class_dev); - struct bttv *btv = dev_get_drvdata(vfd->dev); + struct bttv *btv = dev_get_drvdata(vfd->parent); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } static DEVICE_ATTR(card, S_IRUGO, show_card, NULL); @@ -4185,7 +4185,7 @@ static struct video_device *vdev_init(struct bttv *btv, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &btv->c.pci->dev; + vfd->parent = &btv->c.pci->dev; vfd->release = video_device_release; vfd->type = type; vfd->debug = bttv_debug; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index d99453faaab7..ebcc8ad6271f 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2157,7 +2157,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, cam->v4ldev = cafe_v4l_template; cam->v4ldev.debug = 0; // cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG; - cam->v4ldev.dev = &pdev->dev; + cam->v4ldev.parent = &pdev->dev; ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1); if (ret) goto out_smbus; diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 1728b1d832a9..210a2416b320 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -194,7 +194,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) cx->num); s->v4l2dev->minor = minor; - s->v4l2dev->dev = &cx->dev->dev; + s->v4l2dev->parent = &cx->dev->dev; s->v4l2dev->fops = cx18_stream_info[type].fops; s->v4l2dev->release = video_device_release; s->v4l2dev->tvnorms = V4L2_STD_ALL; diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index e7ef093265af..1b252976edac 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1766,7 +1766,7 @@ static struct video_device *cx23885_video_dev_alloc( vfd->minor = -1; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[tsport->dev->board].name); - vfd->dev = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; return vfd; } diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 043fc4e5c586..3b807ba874f1 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -326,7 +326,7 @@ struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type, cx23885_boards[dev->board].name); diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 60eeda3057e9..2c0582e05594 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -1006,7 +1006,7 @@ struct video_device *cx88_vdev_init(struct cx88_core *core, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &pci->dev; + vfd->parent = &pci->dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", core->name, type, core->board.name); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2d9f14d2a00b..838e7ecfd865 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1892,7 +1892,7 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &dev->udev->dev; + vfd->parent = &dev->udev->dev; vfd->release = video_device_release; vfd->type = type; vfd->debug = video_debug; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 16e367cec760..f5b77deab72d 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1740,7 +1740,7 @@ int gspca_dev_probe(struct usb_interface *intf, /* init video stuff */ memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template); - gspca_dev->vdev.dev = &dev->dev; + gspca_dev->vdev.parent = &dev->dev; memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); gspca_dev->vdev.fops = &gspca_dev->fops; gspca_dev->fops.owner = module; /* module protection */ diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index f8883b487f4a..b883c4e08fbd 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -217,7 +217,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) itv->num, s->name); s->v4l2dev->minor = minor; - s->v4l2dev->dev = &itv->dev->dev; + s->v4l2dev->parent = &itv->dev->dev; s->v4l2dev->fops = ivtv_stream_info[type].fops; s->v4l2dev->release = video_device_release; s->v4l2dev->tvnorms = V4L2_STD_ALL; diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2fb5854cf6f0..0045367a66f1 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1801,7 +1801,7 @@ static int __devinit meye_probe(struct pci_dev *pcidev, } memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); - meye.video_dev->dev = &meye.mchip_dev->dev; + meye.video_dev->parent = &meye.mchip_dev->dev; if ((ret = sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERA, 1))) { printk(KERN_ERR "meye: unable to power on the camera\n"); diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index ee43499544c1..554d2295484e 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c @@ -120,7 +120,7 @@ static int mt9m001_init(struct soc_camera_device *icd) int ret; /* Disable chip, synchronous option update */ - dev_dbg(icd->vdev->dev, "%s\n", __func__); + dev_dbg(icd->vdev->parent, "%s\n", __func__); ret = reg_write(icd, MT9M001_RESET, 1); if (ret >= 0) diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index eafb0c7736e6..b72e5660bc19 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -5833,7 +5833,7 @@ ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) goto error; memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); - ov->vdev->dev = &intf->dev; + ov->vdev->parent = &intf->dev; video_set_drvdata(ov->vdev, ov); for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 423fa7c2d0c9..b4de82115e5b 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1767,7 +1767,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id return -ENOMEM; } memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); - pdev->vdev->dev = &(udev->dev); + pdev->vdev->parent = &(udev->dev); strcpy(pdev->vdev->name, name); pdev->vdev->owner = THIS_MODULE; video_set_drvdata(pdev->vdev, pdev); diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 04eb2c3fabd8..5f8cd3de98e3 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1706,7 +1706,7 @@ static int s2255_probe_v4l(struct s2255_dev *dev) /* register 4 video devices */ dev->vdev[i] = video_device_alloc(); memcpy(dev->vdev[i], &template, sizeof(struct video_device)); - dev->vdev[i]->dev = &dev->interface->dev; + dev->vdev[i]->parent = &dev->interface->dev; if (video_nr == -1) ret = video_register_device(dev->vdev[i], VFL_TYPE_GRABBER, diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index cfee84ee7a88..f3e7a598e4b5 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -798,7 +798,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev, return NULL; *vfd = *template; vfd->minor = -1; - vfd->dev = &dev->pci->dev; + vfd->parent = &dev->pci->dev; vfd->release = video_device_release; vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 2a5ab957542d..3854cc29752d 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -465,7 +465,7 @@ static int empress_init(struct saa7134_dev *dev) if (NULL == dev->empress_dev) return -ENOMEM; *(dev->empress_dev) = saa7134_empress_template; - dev->empress_dev->dev = &dev->pci->dev; + dev->empress_dev->parent = &dev->pci->dev; dev->empress_dev->release = video_device_release; snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), "%s empress (%s)", dev->name, diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index e39b98f1eca4..58c8c39b9597 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -193,7 +193,7 @@ static int soc_camera_open(struct inode *inode, struct file *file) mutex_lock(&video_lock); vdev = video_devdata(file); - icd = container_of(vdev->dev, struct soc_camera_device, dev); + icd = container_of(vdev->parent, struct soc_camera_device, dev); ici = to_soc_camera_host(icd->dev.parent); if (!try_module_get(icd->ops->owner)) { @@ -258,7 +258,7 @@ static int soc_camera_close(struct inode *inode, struct file *file) vfree(icf); - dev_dbg(vdev->dev, "camera device close\n"); + dev_dbg(vdev->parent, "camera device close\n"); return 0; } @@ -271,7 +271,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf, struct video_device *vdev = icd->vdev; int err = -EINVAL; - dev_err(vdev->dev, "camera device read not implemented\n"); + dev_err(vdev->parent, "camera device read not implemented\n"); return err; } @@ -877,7 +877,7 @@ int soc_camera_video_start(struct soc_camera_device *icd) strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); /* Maybe better &ici->dev */ - vdev->dev = &icd->dev; + vdev->parent = &icd->dev; vdev->type = VID_TYPE_CAPTURE; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; @@ -915,7 +915,7 @@ int soc_camera_video_start(struct soc_camera_device *icd) err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor); if (err < 0) { - dev_err(vdev->dev, "video_register_device failed\n"); + dev_err(vdev->parent, "video_register_device failed\n"); goto evidregd; } icd->vdev = vdev; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index f308c38d744f..5998a5483194 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1369,7 +1369,7 @@ static int stk_register_video_device(struct stk_camera *dev) dev->vdev = stk_v4l_data; dev->vdev.debug = debug; - dev->vdev.dev = &dev->interface->dev; + dev->vdev.parent = &dev->interface->dev; dev->vdev.priv = dev; err = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (err) diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index d7f130bedb5f..27e2f4aac13d 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1454,7 +1454,7 @@ static int stv680_probe (struct usb_interface *intf, const struct usb_device_id goto error; } memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template)); - stv680->vdev->dev = &intf->dev; + stv680->vdev->parent = &intf->dev; video_set_drvdata(stv680->vdev, stv680); memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name)); diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 4128ee20b64e..7e6ab2910c13 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c @@ -1040,7 +1040,7 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) err("%s: uvd->dev == NULL", __func__); return -EINVAL; } - uvd->vdev.dev = &uvd->dev->dev; + uvd->vdev.parent = &uvd->dev->dev; if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { err("%s: video_register_device failed", __func__); return -EPIPE; diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index cd6c41d67899..899906d954aa 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1506,7 +1506,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision, } *vdev = *vdev_template; // vdev->minor = -1; - vdev->dev = &usb_dev->dev; + vdev->parent = &usb_dev->dev; snprintf(vdev->name, sizeof(vdev->name), "%s", name); video_set_drvdata(vdev, usbvision); return vdev; diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index f2b2983fe062..79d6821c4741 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1458,7 +1458,7 @@ static int uvc_register_video(struct uvc_device *dev) * unregistered before the reference is released, so we don't need to * get another one. */ - vdev->dev = &dev->intf->dev; + vdev->parent = &dev->intf->dev; vdev->type = 0; vdev->type2 = 0; vdev->minor = -1; diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 2dd82b16bc35..9cc2cf1a1c93 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -201,7 +201,7 @@ static int get_index(struct video_device *vdev, int num) for (i = 0; i < VIDEO_NUM_DEVICES; i++) { if (video_device[i] != NULL && video_device[i] != vdev && - video_device[i]->dev == vdev->dev) { + video_device[i]->parent == vdev->parent) { used |= 1 << video_device[i]->index; } } @@ -323,8 +323,8 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); vfd->class_dev.class = &video_class; vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); - if (vfd->dev) - vfd->class_dev.parent = vfd->dev; + if (vfd->parent) + vfd->class_dev.parent = vfd->parent; sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); ret = device_register(&vfd->class_dev); if (ret < 0) { diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 840522442d07..3f5a59dc5f8f 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -3555,7 +3555,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; video_set_drvdata(cam->v4ldev, cam); - cam->v4ldev->dev = &cam->dev; + cam->v4ldev->parent = &cam->dev; err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER, video_nr[dev_nr]); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 33f379b1ecfe..5ae261fbcb7e 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -89,7 +89,7 @@ struct video_device /* sysfs */ struct device class_dev; /* v4l device */ - struct device *dev; /* device parent */ + struct device *parent; /* device parent */ /* device info */ char name[32]; -- cgit v1.2.3 From 22a04f106346c3af019135f2de3cabf9ac41c3ba Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Jul 2008 06:35:02 -0300 Subject: V4L/DVB (8429): videodev: renamed 'class_dev' to 'dev' The class_dev field is a normal device, not a class device. This is very confusing and now that the old 'dev' field has been renamed to 'parent' we can rename 'class_dev' to just 'dev'. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/bt8xx/bttv-driver.c | 4 +- drivers/media/video/et61x251/et61x251_core.c | 2 +- drivers/media/video/sn9c102/sn9c102_core.c | 60 +++++++++------------ drivers/media/video/usbvision/usbvision-video.c | 72 ++++++++++--------------- drivers/media/video/v4l2-dev.c | 23 ++++---- include/media/v4l2-dev.h | 14 ++--- 6 files changed, 72 insertions(+), 103 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 3dda84d115d1..fff2fffcad63 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -163,7 +163,7 @@ MODULE_LICENSE("GPL"); static ssize_t show_card(struct device *cd, struct device_attribute *attr, char *buf) { - struct video_device *vfd = container_of(cd, struct video_device, class_dev); + struct video_device *vfd = container_of(cd, struct video_device, dev); struct bttv *btv = dev_get_drvdata(vfd->parent); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); } @@ -4244,7 +4244,7 @@ static int __devinit bttv_register_video(struct bttv *btv) goto err; printk(KERN_INFO "bttv%d: registered device video%d\n", btv->c.nr,btv->video_dev->minor & 0x1f); - if (device_create_file(&btv->video_dev->class_dev, + if (device_create_file(&btv->video_dev->dev, &dev_attr_card)<0) { printk(KERN_ERR "bttv%d: device_create_file 'card' " "failed\n", btv->c.nr); diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 15d037ae25c5..3eea1333a52f 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -985,7 +985,7 @@ static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, static int et61x251_create_sysfs(struct et61x251_device* cam) { - struct device *classdev = &(cam->v4ldev->class_dev); + struct device *classdev = &(cam->v4ldev->dev); int err = 0; if ((err = device_create_file(classdev, &dev_attr_reg))) diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 7f9c7bcf3c85..475b78191151 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -1038,8 +1038,7 @@ static ssize_t sn9c102_show_reg(struct device* cd, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1064,8 +1063,7 @@ sn9c102_store_reg(struct device* cd, struct device_attribute *attr, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1098,8 +1096,7 @@ static ssize_t sn9c102_show_val(struct device* cd, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1132,8 +1129,7 @@ sn9c102_store_val(struct device* cd, struct device_attribute *attr, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1170,8 +1166,7 @@ static ssize_t sn9c102_show_i2c_reg(struct device* cd, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1198,8 +1193,7 @@ sn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1232,8 +1226,7 @@ static ssize_t sn9c102_show_i2c_val(struct device* cd, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1271,8 +1264,7 @@ sn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1318,8 +1310,7 @@ sn9c102_store_green(struct device* cd, struct device_attribute *attr, if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; @@ -1400,8 +1391,7 @@ static ssize_t sn9c102_show_frame_header(struct device* cd, struct sn9c102_device* cam; ssize_t count; - cam = video_get_drvdata(container_of(cd, struct video_device, - class_dev)); + cam = video_get_drvdata(container_of(cd, struct video_device, dev)); if (!cam) return -ENODEV; @@ -1428,49 +1418,49 @@ static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); static int sn9c102_create_sysfs(struct sn9c102_device* cam) { - struct device *classdev = &(cam->v4ldev->class_dev); + struct device *dev = &(cam->v4ldev->dev); int err = 0; - if ((err = device_create_file(classdev, &dev_attr_reg))) + if ((err = device_create_file(dev, &dev_attr_reg))) goto err_out; - if ((err = device_create_file(classdev, &dev_attr_val))) + if ((err = device_create_file(dev, &dev_attr_val))) goto err_reg; - if ((err = device_create_file(classdev, &dev_attr_frame_header))) + if ((err = device_create_file(dev, &dev_attr_frame_header))) goto err_val; if (cam->sensor.sysfs_ops) { - if ((err = device_create_file(classdev, &dev_attr_i2c_reg))) + if ((err = device_create_file(dev, &dev_attr_i2c_reg))) goto err_frame_header; - if ((err = device_create_file(classdev, &dev_attr_i2c_val))) + if ((err = device_create_file(dev, &dev_attr_i2c_val))) goto err_i2c_reg; } if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { - if ((err = device_create_file(classdev, &dev_attr_green))) + if ((err = device_create_file(dev, &dev_attr_green))) goto err_i2c_val; } else { - if ((err = device_create_file(classdev, &dev_attr_blue))) + if ((err = device_create_file(dev, &dev_attr_blue))) goto err_i2c_val; - if ((err = device_create_file(classdev, &dev_attr_red))) + if ((err = device_create_file(dev, &dev_attr_red))) goto err_blue; } return 0; err_blue: - device_remove_file(classdev, &dev_attr_blue); + device_remove_file(dev, &dev_attr_blue); err_i2c_val: if (cam->sensor.sysfs_ops) - device_remove_file(classdev, &dev_attr_i2c_val); + device_remove_file(dev, &dev_attr_i2c_val); err_i2c_reg: if (cam->sensor.sysfs_ops) - device_remove_file(classdev, &dev_attr_i2c_reg); + device_remove_file(dev, &dev_attr_i2c_reg); err_frame_header: - device_remove_file(classdev, &dev_attr_frame_header); + device_remove_file(dev, &dev_attr_frame_header); err_val: - device_remove_file(classdev, &dev_attr_val); + device_remove_file(dev, &dev_attr_val); err_reg: - device_remove_file(classdev, &dev_attr_reg); + device_remove_file(dev, &dev_attr_reg); err_out: return err; } diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 899906d954aa..2ddfaa34e6b0 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -184,7 +184,7 @@ MODULE_ALIAS(DRIVER_ALIAS); static inline struct usb_usbvision *cd_to_usbvision(struct device *cd) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); return video_get_drvdata(vdev); } @@ -199,7 +199,7 @@ static ssize_t show_model(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", usbvision_device_data[usbvision->DevModel].ModelString); @@ -210,7 +210,7 @@ static ssize_t show_hue(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_HUE; @@ -225,7 +225,7 @@ static ssize_t show_contrast(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_CONTRAST; @@ -240,7 +240,7 @@ static ssize_t show_brightness(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_BRIGHTNESS; @@ -255,7 +255,7 @@ static ssize_t show_saturation(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); struct v4l2_control ctrl; ctrl.id = V4L2_CID_SATURATION; @@ -270,7 +270,7 @@ static ssize_t show_streaming(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->streaming==Stream_On?1:0)); @@ -281,7 +281,7 @@ static ssize_t show_compression(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%s\n", YES_NO(usbvision->isocMode==ISOC_MODE_COMPRESS)); @@ -292,7 +292,7 @@ static ssize_t show_device_bridge(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vdev = - container_of(cd, struct video_device, class_dev); + container_of(cd, struct video_device, dev); struct usb_usbvision *usbvision = video_get_drvdata(vdev); return sprintf(buf, "%d\n", usbvision->bridgeType); } @@ -304,40 +304,31 @@ static void usbvision_create_sysfs(struct video_device *vdev) if (!vdev) return; do { - res = device_create_file(&vdev->class_dev, - &dev_attr_version); + res = device_create_file(&vdev->dev, &dev_attr_version); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_model); + res = device_create_file(&vdev->dev, &dev_attr_model); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_hue); + res = device_create_file(&vdev->dev, &dev_attr_hue); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_contrast); + res = device_create_file(&vdev->dev, &dev_attr_contrast); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_brightness); + res = device_create_file(&vdev->dev, &dev_attr_brightness); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_saturation); + res = device_create_file(&vdev->dev, &dev_attr_saturation); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_streaming); + res = device_create_file(&vdev->dev, &dev_attr_streaming); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_compression); + res = device_create_file(&vdev->dev, &dev_attr_compression); if (res<0) break; - res = device_create_file(&vdev->class_dev, - &dev_attr_bridge); + res = device_create_file(&vdev->dev, &dev_attr_bridge); if (res>=0) return; } while (0); @@ -348,24 +339,15 @@ static void usbvision_create_sysfs(struct video_device *vdev) static void usbvision_remove_sysfs(struct video_device *vdev) { if (vdev) { - device_remove_file(&vdev->class_dev, - &dev_attr_version); - device_remove_file(&vdev->class_dev, - &dev_attr_model); - device_remove_file(&vdev->class_dev, - &dev_attr_hue); - device_remove_file(&vdev->class_dev, - &dev_attr_contrast); - device_remove_file(&vdev->class_dev, - &dev_attr_brightness); - device_remove_file(&vdev->class_dev, - &dev_attr_saturation); - device_remove_file(&vdev->class_dev, - &dev_attr_streaming); - device_remove_file(&vdev->class_dev, - &dev_attr_compression); - device_remove_file(&vdev->class_dev, - &dev_attr_bridge); + device_remove_file(&vdev->dev, &dev_attr_version); + device_remove_file(&vdev->dev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_hue); + device_remove_file(&vdev->dev, &dev_attr_contrast); + device_remove_file(&vdev->dev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_saturation); + device_remove_file(&vdev->dev, &dev_attr_streaming); + device_remove_file(&vdev->dev, &dev_attr_compression); + device_remove_file(&vdev->dev, &dev_attr_bridge); } } diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 9cc2cf1a1c93..88eeee1d8baf 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -41,16 +41,14 @@ static ssize_t show_index(struct device *cd, struct device_attribute *attr, char *buf) { - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); + struct video_device *vfd = container_of(cd, struct video_device, dev); return sprintf(buf, "%i\n", vfd->index); } static ssize_t show_name(struct device *cd, struct device_attribute *attr, char *buf) { - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); + struct video_device *vfd = container_of(cd, struct video_device, dev); return sprintf(buf, "%.*s\n", (int)sizeof(vfd->name), vfd->name); } @@ -77,8 +75,7 @@ EXPORT_SYMBOL(video_device_release); static void video_release(struct device *cd) { - struct video_device *vfd = container_of(cd, struct video_device, - class_dev); + struct video_device *vfd = container_of(cd, struct video_device, dev); #if 1 /* needed until all drivers are fixed */ @@ -320,13 +317,13 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, mutex_init(&vfd->lock); /* sysfs class */ - memset(&vfd->class_dev, 0x00, sizeof(vfd->class_dev)); - vfd->class_dev.class = &video_class; - vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); + memset(&vfd->dev, 0x00, sizeof(vfd->dev)); + vfd->dev.class = &video_class; + vfd->dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); if (vfd->parent) - vfd->class_dev.parent = vfd->parent; - sprintf(vfd->class_dev.bus_id, "%s%d", name_base, i - base); - ret = device_register(&vfd->class_dev); + vfd->dev.parent = vfd->parent; + sprintf(vfd->dev.bus_id, "%s%d", name_base, i - base); + ret = device_register(&vfd->dev); if (ret < 0) { printk(KERN_ERR "%s: device_register failed\n", __func__); goto fail_minor; @@ -365,7 +362,7 @@ void video_unregister_device(struct video_device *vfd) panic("videodev: bad unregister"); video_device[vfd->minor] = NULL; - device_unregister(&vfd->class_dev); + device_unregister(&vfd->dev); mutex_unlock(&videodev_lock); } EXPORT_SYMBOL(video_unregister_device); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 5ae261fbcb7e..185372ffa270 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -88,18 +88,18 @@ struct video_device const struct file_operations *fops; /* sysfs */ - struct device class_dev; /* v4l device */ + struct device dev; /* v4l device */ struct device *parent; /* device parent */ /* device info */ char name[32]; - int type; /* v4l1 */ - int type2; /* v4l2 */ + int type; /* v4l1 */ + int type2; /* v4l2 */ int minor; /* attribute to diferentiate multiple indexs on one physical device */ int index; - int debug; /* Activates debug level*/ + int debug; /* Activates debug level*/ /* Video standard vars */ v4l2_std_id tvnorms; /* Supported tv norms */ @@ -345,7 +345,7 @@ void *priv; }; /* Class-dev to video-device */ -#define to_video_device(cd) container_of(cd, struct video_device, class_dev) +#define to_video_device(cd) container_of(cd, struct video_device, dev) /* Version 2 functions */ extern int video_register_device(struct video_device *vfd, int type, int nr); @@ -373,7 +373,7 @@ static inline int __must_check video_device_create_file(struct video_device *vfd, struct device_attribute *attr) { - int ret = device_create_file(&vfd->class_dev, attr); + int ret = device_create_file(&vfd->dev, attr); if (ret < 0) printk(KERN_WARNING "%s error: %d\n", __func__, ret); return ret; @@ -382,7 +382,7 @@ static inline void video_device_remove_file(struct video_device *vfd, struct device_attribute *attr) { - device_remove_file(&vfd->class_dev, attr); + device_remove_file(&vfd->dev, attr); } #endif /* CONFIG_VIDEO_V4L1_COMPAT */ -- cgit v1.2.3 From e81cf44428b9540d489a12880663488708bbb9c1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Jul 2008 10:49:39 -0300 Subject: V4L/DVB (8433): Fix macro name at z0194a.h As reported by Hans Verkuil: In file included from /home/v4l/master/v4l/dw2102.c:14: /home/v4l/master/v4l/z0194a.h:93: error: 'STV0229_LOCKOUTPUT_1' undeclared here (not in a function) This is due to some typos that were fixed on stv0299. This patch renames it in accord with that fix. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/z0194a.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h index b5ca9e754218..d2876d2e1769 100644 --- a/drivers/media/dvb/frontends/z0194a.h +++ b/drivers/media/dvb/frontends/z0194a.h @@ -88,7 +88,7 @@ static struct stv0299_config sharp_z0194a_config = { .mclk = 88000000UL, .invert = 1, .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, + .lock_output = STV0299_LOCKOUTPUT_1, .volt13_op0_op1 = STV0299_VOLT13_OP1, .min_delay_ms = 100, .set_symbol_rate = sharp_z0194a__set_symbol_rate, -- cgit v1.2.3 From 35ea11ff84719b1bfab2909903a9640a86552fd1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 20 Jul 2008 08:12:02 -0300 Subject: V4L/DVB (8430): videodev: move some functions from v4l2-dev.h to v4l2-common.h or v4l2-ioctl.h The functions in a header should not belong to another module. The prio functions belong to v4l2-common.c, so move them to v4l2-common.h. The ioctl functions belong to v4l2-ioctl.c, so create a new v4l2-ioctl.h header and move those functions to it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 1 + drivers/media/radio/miropcm20-radio.c | 1 + drivers/media/radio/radio-aimslab.c | 1 + drivers/media/radio/radio-aztech.c | 1 + drivers/media/radio/radio-cadet.c | 1 + drivers/media/radio/radio-gemtek-pci.c | 1 + drivers/media/radio/radio-gemtek.c | 1 + drivers/media/radio/radio-maestro.c | 1 + drivers/media/radio/radio-maxiradio.c | 1 + drivers/media/radio/radio-rtrack2.c | 1 + drivers/media/radio/radio-sf16fmi.c | 1 + drivers/media/radio/radio-sf16fmr2.c | 1 + drivers/media/radio/radio-si470x.c | 1 + drivers/media/radio/radio-terratec.c | 1 + drivers/media/radio/radio-trust.c | 1 + drivers/media/radio/radio-typhoon.c | 1 + drivers/media/radio/radio-zoltrix.c | 1 + drivers/media/video/bt8xx/bttv-driver.c | 1 + drivers/media/video/bt8xx/bttv-risc.c | 1 + drivers/media/video/bt8xx/bttv-vbi.c | 1 + drivers/media/video/bw-qcam.c | 1 + drivers/media/video/c-qcam.c | 1 + drivers/media/video/cafe_ccic.c | 1 + drivers/media/video/cpia.h | 1 + drivers/media/video/cpia2/cpia2_v4l.c | 1 + drivers/media/video/cx18/cx18-driver.h | 1 + drivers/media/video/cx23885/cx23885-417.c | 1 + drivers/media/video/cx23885/cx23885-video.c | 1 + drivers/media/video/cx88/cx88-blackbird.c | 1 + drivers/media/video/cx88/cx88-core.c | 1 + drivers/media/video/cx88/cx88-video.c | 1 + drivers/media/video/em28xx/em28xx-video.c | 1 + drivers/media/video/et61x251/et61x251_core.c | 1 + drivers/media/video/gspca/gspca.c | 1 + drivers/media/video/ivtv/ivtv-driver.h | 1 + drivers/media/video/meye.c | 1 + drivers/media/video/msp3400-driver.c | 1 + drivers/media/video/ov511.h | 1 + drivers/media/video/pms.c | 1 + drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 + drivers/media/video/pwc/pwc.h | 1 + drivers/media/video/s2255drv.c | 1 + drivers/media/video/saa5246a.c | 1 + drivers/media/video/saa5249.c | 1 + drivers/media/video/saa7134/saa7134.h | 1 + drivers/media/video/se401.h | 1 + drivers/media/video/sn9c102/sn9c102.h | 1 + drivers/media/video/soc_camera.c | 1 + drivers/media/video/stk-webcam.c | 1 + drivers/media/video/stv680.c | 1 + drivers/media/video/tda7432.c | 1 + drivers/media/video/tuner-core.c | 1 + drivers/media/video/usbvideo/usbvideo.h | 1 + drivers/media/video/usbvision/usbvision-video.c | 1 + drivers/media/video/uvc/uvc_v4l2.c | 1 + drivers/media/video/v4l1-compat.c | 1 + drivers/media/video/v4l2-ioctl.c | 1865 +++++++++++++++++++++++ drivers/media/video/vivi.c | 1 + drivers/media/video/w9966.c | 1 + drivers/media/video/zc0301/zc0301.h | 1 + drivers/media/video/zoran_driver.c | 1 + drivers/media/video/zr364xx.c | 1 + include/media/saa7146_vv.h | 1 + include/media/v4l2-common.h | 15 + include/media/v4l2-dev.h | 45 - include/media/v4l2-ioctl.h | 57 + 66 files changed, 1999 insertions(+), 45 deletions(-) create mode 100644 drivers/media/video/v4l2-ioctl.c create mode 100644 include/media/v4l2-ioctl.h (limited to 'drivers/media') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 4e3f83e4e48f..97c6853ad1d3 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -85,6 +85,7 @@ #include #include #include +#include #include /* diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index 09fe6f1cdf14..4a332fe8b64b 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "oss/aci.h" #include "miropcm20-rds-core.h" diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 1ec18ed1a733..ec8d64704dd0 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -36,6 +36,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,2) diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 46cdb549eac7..639164a974a1 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -33,6 +33,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,2) diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index b14db53ea456..484ea87d7fba 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -39,6 +39,7 @@ #include /* copy to/from user */ #include /* V4L2 API defs */ #include +#include #include #include diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index de49be971480..2b834b95f3e7 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include /* for KERNEL_VERSION MACRO */ diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 81f6aeb1cd11..4740bacc2f88 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -23,6 +23,7 @@ #include /* outb, outb_p */ #include /* copy to/from user */ #include /* kernel radio structs */ +#include #include #include diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index bddd3c409aa9..040a73fac694 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -27,6 +27,7 @@ #include #include #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,6) diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 0133ecf3e040..9e824a7d5cc4 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -44,6 +44,7 @@ #include #include #include +#include #define DRIVER_VERSION "0.77" diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 070802103dc3..c3fb270f211b 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -17,6 +17,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include #include /* for KERNEL_VERSION MACRO */ diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 66e052fd3909..bb8b1c9107b1 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -24,6 +24,7 @@ #include /* udelay */ #include /* kernel radio structs */ #include +#include #include #include /* outb, outb_p */ #include /* copy to/from user */ diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index b0ccf7cb5952..9fa025b704cb 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -22,6 +22,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include static struct mutex lock; diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index dc93a882b385..333612180176 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -133,6 +133,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index acc32080e9bd..a9914dbcf493 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -32,6 +32,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include #include /* for KERNEL_VERSION MACRO */ diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 4ebdfbadeb9c..560c49481a2d 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,2) diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 18f2abd7e255..023d6f3c751c 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -40,6 +40,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,1,1) diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 43773c56c62f..cf0355bb6ef7 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -37,6 +37,7 @@ #include /* copy to/from user */ #include /* kernel radio structs */ #include +#include #include /* for KERNEL_VERSION MACRO */ #define RADIO_VERSION KERNEL_VERSION(0,0,2) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index fff2fffcad63..33c72055447d 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -45,6 +45,7 @@ #include #include "bttvp.h" #include +#include #include #include diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c index 0af586876e72..649682aac1ac 100644 --- a/drivers/media/video/bt8xx/bttv-risc.c +++ b/drivers/media/video/bt8xx/bttv-risc.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "bttvp.h" diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c index 68f28e5fa040..6819e21a3773 100644 --- a/drivers/media/video/bt8xx/bttv-vbi.c +++ b/drivers/media/video/bt8xx/bttv-vbi.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "bttvp.h" diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index b364adaae78d..e367862313e1 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -74,6 +74,7 @@ OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index fe1e67bb1ca8..8d690410c84f 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index ebcc8ad6271f..302c57f151c2 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h index 5096058bf579..8f0cfee4b8a1 100644 --- a/drivers/media/video/cpia.h +++ b/drivers/media/video/cpia.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 7ce2789fa976..8817c3841463 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "cpia2.h" #include "cpia2dev.h" diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 45e31b04730e..4801bc7fb5b2 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "cx18-mailbox.h" #include "cx18-av-core.h" diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 1b252976edac..4d0dcb06c19d 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "cx23885.h" diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 3b807ba874f1..245712e45f69 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -33,6 +33,7 @@ #include "cx23885.h" #include +#include #ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index bfdca5847764..4d1a461f329f 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "cx88.h" diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 2c0582e05594..d656fec59010 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c @@ -40,6 +40,7 @@ #include "cx88.h" #include +#include MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 0fed5cd2ccea..d08c11eb8a75 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -39,6 +39,7 @@ #include "cx88.h" #include +#include #ifdef CONFIG_VIDEO_V4L1_COMPAT /* Include V4L1 specific functions. Should be removed soon */ diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 838e7ecfd865..67c62eaa5b6d 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -38,6 +38,7 @@ #include "em28xx.h" #include +#include #include #include diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 3eea1333a52f..8cd5f37425ea 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index f5b77deab72d..8170a6937b8c 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "gspca.h" diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index a08bb3331cfb..ab287b48fc2b 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -60,6 +60,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 0045367a66f1..a1fb9874fdcf 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 5691e019d195..780531b587a4 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h index 1010e51189b7..baded1262ca9 100644 --- a/drivers/media/video/ov511.h +++ b/drivers/media/video/ov511.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 51b1461d8fb6..260c1d3f9692 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 0d72dc470fef..bd6169fbdcca 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -30,6 +30,7 @@ #include #include #include +#include struct pvr2_v4l2_dev; struct pvr2_v4l2_fh; diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 8e8e5b27e77e..835db149a3b1 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "pwc-uncompress.h" #include diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 5f8cd3de98e3..eb81915935b1 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 03e772130b55..8d69632a6658 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "saa5246a.h" diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index fde99d9ee71f..812cfe3fd3f3 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -57,6 +57,7 @@ #include #include #include +#include #include diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 6927cbea8624..ade4e19799e9 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -34,6 +34,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h index 835ef872e803..2ce685db5d8b 100644 --- a/drivers/media/video/se401.h +++ b/drivers/media/video/se401.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #define se401_DEBUG /* Turn on debug messages */ diff --git a/drivers/media/video/sn9c102/sn9c102.h b/drivers/media/video/sn9c102/sn9c102.h index 0c8d87d8d18d..cbfc44433b99 100644 --- a/drivers/media/video/sn9c102/sn9c102.h +++ b/drivers/media/video/sn9c102/sn9c102.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 58c8c39b9597..b01749088472 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 5998a5483194..20028aeb842b 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "stk-webcam.h" diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 27e2f4aac13d..da94d3fd8fac 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index ae75c187da79..2fda40c0f255 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -48,6 +48,7 @@ #include #include +#include #include #ifndef VIDEO_AUDIO_BALANCE diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 93d879dc510f..d806a3556eed 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "mt20xx.h" #include "tda8290.h" diff --git a/drivers/media/video/usbvideo/usbvideo.h b/drivers/media/video/usbvideo/usbvideo.h index 051775d4c726..c66985beb8c9 100644 --- a/drivers/media/video/usbvideo/usbvideo.h +++ b/drivers/media/video/usbvideo/usbvideo.h @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 2ddfaa34e6b0..56cd685d35ea 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -65,6 +65,7 @@ #include #include +#include #include #include diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index b5a11eb8f9fa..d7bd71be40a9 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c @@ -23,6 +23,7 @@ #include #include +#include #include "uvcvideo.h" diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index a0f6c60279ec..79937d1031fc 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c new file mode 100644 index 000000000000..56a4fdee9160 --- /dev/null +++ b/drivers/media/video/v4l2-ioctl.c @@ -0,0 +1,1865 @@ +/* + * Video capture interface for Linux version 2 + * + * A generic framework to process V4L2 ioctl commands. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Alan Cox, (version 1) + * Mauro Carvalho Chehab (version 2) + */ + +#include +#include +#include + +#define __OLD_VIDIOC_ /* To allow fixing old calls */ +#include + +#ifdef CONFIG_VIDEO_V4L1 +#include +#endif +#include +#include +#include + +#define dbgarg(cmd, fmt, arg...) \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { \ + printk(KERN_DEBUG "%s: ", vfd->name); \ + v4l_printk_ioctl(cmd); \ + printk(" " fmt, ## arg); \ + } \ + } while (0) + +#define dbgarg2(fmt, arg...) \ + do { \ + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) \ + printk(KERN_DEBUG "%s: " fmt, vfd->name, ## arg);\ + } while (0) + +struct std_descr { + v4l2_std_id std; + const char *descr; +}; + +static const struct std_descr standards[] = { + { V4L2_STD_NTSC, "NTSC" }, + { V4L2_STD_NTSC_M, "NTSC-M" }, + { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" }, + { V4L2_STD_NTSC_M_KR, "NTSC-M-KR" }, + { V4L2_STD_NTSC_443, "NTSC-443" }, + { V4L2_STD_PAL, "PAL" }, + { V4L2_STD_PAL_BG, "PAL-BG" }, + { V4L2_STD_PAL_B, "PAL-B" }, + { V4L2_STD_PAL_B1, "PAL-B1" }, + { V4L2_STD_PAL_G, "PAL-G" }, + { V4L2_STD_PAL_H, "PAL-H" }, + { V4L2_STD_PAL_I, "PAL-I" }, + { V4L2_STD_PAL_DK, "PAL-DK" }, + { V4L2_STD_PAL_D, "PAL-D" }, + { V4L2_STD_PAL_D1, "PAL-D1" }, + { V4L2_STD_PAL_K, "PAL-K" }, + { V4L2_STD_PAL_M, "PAL-M" }, + { V4L2_STD_PAL_N, "PAL-N" }, + { V4L2_STD_PAL_Nc, "PAL-Nc" }, + { V4L2_STD_PAL_60, "PAL-60" }, + { V4L2_STD_SECAM, "SECAM" }, + { V4L2_STD_SECAM_B, "SECAM-B" }, + { V4L2_STD_SECAM_G, "SECAM-G" }, + { V4L2_STD_SECAM_H, "SECAM-H" }, + { V4L2_STD_SECAM_DK, "SECAM-DK" }, + { V4L2_STD_SECAM_D, "SECAM-D" }, + { V4L2_STD_SECAM_K, "SECAM-K" }, + { V4L2_STD_SECAM_K1, "SECAM-K1" }, + { V4L2_STD_SECAM_L, "SECAM-L" }, + { V4L2_STD_SECAM_LC, "SECAM-Lc" }, + { 0, "Unknown" } +}; + +/* video4linux standard ID conversion to standard name + */ +const char *v4l2_norm_to_name(v4l2_std_id id) +{ + u32 myid = id; + int i; + + /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle + 64 bit comparations. So, on that architecture, with some gcc + variants, compilation fails. Currently, the max value is 30bit wide. + */ + BUG_ON(myid != id); + + for (i = 0; standards[i].std; i++) + if (myid == standards[i].std) + break; + return standards[i].descr; +} +EXPORT_SYMBOL(v4l2_norm_to_name); + +/* Fill in the fields of a v4l2_standard structure according to the + 'id' and 'transmission' parameters. Returns negative on error. */ +int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, const char *name) +{ + u32 index = vs->index; + + memset(vs, 0, sizeof(struct v4l2_standard)); + vs->index = index; + vs->id = id; + if (id & V4L2_STD_525_60) { + vs->frameperiod.numerator = 1001; + vs->frameperiod.denominator = 30000; + vs->framelines = 525; + } else { + vs->frameperiod.numerator = 1; + vs->frameperiod.denominator = 25; + vs->framelines = 625; + } + strlcpy(vs->name, name, sizeof(vs->name)); + return 0; +} +EXPORT_SYMBOL(v4l2_video_std_construct); + +/* ----------------------------------------------------------------- */ +/* some arrays for pretty-printing debug messages of enum types */ + +const char *v4l2_field_names[] = { + [V4L2_FIELD_ANY] = "any", + [V4L2_FIELD_NONE] = "none", + [V4L2_FIELD_TOP] = "top", + [V4L2_FIELD_BOTTOM] = "bottom", + [V4L2_FIELD_INTERLACED] = "interlaced", + [V4L2_FIELD_SEQ_TB] = "seq-tb", + [V4L2_FIELD_SEQ_BT] = "seq-bt", + [V4L2_FIELD_ALTERNATE] = "alternate", + [V4L2_FIELD_INTERLACED_TB] = "interlaced-tb", + [V4L2_FIELD_INTERLACED_BT] = "interlaced-bt", +}; +EXPORT_SYMBOL(v4l2_field_names); + +const char *v4l2_type_names[] = { + [V4L2_BUF_TYPE_VIDEO_CAPTURE] = "vid-cap", + [V4L2_BUF_TYPE_VIDEO_OVERLAY] = "vid-overlay", + [V4L2_BUF_TYPE_VIDEO_OUTPUT] = "vid-out", + [V4L2_BUF_TYPE_VBI_CAPTURE] = "vbi-cap", + [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", + [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", + [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", + [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", +}; +EXPORT_SYMBOL(v4l2_type_names); + +static const char *v4l2_memory_names[] = { + [V4L2_MEMORY_MMAP] = "mmap", + [V4L2_MEMORY_USERPTR] = "userptr", + [V4L2_MEMORY_OVERLAY] = "overlay", +}; + +#define prt_names(a, arr) ((((a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \ + arr[a] : "unknown") + +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +#ifdef CONFIG_VIDEO_V4L1_COMPAT +static const char *v4l1_ioctls[] = { + [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", + [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", + [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", + [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", + [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", + [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", + [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", + [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", + [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", + [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", + [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", + [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", + [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", + [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", + [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", + [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", + [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", + [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", + [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", + [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", + [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", + [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", + [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", + [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", + [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", + [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", + [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", + [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", + [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" +}; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) +#endif + +static const char *v4l2_ioctls[] = { + [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", + [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", + [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", + [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", + [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", + [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", + [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", + [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", + [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", + [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", + [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", + [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", + [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", + [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", + [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", + [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", + [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", + [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", + [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", + [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", + [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", + [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", + [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", + [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", + [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", + [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", + [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", + [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", + [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", + [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", + [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", + [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", + [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", + [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", + [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", + [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", + [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", + [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", + [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", + [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", + [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", + [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", + [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", + [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", + [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", + [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", + [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", + [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", + [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", + [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", + [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", + [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS", + [_IOC_NR(VIDIOC_G_EXT_CTRLS)] = "VIDIOC_G_EXT_CTRLS", + [_IOC_NR(VIDIOC_S_EXT_CTRLS)] = "VIDIOC_S_EXT_CTRLS", + [_IOC_NR(VIDIOC_TRY_EXT_CTRLS)] = "VIDIOC_TRY_EXT_CTRLS", +#if 1 + [_IOC_NR(VIDIOC_ENUM_FRAMESIZES)] = "VIDIOC_ENUM_FRAMESIZES", + [_IOC_NR(VIDIOC_ENUM_FRAMEINTERVALS)] = "VIDIOC_ENUM_FRAMEINTERVALS", + [_IOC_NR(VIDIOC_G_ENC_INDEX)] = "VIDIOC_G_ENC_INDEX", + [_IOC_NR(VIDIOC_ENCODER_CMD)] = "VIDIOC_ENCODER_CMD", + [_IOC_NR(VIDIOC_TRY_ENCODER_CMD)] = "VIDIOC_TRY_ENCODER_CMD", + + [_IOC_NR(VIDIOC_DBG_S_REGISTER)] = "VIDIOC_DBG_S_REGISTER", + [_IOC_NR(VIDIOC_DBG_G_REGISTER)] = "VIDIOC_DBG_G_REGISTER", + + [_IOC_NR(VIDIOC_G_CHIP_IDENT)] = "VIDIOC_G_CHIP_IDENT", + [_IOC_NR(VIDIOC_S_HW_FREQ_SEEK)] = "VIDIOC_S_HW_FREQ_SEEK", +#endif +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +static const char *v4l2_int_ioctls[] = { +#ifdef CONFIG_VIDEO_V4L1_COMPAT + [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", + [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", + [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", + [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", + [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", + [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", + [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", + [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", + [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", + [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", + [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", +#endif + [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", + + [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", + [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", + [_IOC_NR(TUNER_SET_CONFIG)] = "TUNER_SET_CONFIG", + + [_IOC_NR(VIDIOC_INT_S_TUNER_MODE)] = "VIDIOC_INT_S_TUNER_MODE", + [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", + [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", + [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", + [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", + [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ", + [_IOC_NR(VIDIOC_INT_S_STANDBY)] = "VIDIOC_INT_S_STANDBY", + [_IOC_NR(VIDIOC_INT_S_AUDIO_ROUTING)] = "VIDIOC_INT_S_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_AUDIO_ROUTING)] = "VIDIOC_INT_G_AUDIO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_VIDEO_ROUTING)] = "VIDIOC_INT_S_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_G_VIDEO_ROUTING)] = "VIDIOC_INT_G_VIDEO_ROUTING", + [_IOC_NR(VIDIOC_INT_S_CRYSTAL_FREQ)] = "VIDIOC_INT_S_CRYSTAL_FREQ", + [_IOC_NR(VIDIOC_INT_INIT)] = "VIDIOC_INT_INIT", + [_IOC_NR(VIDIOC_INT_G_STD_OUTPUT)] = "VIDIOC_INT_G_STD_OUTPUT", + [_IOC_NR(VIDIOC_INT_S_STD_OUTPUT)] = "VIDIOC_INT_S_STD_OUTPUT", +}; +#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) + +/* Common ioctl debug function. This function can be used by + external ioctl messages as well as internal V4L ioctl */ +void v4l_printk_ioctl(unsigned int cmd) +{ + char *dir, *type; + + switch (_IOC_TYPE(cmd)) { + case 'd': + if (_IOC_NR(cmd) >= V4L2_INT_IOCTLS) { + type = "v4l2_int"; + break; + } + printk("%s", v4l2_int_ioctls[_IOC_NR(cmd)]); + return; +#ifdef CONFIG_VIDEO_V4L1_COMPAT + case 'v': + if (_IOC_NR(cmd) >= V4L1_IOCTLS) { + type = "v4l1"; + break; + } + printk("%s", v4l1_ioctls[_IOC_NR(cmd)]); + return; +#endif + case 'V': + if (_IOC_NR(cmd) >= V4L2_IOCTLS) { + type = "v4l2"; + break; + } + printk("%s", v4l2_ioctls[_IOC_NR(cmd)]); + return; + default: + type = "unknown"; + } + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "*ERR*"; break; + } + printk("%s ioctl '%c', dir=%s, #%d (0x%08x)", + type, _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); +} +EXPORT_SYMBOL(v4l_printk_ioctl); + +/* + * helper function -- handles userspace copying for ioctl arguments + */ + +#ifdef __OLD_VIDIOC_ +static unsigned int +video_fix_command(unsigned int cmd) +{ + switch (cmd) { + case VIDIOC_OVERLAY_OLD: + cmd = VIDIOC_OVERLAY; + break; + case VIDIOC_S_PARM_OLD: + cmd = VIDIOC_S_PARM; + break; + case VIDIOC_S_CTRL_OLD: + cmd = VIDIOC_S_CTRL; + break; + case VIDIOC_G_AUDIO_OLD: + cmd = VIDIOC_G_AUDIO; + break; + case VIDIOC_G_AUDOUT_OLD: + cmd = VIDIOC_G_AUDOUT; + break; + case VIDIOC_CROPCAP_OLD: + cmd = VIDIOC_CROPCAP; + break; + } + return cmd; +} +#endif + +/* + * Obsolete usercopy function - Should be removed soon + */ +int +video_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)) +{ + char sbuf[128]; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; + int is_ext_ctrl; + size_t ctrls_size = 0; + void __user *user_ptr = NULL; + +#ifdef __OLD_VIDIOC_ + cmd = video_fix_command(cmd); +#endif + is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || + cmd == VIDIOC_TRY_EXT_CTRLS); + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + parg = NULL; + break; + case _IOC_READ: + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { + parg = sbuf; + } else { + /* too big to allocate from stack */ + mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); + if (NULL == mbuf) + return -ENOMEM; + parg = mbuf; + } + + err = -EFAULT; + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) + goto out; + break; + } + if (is_ext_ctrl) { + struct v4l2_ext_controls *p = parg; + + /* In case of an error, tell the caller that it wasn't + a specific control that caused it. */ + p->error_idx = p->count; + user_ptr = (void __user *)p->controls; + if (p->count) { + ctrls_size = sizeof(struct v4l2_ext_control) * p->count; + /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ + mbuf = kmalloc(ctrls_size, GFP_KERNEL); + err = -ENOMEM; + if (NULL == mbuf) + goto out_ext_ctrl; + err = -EFAULT; + if (copy_from_user(mbuf, user_ptr, ctrls_size)) + goto out_ext_ctrl; + p->controls = mbuf; + } + } + + /* call driver */ + err = func(inode, file, cmd, parg); + if (err == -ENOIOCTLCMD) + err = -EINVAL; + if (is_ext_ctrl) { + struct v4l2_ext_controls *p = parg; + + p->controls = (void *)user_ptr; + if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) + err = -EFAULT; + goto out_ext_ctrl; + } + if (err < 0) + goto out; + +out_ext_ctrl: + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) + err = -EFAULT; + break; + } + +out: + kfree(mbuf); + return err; +} +EXPORT_SYMBOL(video_usercopy); + +static void dbgbuf(unsigned int cmd, struct video_device *vfd, + struct v4l2_buffer *p) +{ + struct v4l2_timecode *tc = &p->timecode; + + dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " + "bytesused=%d, flags=0x%08d, " + "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n", + p->timestamp.tv_sec / 3600, + (int)(p->timestamp.tv_sec / 60) % 60, + (int)(p->timestamp.tv_sec % 60), + p->timestamp.tv_usec, + p->index, + prt_names(p->type, v4l2_type_names), + p->bytesused, p->flags, + p->field, p->sequence, + prt_names(p->memory, v4l2_memory_names), + p->m.userptr, p->length); + dbgarg2("timecode=%02d:%02d:%02d type=%d, " + "flags=0x%08d, frames=%d, userbits=0x%08x\n", + tc->hours, tc->minutes, tc->seconds, + tc->type, tc->flags, tc->frames, *(__u32 *)tc->userbits); +} + +static inline void dbgrect(struct video_device *vfd, char *s, + struct v4l2_rect *r) +{ + dbgarg2("%sRect start at %dx%d, size=%dx%d\n", s, r->left, r->top, + r->width, r->height); +}; + +static inline void v4l_print_pix_fmt(struct video_device *vfd, + struct v4l2_pix_format *fmt) +{ + dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, " + "bytesperline=%d sizeimage=%d, colorspace=%d\n", + fmt->width, fmt->height, + (fmt->pixelformat & 0xff), + (fmt->pixelformat >> 8) & 0xff, + (fmt->pixelformat >> 16) & 0xff, + (fmt->pixelformat >> 24) & 0xff, + prt_names(fmt->field, v4l2_field_names), + fmt->bytesperline, fmt->sizeimage, fmt->colorspace); +}; + +static inline void v4l_print_ext_ctrls(unsigned int cmd, + struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) +{ + __u32 i; + + if (!(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) + return; + dbgarg(cmd, ""); + printk(KERN_CONT "class=0x%x", c->ctrl_class); + for (i = 0; i < c->count; i++) { + if (show_vals) + printk(KERN_CONT " id/val=0x%x/0x%x", + c->controls[i].id, c->controls[i].value); + else + printk(KERN_CONT " id=0x%x", c->controls[i].id); + } + printk(KERN_CONT "\n"); +}; + +static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) +{ + __u32 i; + + /* zero the reserved fields */ + c->reserved[0] = c->reserved[1] = 0; + for (i = 0; i < c->count; i++) { + c->controls[i].reserved2[0] = 0; + c->controls[i].reserved2[1] = 0; + } + /* V4L2_CID_PRIVATE_BASE cannot be used as control class + when using extended controls. + Only when passed in through VIDIOC_G_CTRL and VIDIOC_S_CTRL + is it allowed for backwards compatibility. + */ + if (!allow_priv && c->ctrl_class == V4L2_CID_PRIVATE_BASE) + return 0; + /* Check that all controls are from the same control class. */ + for (i = 0; i < c->count; i++) { + if (V4L2_CTRL_ID2CLASS(c->controls[i].id) != c->ctrl_class) { + c->error_idx = i; + return 0; + } + } + return 1; +} + +static int check_fmt(struct video_device *vfd, enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (vfd->vidioc_try_fmt_vid_cap) + return 0; + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (vfd->vidioc_try_fmt_vid_overlay) + return 0; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_try_fmt_vid_out) + return 0; + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_try_fmt_vid_out_overlay) + return 0; + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_vbi_cap) + return 0; + break; + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_vbi_out) + return 0; + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_sliced_vbi_cap) + return 0; + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_sliced_vbi_out) + return 0; + break; + case V4L2_BUF_TYPE_PRIVATE: + if (vfd->vidioc_try_fmt_type_private) + return 0; + break; + } + return -EINVAL; +} + +static int __video_do_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *vfd = video_devdata(file); + void *fh = file->private_data; + int ret = -EINVAL; + + if ((vfd->debug & V4L2_DEBUG_IOCTL) && + !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { + v4l_print_ioctl(vfd->name, cmd); + printk(KERN_CONT "\n"); + } + +#ifdef CONFIG_VIDEO_V4L1_COMPAT + /*********************************************************** + Handles calls to the obsoleted V4L1 API + Due to the nature of VIDIOCGMBUF, each driver that supports + V4L1 should implement its own handler for this ioctl. + ***********************************************************/ + + /* --- streaming capture ------------------------------------- */ + if (cmd == VIDIOCGMBUF) { + struct video_mbuf *p = arg; + + memset(p, 0, sizeof(*p)); + + if (!vfd->vidiocgmbuf) + return ret; + ret = vfd->vidiocgmbuf(file, fh, p); + if (!ret) + dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", + p->size, p->frames, + (unsigned long)p->offsets); + return ret; + } + + /******************************************************** + All other V4L1 calls are handled by v4l1_compat module. + Those calls will be translated into V4L2 calls, and + __video_do_ioctl will be called again, with one or more + V4L2 ioctls. + ********************************************************/ + if (_IOC_TYPE(cmd) == 'v') + return v4l_compat_translate_ioctl(inode, file, cmd, arg, + __video_do_ioctl); +#endif + + switch (cmd) { + /* --- capabilities ------------------------------------------ */ + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *cap = (struct v4l2_capability *)arg; + memset(cap, 0, sizeof(*cap)); + + if (!vfd->vidioc_querycap) + break; + + ret = vfd->vidioc_querycap(file, fh, cap); + if (!ret) + dbgarg(cmd, "driver=%s, card=%s, bus=%s, " + "version=0x%08x, " + "capabilities=0x%08x\n", + cap->driver, cap->card, cap->bus_info, + cap->version, + cap->capabilities); + break; + } + + /* --- priority ------------------------------------------ */ + case VIDIOC_G_PRIORITY: + { + enum v4l2_priority *p = arg; + + if (!vfd->vidioc_g_priority) + break; + ret = vfd->vidioc_g_priority(file, fh, p); + if (!ret) + dbgarg(cmd, "priority is %d\n", *p); + break; + } + case VIDIOC_S_PRIORITY: + { + enum v4l2_priority *p = arg; + + if (!vfd->vidioc_s_priority) + break; + dbgarg(cmd, "setting priority to %d\n", *p); + ret = vfd->vidioc_s_priority(file, fh, *p); + break; + } + + /* --- capture ioctls ---------------------------------------- */ + case VIDIOC_ENUM_FMT: + { + struct v4l2_fmtdesc *f = arg; + enum v4l2_buf_type type; + unsigned int index; + + index = f->index; + type = f->type; + memset(f, 0, sizeof(*f)); + f->index = index; + f->type = type; + + switch (type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (vfd->vidioc_enum_fmt_vid_cap) + ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (vfd->vidioc_enum_fmt_vid_overlay) + ret = vfd->vidioc_enum_fmt_vid_overlay(file, + fh, f); + break; +#if 1 + /* V4L2_BUF_TYPE_VBI_CAPTURE should not support VIDIOC_ENUM_FMT + * according to the spec. The bttv and saa7134 drivers support + * it though, so just warn that this is deprecated and will be + * removed in the near future. */ + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_enum_fmt_vbi_cap) { + printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); + ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); + } + break; +#endif + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_enum_fmt_vid_out) + ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); + break; + case V4L2_BUF_TYPE_PRIVATE: + if (vfd->vidioc_enum_fmt_type_private) + ret = vfd->vidioc_enum_fmt_type_private(file, + fh, f); + break; + default: + break; + } + if (!ret) + dbgarg(cmd, "index=%d, type=%d, flags=%d, " + "pixelformat=%c%c%c%c, description='%s'\n", + f->index, f->type, f->flags, + (f->pixelformat & 0xff), + (f->pixelformat >> 8) & 0xff, + (f->pixelformat >> 16) & 0xff, + (f->pixelformat >> 24) & 0xff, + f->description); + break; + } + case VIDIOC_G_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; + + memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); + + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (vfd->vidioc_g_fmt_vid_cap) + ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (vfd->vidioc_g_fmt_vid_overlay) + ret = vfd->vidioc_g_fmt_vid_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_g_fmt_vid_out) + ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_g_fmt_vid_out_overlay) + ret = vfd->vidioc_g_fmt_vid_out_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_g_fmt_vbi_cap) + ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); + break; + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_g_fmt_vbi_out) + ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_g_fmt_sliced_vbi_cap) + ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, + fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_g_fmt_sliced_vbi_out) + ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, + fh, f); + break; + case V4L2_BUF_TYPE_PRIVATE: + if (vfd->vidioc_g_fmt_type_private) + ret = vfd->vidioc_g_fmt_type_private(file, + fh, f); + break; + } + + break; + } + case VIDIOC_S_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; + + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); + + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + v4l_print_pix_fmt(vfd, &f->fmt.pix); + if (vfd->vidioc_s_fmt_vid_cap) + ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (vfd->vidioc_s_fmt_vid_overlay) + ret = vfd->vidioc_s_fmt_vid_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + v4l_print_pix_fmt(vfd, &f->fmt.pix); + if (vfd->vidioc_s_fmt_vid_out) + ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_s_fmt_vid_out_overlay) + ret = vfd->vidioc_s_fmt_vid_out_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_s_fmt_vbi_cap) + ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); + break; + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_s_fmt_vbi_out) + ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_s_fmt_sliced_vbi_cap) + ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, + fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_s_fmt_sliced_vbi_out) + ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, + fh, f); + break; + case V4L2_BUF_TYPE_PRIVATE: + if (vfd->vidioc_s_fmt_type_private) + ret = vfd->vidioc_s_fmt_type_private(file, + fh, f); + break; + } + break; + } + case VIDIOC_TRY_FMT: + { + struct v4l2_format *f = (struct v4l2_format *)arg; + + /* FIXME: Should be one dump per type */ + dbgarg(cmd, "type=%s\n", prt_names(f->type, + v4l2_type_names)); + switch (f->type) { + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + if (vfd->vidioc_try_fmt_vid_cap) + ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); + break; + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (vfd->vidioc_try_fmt_vid_overlay) + ret = vfd->vidioc_try_fmt_vid_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + if (vfd->vidioc_try_fmt_vid_out) + ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); + if (!ret) + v4l_print_pix_fmt(vfd, &f->fmt.pix); + break; + case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: + if (vfd->vidioc_try_fmt_vid_out_overlay) + ret = vfd->vidioc_try_fmt_vid_out_overlay(file, + fh, f); + break; + case V4L2_BUF_TYPE_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_vbi_cap) + ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); + break; + case V4L2_BUF_TYPE_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_vbi_out) + ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: + if (vfd->vidioc_try_fmt_sliced_vbi_cap) + ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, + fh, f); + break; + case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: + if (vfd->vidioc_try_fmt_sliced_vbi_out) + ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, + fh, f); + break; + case V4L2_BUF_TYPE_PRIVATE: + if (vfd->vidioc_try_fmt_type_private) + ret = vfd->vidioc_try_fmt_type_private(file, + fh, f); + break; + } + + break; + } + /* FIXME: Those buf reqs could be handled here, + with some changes on videobuf to allow its header to be included at + videodev2.h or being merged at videodev2. + */ + case VIDIOC_REQBUFS: + { + struct v4l2_requestbuffers *p = arg; + + if (!vfd->vidioc_reqbufs) + break; + ret = check_fmt(vfd, p->type); + if (ret) + break; + + ret = vfd->vidioc_reqbufs(file, fh, p); + dbgarg(cmd, "count=%d, type=%s, memory=%s\n", + p->count, + prt_names(p->type, v4l2_type_names), + prt_names(p->memory, v4l2_memory_names)); + break; + } + case VIDIOC_QUERYBUF: + { + struct v4l2_buffer *p = arg; + + if (!vfd->vidioc_querybuf) + break; + ret = check_fmt(vfd, p->type); + if (ret) + break; + + ret = vfd->vidioc_querybuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_QBUF: + { + struct v4l2_buffer *p = arg; + + if (!vfd->vidioc_qbuf) + break; + ret = check_fmt(vfd, p->type); + if (ret) + break; + + ret = vfd->vidioc_qbuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_DQBUF: + { + struct v4l2_buffer *p = arg; + + if (!vfd->vidioc_dqbuf) + break; + ret = check_fmt(vfd, p->type); + if (ret) + break; + + ret = vfd->vidioc_dqbuf(file, fh, p); + if (!ret) + dbgbuf(cmd, vfd, p); + break; + } + case VIDIOC_OVERLAY: + { + int *i = arg; + + if (!vfd->vidioc_overlay) + break; + dbgarg(cmd, "value=%d\n", *i); + ret = vfd->vidioc_overlay(file, fh, *i); + break; + } + case VIDIOC_G_FBUF: + { + struct v4l2_framebuffer *p = arg; + + if (!vfd->vidioc_g_fbuf) + break; + ret = vfd->vidioc_g_fbuf(file, fh, arg); + if (!ret) { + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, + (unsigned long)p->base); + v4l_print_pix_fmt(vfd, &p->fmt); + } + break; + } + case VIDIOC_S_FBUF: + { + struct v4l2_framebuffer *p = arg; + + if (!vfd->vidioc_s_fbuf) + break; + dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", + p->capability, p->flags, (unsigned long)p->base); + v4l_print_pix_fmt(vfd, &p->fmt); + ret = vfd->vidioc_s_fbuf(file, fh, arg); + break; + } + case VIDIOC_STREAMON: + { + enum v4l2_buf_type i = *(int *)arg; + + if (!vfd->vidioc_streamon) + break; + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); + ret = vfd->vidioc_streamon(file, fh, i); + break; + } + case VIDIOC_STREAMOFF: + { + enum v4l2_buf_type i = *(int *)arg; + + if (!vfd->vidioc_streamoff) + break; + dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); + ret = vfd->vidioc_streamoff(file, fh, i); + break; + } + /* ---------- tv norms ---------- */ + case VIDIOC_ENUMSTD: + { + struct v4l2_standard *p = arg; + v4l2_std_id id = vfd->tvnorms, curr_id = 0; + unsigned int index = p->index, i, j = 0; + const char *descr = ""; + + /* Return norm array in a canonical way */ + for (i = 0; i <= index && id; i++) { + /* last std value in the standards array is 0, so this + while always ends there since (id & 0) == 0. */ + while ((id & standards[j].std) != standards[j].std) + j++; + curr_id = standards[j].std; + descr = standards[j].descr; + j++; + if (curr_id == 0) + break; + if (curr_id != V4L2_STD_PAL && + curr_id != V4L2_STD_SECAM && + curr_id != V4L2_STD_NTSC) + id &= ~curr_id; + } + if (i <= index) + return -EINVAL; + + v4l2_video_std_construct(p, curr_id, descr); + p->index = index; + + dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " + "framelines=%d\n", p->index, + (unsigned long long)p->id, p->name, + p->frameperiod.numerator, + p->frameperiod.denominator, + p->framelines); + + ret = 0; + break; + } + case VIDIOC_G_STD: + { + v4l2_std_id *id = arg; + + ret = 0; + /* Calls the specific handler */ + if (vfd->vidioc_g_std) + ret = vfd->vidioc_g_std(file, fh, id); + else + *id = vfd->current_norm; + + if (!ret) + dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id); + break; + } + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg, norm; + + dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id); + + norm = (*id) & vfd->tvnorms; + if (vfd->tvnorms && !norm) /* Check if std is supported */ + break; + + /* Calls the specific handler */ + if (vfd->vidioc_s_std) + ret = vfd->vidioc_s_std(file, fh, &norm); + else + ret = -EINVAL; + + /* Updates standard information */ + if (ret >= 0) + vfd->current_norm = norm; + break; + } + case VIDIOC_QUERYSTD: + { + v4l2_std_id *p = arg; + + if (!vfd->vidioc_querystd) + break; + ret = vfd->vidioc_querystd(file, fh, arg); + if (!ret) + dbgarg(cmd, "detected std=%08Lx\n", + (unsigned long long)*p); + break; + } + /* ------ input switching ---------- */ + /* FIXME: Inputs can be handled inside videodev2 */ + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *p = arg; + int i = p->index; + + if (!vfd->vidioc_enum_input) + break; + memset(p, 0, sizeof(*p)); + p->index = i; + + ret = vfd->vidioc_enum_input(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "audioset=%d, " + "tuner=%d, std=%08Lx, status=%d\n", + p->index, p->name, p->type, p->audioset, + p->tuner, + (unsigned long long)p->std, + p->status); + break; + } + case VIDIOC_G_INPUT: + { + unsigned int *i = arg; + + if (!vfd->vidioc_g_input) + break; + ret = vfd->vidioc_g_input(file, fh, i); + if (!ret) + dbgarg(cmd, "value=%d\n", *i); + break; + } + case VIDIOC_S_INPUT: + { + unsigned int *i = arg; + + if (!vfd->vidioc_s_input) + break; + dbgarg(cmd, "value=%d\n", *i); + ret = vfd->vidioc_s_input(file, fh, *i); + break; + } + + /* ------ output switching ---------- */ + case VIDIOC_ENUMOUTPUT: + { + struct v4l2_output *p = arg; + int i = p->index; + + if (!vfd->vidioc_enum_output) + break; + memset(p, 0, sizeof(*p)); + p->index = i; + + ret = vfd->vidioc_enum_output(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "audioset=0x%x, " + "modulator=%d, std=0x%08Lx\n", + p->index, p->name, p->type, p->audioset, + p->modulator, (unsigned long long)p->std); + break; + } + case VIDIOC_G_OUTPUT: + { + unsigned int *i = arg; + + if (!vfd->vidioc_g_output) + break; + ret = vfd->vidioc_g_output(file, fh, i); + if (!ret) + dbgarg(cmd, "value=%d\n", *i); + break; + } + case VIDIOC_S_OUTPUT: + { + unsigned int *i = arg; + + if (!vfd->vidioc_s_output) + break; + dbgarg(cmd, "value=%d\n", *i); + ret = vfd->vidioc_s_output(file, fh, *i); + break; + } + + /* --- controls ---------------------------------------------- */ + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *p = arg; + + if (!vfd->vidioc_queryctrl) + break; + ret = vfd->vidioc_queryctrl(file, fh, p); + if (!ret) + dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " + "step=%d, default=%d, flags=0x%08x\n", + p->id, p->type, p->name, + p->minimum, p->maximum, + p->step, p->default_value, p->flags); + else + dbgarg(cmd, "id=0x%x\n", p->id); + break; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *p = arg; + + if (vfd->vidioc_g_ctrl) + ret = vfd->vidioc_g_ctrl(file, fh, p); + else if (vfd->vidioc_g_ext_ctrls) { + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls, 1)) { + ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); + if (ret == 0) + p->value = ctrl.value; + } + } else + break; + if (!ret) + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); + else + dbgarg(cmd, "id=0x%x\n", p->id); + break; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *p = arg; + struct v4l2_ext_controls ctrls; + struct v4l2_ext_control ctrl; + + if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) + break; + + dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); + + if (vfd->vidioc_s_ctrl) { + ret = vfd->vidioc_s_ctrl(file, fh, p); + break; + } + if (!vfd->vidioc_s_ext_ctrls) + break; + + ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); + ctrls.count = 1; + ctrls.controls = &ctrl; + ctrl.id = p->id; + ctrl.value = p->value; + if (check_ext_ctrls(&ctrls, 1)) + ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); + break; + } + case VIDIOC_G_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; + + p->error_idx = p->count; + if (!vfd->vidioc_g_ext_ctrls) + break; + if (check_ext_ctrls(p, 0)) + ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + v4l_print_ext_ctrls(cmd, vfd, p, !ret); + break; + } + case VIDIOC_S_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; + + p->error_idx = p->count; + if (!vfd->vidioc_s_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p, 0)) + ret = vfd->vidioc_s_ext_ctrls(file, fh, p); + break; + } + case VIDIOC_TRY_EXT_CTRLS: + { + struct v4l2_ext_controls *p = arg; + + p->error_idx = p->count; + if (!vfd->vidioc_try_ext_ctrls) + break; + v4l_print_ext_ctrls(cmd, vfd, p, 1); + if (check_ext_ctrls(p, 0)) + ret = vfd->vidioc_try_ext_ctrls(file, fh, p); + break; + } + case VIDIOC_QUERYMENU: + { + struct v4l2_querymenu *p = arg; + + if (!vfd->vidioc_querymenu) + break; + ret = vfd->vidioc_querymenu(file, fh, p); + if (!ret) + dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", + p->id, p->index, p->name); + else + dbgarg(cmd, "id=0x%x, index=%d\n", + p->id, p->index); + break; + } + /* --- audio ---------------------------------------------- */ + case VIDIOC_ENUMAUDIO: + { + struct v4l2_audio *p = arg; + + if (!vfd->vidioc_enumaudio) + break; + ret = vfd->vidioc_enumaudio(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, + p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); + break; + } + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *p = arg; + __u32 index = p->index; + + if (!vfd->vidioc_g_audio) + break; + + memset(p, 0, sizeof(*p)); + p->index = index; + ret = vfd->vidioc_g_audio(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, + p->name, p->capability, p->mode); + else + dbgarg(cmd, "index=%d\n", p->index); + break; + } + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *p = arg; + + if (!vfd->vidioc_s_audio) + break; + dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " + "mode=0x%x\n", p->index, p->name, + p->capability, p->mode); + ret = vfd->vidioc_s_audio(file, fh, p); + break; + } + case VIDIOC_ENUMAUDOUT: + { + struct v4l2_audioout *p = arg; + + if (!vfd->vidioc_enumaudout) + break; + dbgarg(cmd, "Enum for index=%d\n", p->index); + ret = vfd->vidioc_enumaudout(file, fh, p); + if (!ret) + dbgarg2("index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); + break; + } + case VIDIOC_G_AUDOUT: + { + struct v4l2_audioout *p = arg; + + if (!vfd->vidioc_g_audout) + break; + dbgarg(cmd, "Enum for index=%d\n", p->index); + ret = vfd->vidioc_g_audout(file, fh, p); + if (!ret) + dbgarg2("index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); + break; + } + case VIDIOC_S_AUDOUT: + { + struct v4l2_audioout *p = arg; + + if (!vfd->vidioc_s_audout) + break; + dbgarg(cmd, "index=%d, name=%s, capability=%d, " + "mode=%d\n", p->index, p->name, + p->capability, p->mode); + + ret = vfd->vidioc_s_audout(file, fh, p); + break; + } + case VIDIOC_G_MODULATOR: + { + struct v4l2_modulator *p = arg; + + if (!vfd->vidioc_g_modulator) + break; + ret = vfd->vidioc_g_modulator(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, " + "capability=%d, rangelow=%d," + " rangehigh=%d, txsubchans=%d\n", + p->index, p->name, p->capability, + p->rangelow, p->rangehigh, + p->txsubchans); + break; + } + case VIDIOC_S_MODULATOR: + { + struct v4l2_modulator *p = arg; + + if (!vfd->vidioc_s_modulator) + break; + dbgarg(cmd, "index=%d, name=%s, capability=%d, " + "rangelow=%d, rangehigh=%d, txsubchans=%d\n", + p->index, p->name, p->capability, p->rangelow, + p->rangehigh, p->txsubchans); + ret = vfd->vidioc_s_modulator(file, fh, p); + break; + } + case VIDIOC_G_CROP: + { + struct v4l2_crop *p = arg; + + if (!vfd->vidioc_g_crop) + break; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + ret = vfd->vidioc_g_crop(file, fh, p); + if (!ret) + dbgrect(vfd, "", &p->c); + break; + } + case VIDIOC_S_CROP: + { + struct v4l2_crop *p = arg; + + if (!vfd->vidioc_s_crop) + break; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + dbgrect(vfd, "", &p->c); + ret = vfd->vidioc_s_crop(file, fh, p); + break; + } + case VIDIOC_CROPCAP: + { + struct v4l2_cropcap *p = arg; + + /*FIXME: Should also show v4l2_fract pixelaspect */ + if (!vfd->vidioc_cropcap) + break; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + ret = vfd->vidioc_cropcap(file, fh, p); + if (!ret) { + dbgrect(vfd, "bounds ", &p->bounds); + dbgrect(vfd, "defrect ", &p->defrect); + } + break; + } + case VIDIOC_G_JPEGCOMP: + { + struct v4l2_jpegcompression *p = arg; + + if (!vfd->vidioc_g_jpegcomp) + break; + ret = vfd->vidioc_g_jpegcomp(file, fh, p); + if (!ret) + dbgarg(cmd, "quality=%d, APPn=%d, " + "APP_len=%d, COM_len=%d, " + "jpeg_markers=%d\n", + p->quality, p->APPn, p->APP_len, + p->COM_len, p->jpeg_markers); + break; + } + case VIDIOC_S_JPEGCOMP: + { + struct v4l2_jpegcompression *p = arg; + + if (!vfd->vidioc_g_jpegcomp) + break; + dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " + "COM_len=%d, jpeg_markers=%d\n", + p->quality, p->APPn, p->APP_len, + p->COM_len, p->jpeg_markers); + ret = vfd->vidioc_s_jpegcomp(file, fh, p); + break; + } + case VIDIOC_G_ENC_INDEX: + { + struct v4l2_enc_idx *p = arg; + + if (!vfd->vidioc_g_enc_index) + break; + ret = vfd->vidioc_g_enc_index(file, fh, p); + if (!ret) + dbgarg(cmd, "entries=%d, entries_cap=%d\n", + p->entries, p->entries_cap); + break; + } + case VIDIOC_ENCODER_CMD: + { + struct v4l2_encoder_cmd *p = arg; + + if (!vfd->vidioc_encoder_cmd) + break; + memset(&p->raw, 0, sizeof(p->raw)); + ret = vfd->vidioc_encoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; + } + case VIDIOC_TRY_ENCODER_CMD: + { + struct v4l2_encoder_cmd *p = arg; + + if (!vfd->vidioc_try_encoder_cmd) + break; + memset(&p->raw, 0, sizeof(p->raw)); + ret = vfd->vidioc_try_encoder_cmd(file, fh, p); + if (!ret) + dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); + break; + } + case VIDIOC_G_PARM: + { + struct v4l2_streamparm *p = arg; + __u32 type = p->type; + + memset(p, 0, sizeof(*p)); + p->type = type; + + if (vfd->vidioc_g_parm) { + ret = vfd->vidioc_g_parm(file, fh, p); + } else { + struct v4l2_standard s; + + if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + v4l2_video_std_construct(&s, vfd->current_norm, + v4l2_norm_to_name(vfd->current_norm)); + + p->parm.capture.timeperframe = s.frameperiod; + ret = 0; + } + + dbgarg(cmd, "type=%d\n", p->type); + break; + } + case VIDIOC_S_PARM: + { + struct v4l2_streamparm *p = arg; + + if (!vfd->vidioc_s_parm) + break; + dbgarg(cmd, "type=%d\n", p->type); + ret = vfd->vidioc_s_parm(file, fh, p); + break; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *p = arg; + __u32 index = p->index; + + if (!vfd->vidioc_g_tuner) + break; + + memset(p, 0, sizeof(*p)); + p->index = index; + + ret = vfd->vidioc_g_tuner(file, fh, p); + if (!ret) + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " + "rxsubchans=0x%x, audmode=%d\n", + p->index, p->name, p->type, + p->capability, p->rangelow, + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); + break; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *p = arg; + + if (!vfd->vidioc_s_tuner) + break; + dbgarg(cmd, "index=%d, name=%s, type=%d, " + "capability=0x%x, rangelow=%d, " + "rangehigh=%d, signal=%d, afc=%d, " + "rxsubchans=0x%x, audmode=%d\n", + p->index, p->name, p->type, + p->capability, p->rangelow, + p->rangehigh, p->signal, p->afc, + p->rxsubchans, p->audmode); + ret = vfd->vidioc_s_tuner(file, fh, p); + break; + } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *p = arg; + + if (!vfd->vidioc_g_frequency) + break; + + memset(p->reserved, 0, sizeof(p->reserved)); + + ret = vfd->vidioc_g_frequency(file, fh, p); + if (!ret) + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", + p->tuner, p->type, p->frequency); + break; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *p = arg; + + if (!vfd->vidioc_s_frequency) + break; + dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", + p->tuner, p->type, p->frequency); + ret = vfd->vidioc_s_frequency(file, fh, p); + break; + } + case VIDIOC_G_SLICED_VBI_CAP: + { + struct v4l2_sliced_vbi_cap *p = arg; + __u32 type = p->type; + + if (!vfd->vidioc_g_sliced_vbi_cap) + break; + memset(p, 0, sizeof(*p)); + p->type = type; + dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); + ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); + if (!ret) + dbgarg2("service_set=%d\n", p->service_set); + break; + } + case VIDIOC_LOG_STATUS: + { + if (!vfd->vidioc_log_status) + break; + ret = vfd->vidioc_log_status(file, fh); + break; + } +#ifdef CONFIG_VIDEO_ADV_DEBUG + case VIDIOC_DBG_G_REGISTER: + { + struct v4l2_register *p = arg; + + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else if (vfd->vidioc_g_register) + ret = vfd->vidioc_g_register(file, fh, p); + break; + } + case VIDIOC_DBG_S_REGISTER: + { + struct v4l2_register *p = arg; + + if (!capable(CAP_SYS_ADMIN)) + ret = -EPERM; + else if (vfd->vidioc_s_register) + ret = vfd->vidioc_s_register(file, fh, p); + break; + } +#endif + case VIDIOC_G_CHIP_IDENT: + { + struct v4l2_chip_ident *p = arg; + + if (!vfd->vidioc_g_chip_ident) + break; + ret = vfd->vidioc_g_chip_ident(file, fh, p); + if (!ret) + dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); + break; + } + default: + { + if (!vfd->vidioc_default) + break; + ret = vfd->vidioc_default(file, fh, cmd, arg); + break; + } + case VIDIOC_S_HW_FREQ_SEEK: + { + struct v4l2_hw_freq_seek *p = arg; + + if (!vfd->vidioc_s_hw_freq_seek) + break; + dbgarg(cmd, + "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", + p->tuner, p->type, p->seek_upward, p->wrap_around); + ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); + break; + } + } /* switch */ + + if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { + if (ret < 0) { + v4l_print_ioctl(vfd->name, cmd); + printk(KERN_CONT " error %d\n", ret); + } + } + + return ret; +} + +int video_ioctl2(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + char sbuf[128]; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; + int is_ext_ctrl; + size_t ctrls_size = 0; + void __user *user_ptr = NULL; + +#ifdef __OLD_VIDIOC_ + cmd = video_fix_command(cmd); +#endif + is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || + cmd == VIDIOC_TRY_EXT_CTRLS); + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + parg = NULL; + break; + case _IOC_READ: + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { + parg = sbuf; + } else { + /* too big to allocate from stack */ + mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); + if (NULL == mbuf) + return -ENOMEM; + parg = mbuf; + } + + err = -EFAULT; + if (_IOC_DIR(cmd) & _IOC_WRITE) + if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) + goto out; + break; + } + + if (is_ext_ctrl) { + struct v4l2_ext_controls *p = parg; + + /* In case of an error, tell the caller that it wasn't + a specific control that caused it. */ + p->error_idx = p->count; + user_ptr = (void __user *)p->controls; + if (p->count) { + ctrls_size = sizeof(struct v4l2_ext_control) * p->count; + /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ + mbuf = kmalloc(ctrls_size, GFP_KERNEL); + err = -ENOMEM; + if (NULL == mbuf) + goto out_ext_ctrl; + err = -EFAULT; + if (copy_from_user(mbuf, user_ptr, ctrls_size)) + goto out_ext_ctrl; + p->controls = mbuf; + } + } + + /* Handles IOCTL */ + err = __video_do_ioctl(inode, file, cmd, parg); + if (err == -ENOIOCTLCMD) + err = -EINVAL; + if (is_ext_ctrl) { + struct v4l2_ext_controls *p = parg; + + p->controls = (void *)user_ptr; + if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) + err = -EFAULT; + goto out_ext_ctrl; + } + if (err < 0) + goto out; + +out_ext_ctrl: + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) + err = -EFAULT; + break; + } + +out: + kfree(mbuf); + return err; +} +EXPORT_SYMBOL(video_ioctl2); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 059b01c11dc1..e4b3a006c71e 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 33f702698a56..a63e11f8399b 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -59,6 +59,7 @@ #include #include #include +#include #include /*#define DEBUG*/ /* Undef me for production */ diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h index 7bbab541a309..b1b5cceb4baa 100644 --- a/drivers/media/video/zc0301/zc0301.h +++ b/drivers/media/video/zc0301/zc0301.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index c0675921fe20..e1e1b19a0aed 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -71,6 +71,7 @@ #include #include +#include #include "videocodec.h" #include diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 485df2e36132..ea5265c22983 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -35,6 +35,7 @@ #include #include #include +#include /* Version Information */ diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index 89c442eb8849..1d104096619c 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h @@ -2,6 +2,7 @@ #define __SAA7146_VV__ #include +#include #include #include diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 020d05758bd8..8bbb526a5a24 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -79,6 +79,21 @@ /* ------------------------------------------------------------------------- */ +/* Priority helper functions */ + +struct v4l2_prio_state { + atomic_t prios[4]; +}; +int v4l2_prio_init(struct v4l2_prio_state *global); +int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, + enum v4l2_priority new); +int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); +int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local); +enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); +int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local); + +/* ------------------------------------------------------------------------- */ + /* Control helper functions */ int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 185372ffa270..ad62d322e178 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -39,43 +39,6 @@ #define VFL_TYPE_RADIO 2 #define VFL_TYPE_VTX 3 -/* Video standard functions */ -extern const char *v4l2_norm_to_name(v4l2_std_id id); -extern int v4l2_video_std_construct(struct v4l2_standard *vs, - int id, const char *name); -/* Prints the ioctl in a human-readable format */ -extern void v4l_printk_ioctl(unsigned int cmd); - -/* prority handling */ -struct v4l2_prio_state { - atomic_t prios[4]; -}; -int v4l2_prio_init(struct v4l2_prio_state *global); -int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, - enum v4l2_priority new); -int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); -int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local); -enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); -int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local); - -/* names for fancy debug output */ -extern const char *v4l2_field_names[]; -extern const char *v4l2_type_names[]; - -/* Compatibility layer interface -- v4l1-compat module */ -typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); -#ifdef CONFIG_VIDEO_V4L1_COMPAT -int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, - int cmd, void *arg, v4l2_kioctl driver_ioctl); -#else -#define v4l_compat_translate_ioctl(inode,file,cmd,arg,ioctl) -EINVAL -#endif - -/* 32 Bits compatibility layer for 64 bits processors */ -extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd, - unsigned long arg); - /* * Newer version of video_device, handled by videodev2.c * This version moves redundant code from video device code to @@ -352,20 +315,12 @@ extern int video_register_device(struct video_device *vfd, int type, int nr); int video_register_device_index(struct video_device *vfd, int type, int nr, int index); void video_unregister_device(struct video_device *); -extern int video_ioctl2(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); /* helper functions to alloc / release struct video_device, the later can be used for video_device->release() */ struct video_device *video_device_alloc(void); void video_device_release(struct video_device *vfd); -/* Include support for obsoleted stuff */ -extern int video_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); - #ifdef CONFIG_VIDEO_V4L1_COMPAT #include diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h new file mode 100644 index 000000000000..685b1b62a054 --- /dev/null +++ b/include/media/v4l2-ioctl.h @@ -0,0 +1,57 @@ +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Moved from videodev2.h + * + * Some commonly needed functions for drivers (v4l2-common.o module) + */ +#ifndef _V4L2_IOCTL_H +#define _V4L2_IOCTL_H + +#include +#include +#include +#include +#include /* need __user */ +#ifdef CONFIG_VIDEO_V4L1_COMPAT +#include +#else +#include +#endif + +/* Video standard functions */ +extern const char *v4l2_norm_to_name(v4l2_std_id id); +extern int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, const char *name); +/* Prints the ioctl in a human-readable format */ +extern void v4l_printk_ioctl(unsigned int cmd); + +/* names for fancy debug output */ +extern const char *v4l2_field_names[]; +extern const char *v4l2_type_names[]; + +/* Compatibility layer interface -- v4l1-compat module */ +typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); +#ifdef CONFIG_VIDEO_V4L1_COMPAT +int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, + int cmd, void *arg, v4l2_kioctl driver_ioctl); +#else +#define v4l_compat_translate_ioctl(inode, file, cmd, arg, ioctl) (-EINVAL) +#endif + +/* 32 Bits compatibility layer for 64 bits processors */ +extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd, + unsigned long arg); + +extern int video_ioctl2(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +/* Include support for obsoleted stuff */ +extern int video_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)); + +#endif /* _V4L2_IOCTL_H */ -- cgit v1.2.3 From 2864462eaf027ff10c1df1ce57d3518332e9083c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 20 Jul 2008 20:26:54 -0300 Subject: V4L/DVB (8434): Fix x86_64 compilation and move some macros to v4l2-ioctl.h Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/compat_ioctl32.c | 2 +- drivers/media/video/stradis.c | 1 + drivers/media/video/w9968cf.c | 1 + include/media/v4l2-common.h | 22 ---------------------- include/media/v4l2-ioctl.h | 21 +++++++++++++++++++++ 5 files changed, 24 insertions(+), 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 54de0cd482e9..bd5d9de5a008 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #ifdef CONFIG_COMPAT diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index c109511f21ea..6ace8923b797 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "saa7146.h" #include "saa7146reg.h" diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 3f5a59dc5f8f..56bbeec542c5 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "w9968cf.h" #include "w9968cf_decoder.h" diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 8bbb526a5a24..07d3a9a575d1 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -28,12 +28,6 @@ #include -/* v4l debugging and diagnostics */ - -/* Debug bitmask flags to be used on V4L2 */ -#define V4L2_DEBUG_IOCTL 0x01 -#define V4L2_DEBUG_IOCTL_ARG 0x02 - /* Common printk constucts for v4l-i2c drivers. These macros create a unique prefix consisting of the driver name, the adapter number and the i2c address. */ @@ -61,22 +55,6 @@ v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \ } while (0) - -/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ -#define v4l_print_ioctl(name, cmd) \ - do { \ - printk(KERN_DEBUG "%s: ", name); \ - v4l_printk_ioctl(cmd); \ - } while (0) - -/* Use this macro in I2C drivers where 'client' is the struct i2c_client - pointer */ -#define v4l_i2c_print_ioctl(client, cmd) \ - do { \ - v4l_client_printk(KERN_DEBUG, client, ""); \ - v4l_printk_ioctl(cmd); \ - } while (0) - /* ------------------------------------------------------------------------- */ /* Priority helper functions */ diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 685b1b62a054..e319d1fffb82 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -20,6 +20,27 @@ #include #endif +/* v4l debugging and diagnostics */ + +/* Debug bitmask flags to be used on V4L2 */ +#define V4L2_DEBUG_IOCTL 0x01 +#define V4L2_DEBUG_IOCTL_ARG 0x02 + +/* Use this macro for non-I2C drivers. Pass the driver name as the first arg. */ +#define v4l_print_ioctl(name, cmd) \ + do { \ + printk(KERN_DEBUG "%s: ", name); \ + v4l_printk_ioctl(cmd); \ + } while (0) + +/* Use this macro in I2C drivers where 'client' is the struct i2c_client + pointer */ +#define v4l_i2c_print_ioctl(client, cmd) \ + do { \ + v4l_client_printk(KERN_DEBUG, client, ""); \ + v4l_printk_ioctl(cmd); \ + } while (0) + /* Video standard functions */ extern const char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, -- cgit v1.2.3 From 600176176101fc6e0e0c7468efa83203e8d3e015 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 18 Jul 2008 08:46:19 -0300 Subject: V4L/DVB (8435): gspca: Delay after reset for ov7660 and USB traces in sonixj. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 246 ++++++++++++++++++------------------- 1 file changed, 118 insertions(+), 128 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 3e68b9926956..aa4d10b823ea 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -361,6 +361,7 @@ static const __u8 mo4000_sensor_init[][8] = { }; static const __u8 ov7660_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */ +/* (delay 20ms) */ {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10}, /* Outformat ?? rawRGB */ {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */ @@ -539,13 +540,31 @@ static void reg_r(struct gspca_dev *gspca_dev, value, 0, gspca_dev->usb_buf, len, 500); + PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]); } +static void reg_w1(struct gspca_dev *gspca_dev, + __u16 value, + __u8 data) +{ + PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data); + gspca_dev->usb_buf[0] = data; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + value, + 0, + gspca_dev->usb_buf, 1, + 500); +} static void reg_w(struct gspca_dev *gspca_dev, __u16 value, const __u8 *buffer, int len) { + PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..", + value, buffer[0], buffer[1]); if (len <= sizeof gspca_dev->usb_buf) { memcpy(gspca_dev->usb_buf, buffer, len); usb_control_msg(gspca_dev->dev, @@ -571,31 +590,42 @@ static void reg_w(struct gspca_dev *gspca_dev, } } -/* I2C write 2 bytes */ -static void i2c_w2(struct gspca_dev *gspca_dev, - const __u8 *buffer) +/* I2C write 1 byte */ +static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val) { struct sd *sd = (struct sd *) gspca_dev; - __u8 mode[8]; - /* is i2c ready */ - mode[0] = 0x81 | (2 << 4); - mode[1] = sd->i2c_base; - mode[2] = buffer[0]; - mode[3] = buffer[1]; - mode[4] = 0; - mode[5] = 0; - mode[6] = 0; - mode[7] = 0x10; - reg_w(gspca_dev, 0x08, mode, 8); + PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val); + gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */ + gspca_dev->usb_buf[1] = sd->i2c_base; + gspca_dev->usb_buf[2] = reg; + gspca_dev->usb_buf[3] = val; + gspca_dev->usb_buf[4] = 0; + gspca_dev->usb_buf[5] = 0; + gspca_dev->usb_buf[6] = 0; + gspca_dev->usb_buf[7] = 0x10; + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0x08, /* value = i2c */ + 0, + gspca_dev->usb_buf, 8, + 500); } /* I2C write 8 bytes */ static void i2c_w8(struct gspca_dev *gspca_dev, const __u8 *buffer) { - reg_w(gspca_dev, 0x08, buffer, 8); - msleep(1); + memcpy(gspca_dev->usb_buf, buffer, 8); + usb_control_msg(gspca_dev->dev, + usb_sndctrlpipe(gspca_dev->dev, 0), + 0x08, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE, + 0x08, 0, /* value, index */ + gspca_dev->usb_buf, 8, + 500); } /* read 5 bytes in gspca_dev->usb_buf */ @@ -613,24 +643,21 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg) mode[6] = 0; mode[7] = 0x10; i2c_w8(gspca_dev, mode); + msleep(2); mode[0] = 0x81 | (5 << 4) | 0x02; mode[2] = 0; i2c_w8(gspca_dev, mode); + msleep(2); reg_r(gspca_dev, 0x0a, 5); } static int probesensor(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - __u8 reg02; - static const __u8 datasend[] = { 2, 0 }; - /* reg val1 val2 val3 val4 */ - i2c_w2(gspca_dev, datasend); -/* should write 0xa1 0x11 0x02 0x00 0x00 0x00 0x00 the 0x10 is add by i2cw */ + i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */ msleep(10); - reg02 = 0x66; - reg_w(gspca_dev, 0x02, ®02, 1); /* Gpio on */ + reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */ msleep(10); i2c_r5(gspca_dev, 0); /* read sensor id */ if (gspca_dev->usb_buf[0] == 0x02 @@ -642,7 +669,7 @@ static int probesensor(struct gspca_dev *gspca_dev) sd->sensor = SENSOR_HV7131R; return SENSOR_HV7131R; } - PDEBUG(D_PROBE, "Find Sensor %d %d %d", + PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x", gspca_dev->usb_buf[0], gspca_dev->usb_buf[1], gspca_dev->usb_buf[2]); PDEBUG(D_PROBE, "Sensor sn9c102P Not found"); @@ -653,8 +680,6 @@ static int configure_gpio(struct gspca_dev *gspca_dev, const __u8 *sn9c1xx) { struct sd *sd = (struct sd *) gspca_dev; - __u8 data; - __u8 regF1; const __u8 *reg9a; static const __u8 reg9a_def[] = {0x08, 0x40, 0x20, 0x10, 0x00, 0x04}; @@ -663,15 +688,13 @@ static int configure_gpio(struct gspca_dev *gspca_dev, static const __u8 reg9a_sn9c325[] = {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20}; - - regF1 = 0x00; - reg_w(gspca_dev, 0xf1, ®F1, 1); - reg_w(gspca_dev, 0x01, &sn9c1xx[0], 1); /*fixme:jfm was [1] en v1*/ + reg_w1(gspca_dev, 0xf1, 0x00); + reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/ /* configure gpio */ reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2); reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); - reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm was 3 */ + reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */ switch (sd->bridge) { case BRIDGE_SN9C325: reg9a = reg9a_sn9c325; @@ -685,35 +708,25 @@ static int configure_gpio(struct gspca_dev *gspca_dev, } reg_w(gspca_dev, 0x9a, reg9a, 6); - data = 0x60; /*fixme:jfm 60 00 00 (3) */ - reg_w(gspca_dev, 0xd4, &data, 1); + reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */ reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); switch (sd->bridge) { case BRIDGE_SN9C120: /* from win trace */ - data = 0x61; - reg_w(gspca_dev, 0x01, &data, 1); - data = 0x20; - reg_w(gspca_dev, 0x17, &data, 1); - data = 0x60; - reg_w(gspca_dev, 0x01, &data, 1); + reg_w1(gspca_dev, 0x01, 0x61); + reg_w1(gspca_dev, 0x17, 0x20); + reg_w1(gspca_dev, 0x01, 0x60); break; case BRIDGE_SN9C325: - data = 0x43; - reg_w(gspca_dev, 0x01, &data, 1); - data = 0xae; - reg_w(gspca_dev, 0x17, &data, 1); - data = 0x42; - reg_w(gspca_dev, 0x01, &data, 1); + reg_w1(gspca_dev, 0x01, 0x43); + reg_w1(gspca_dev, 0x17, 0xae); + reg_w1(gspca_dev, 0x01, 0x42); break; default: - data = 0x43; - reg_w(gspca_dev, 0x01, &data, 1); - data = 0x61; - reg_w(gspca_dev, 0x17, &data, 1); - data = 0x42; - reg_w(gspca_dev, 0x01, &data, 1); + reg_w1(gspca_dev, 0x01, 0x43); + reg_w1(gspca_dev, 0x17, 0x61); + reg_w1(gspca_dev, 0x01, 0x42); } if (sd->sensor == SENSOR_HV7131R) { @@ -770,6 +783,9 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev) { int i = 0; + i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */ + i++; + msleep(20); while (ov7660_sensor_init[i][0]) { i2c_w8(gspca_dev, ov7660_sensor_init[i]); i++; @@ -782,13 +798,11 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; __u16 product; - vendor = id->idVendor; product = id->idProduct; sd->sensor = -1; - switch (vendor) { + switch (id->idVendor) { case 0x0458: /* Genius */ /* switch (product) { case 0x7025: */ @@ -960,7 +974,7 @@ static int sd_config(struct gspca_dev *gspca_dev, } if (sd->sensor < 0) { PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", - vendor, product); + id->idVendor, product); return -EINVAL; } @@ -983,34 +997,26 @@ static int sd_open(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; /* const __u8 *sn9c1xx; */ - __u8 regF1; __u8 regGpio[] = { 0x29, 0x74 }; + __u8 regF1; /* setup a selector by bridge */ - regF1 = 0x01; - reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_w1(gspca_dev, 0xf1, 0x01); reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */ - regF1 = gspca_dev->usb_buf[0]; - reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); reg_r(gspca_dev, 0x00, 1); regF1 = gspca_dev->usb_buf[0]; switch (sd->bridge) { case BRIDGE_SN9C102P: if (regF1 != 0x11) return -ENODEV; - reg_w(gspca_dev, 0x02, ®Gpio[1], 1); + reg_w1(gspca_dev, 0x02, regGpio[1]); break; case BRIDGE_SN9C105: if (regF1 != 0x11) return -ENODEV; reg_w(gspca_dev, 0x02, regGpio, 2); break; - case BRIDGE_SN9C110: - if (regF1 != 0x12) - return -ENODEV; - regGpio[1] = 0x62; - reg_w(gspca_dev, 0x02, ®Gpio[1], 1); - break; case BRIDGE_SN9C120: if (regF1 != 0x12) return -ENODEV; @@ -1018,16 +1024,15 @@ static int sd_open(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x02, regGpio, 2); break; default: +/* case BRIDGE_SN9C110: */ /* case BRIDGE_SN9C325: */ if (regF1 != 0x12) return -ENODEV; - regGpio[1] = 0x62; - reg_w(gspca_dev, 0x02, ®Gpio[1], 1); + reg_w1(gspca_dev, 0x02, 0x62); break; } - regF1 = 0x01; - reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_w1(gspca_dev, 0xf1, 0x01); return 0; } @@ -1123,7 +1128,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) } k2 = sd->brightness >> 10; - reg_w(gspca_dev, 0x96, &k2, 1); + reg_w1(gspca_dev, 0x96, k2); } static void setcontrast(struct gspca_dev *gspca_dev) @@ -1152,7 +1157,7 @@ static void setcolors(struct gspca_dev *gspca_dev) data = (colour + 32) & 0x7f; /* blue */ else data = (-colour + 32) & 0x7f; /* red */ - reg_w(gspca_dev, 0x05, &data, 1); + reg_w1(gspca_dev, 0x05, data); } /* -- start the camera -- */ @@ -1165,7 +1170,6 @@ static void sd_start(struct gspca_dev *gspca_dev) __u8 reg17; const __u8 *sn9c1xx; int mode; - static const __u8 DC29[] = { 0x6a, 0x50, 0x00, 0x00, 0x50, 0x3c }; static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; static const __u8 CA_sn9c120[] = @@ -1179,21 +1183,20 @@ static void sd_start(struct gspca_dev *gspca_dev) /*fixme:jfm this sequence should appear at end of sd_start */ /* with - data = 0x44; - reg_w(gspca_dev, 0x01, &data, 1); */ - reg_w(gspca_dev, 0x15, &sn9c1xx[0x15], 1); - reg_w(gspca_dev, 0x16, &sn9c1xx[0x16], 1); - reg_w(gspca_dev, 0x12, &sn9c1xx[0x12], 1); - reg_w(gspca_dev, 0x13, &sn9c1xx[0x13], 1); - reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); - reg_w(gspca_dev, 0xd2, &DC29[0], 1); - reg_w(gspca_dev, 0xd3, &DC29[1], 1); - reg_w(gspca_dev, 0xc6, &DC29[2], 1); - reg_w(gspca_dev, 0xc7, &DC29[3], 1); - reg_w(gspca_dev, 0xc8, &DC29[4], 1); - reg_w(gspca_dev, 0xc9, &DC29[5], 1); + reg_w1(gspca_dev, 0x01, 0x44); */ + reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]); + reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]); + reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]); + reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]); + reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); + reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */ + reg_w1(gspca_dev, 0xd3, 0x50); + reg_w1(gspca_dev, 0xc6, 0x00); + reg_w1(gspca_dev, 0xc7, 0x00); + reg_w1(gspca_dev, 0xc8, 0x50); + reg_w1(gspca_dev, 0xc9, 0x3c); /*fixme:jfm end of ending sequence */ - reg_w(gspca_dev, 0x18, &sn9c1xx[0x18], 1); + reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); switch (sd->bridge) { case BRIDGE_SN9C325: data = 0xae; @@ -1205,11 +1208,11 @@ static void sd_start(struct gspca_dev *gspca_dev) data = 0x60; break; } - reg_w(gspca_dev, 0x17, &data, 1); - reg_w(gspca_dev, 0x05, &sn9c1xx[5], 1); - reg_w(gspca_dev, 0x07, &sn9c1xx[7], 1); - reg_w(gspca_dev, 0x06, &sn9c1xx[6], 1); - reg_w(gspca_dev, 0x14, &sn9c1xx[0x14], 1); + reg_w1(gspca_dev, 0x17, data); + reg_w1(gspca_dev, 0x05, sn9c1xx[5]); + reg_w1(gspca_dev, 0x07, sn9c1xx[7]); + reg_w1(gspca_dev, 0x06, sn9c1xx[6]); + reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]); switch (sd->bridge) { case BRIDGE_SN9C325: reg_w(gspca_dev, 0x20, regsn20_sn9c325, @@ -1217,10 +1220,8 @@ static void sd_start(struct gspca_dev *gspca_dev) for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84_sn9c325, sizeof reg84_sn9c325); - data = 0x0a; - reg_w(gspca_dev, 0x9a, &data, 1); - data = 0x60; - reg_w(gspca_dev, 0x99, &data, 1); + reg_w1(gspca_dev, 0x9a, 0x0a); + reg_w1(gspca_dev, 0x99, 0x60); break; case BRIDGE_SN9C120: reg_w(gspca_dev, 0x20, regsn20_sn9c120, @@ -1233,39 +1234,30 @@ static void sd_start(struct gspca_dev *gspca_dev) sizeof reg84_sn9c120_2); reg_w(gspca_dev, 0x84, reg84_sn9c120_3, sizeof reg84_sn9c120_3); - data = 0x05; - reg_w(gspca_dev, 0x9a, &data, 1); - data = 0x5b; - reg_w(gspca_dev, 0x99, &data, 1); + reg_w1(gspca_dev, 0x9a, 0x05); + reg_w1(gspca_dev, 0x99, 0x5b); break; default: reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20); for (i = 0; i < 8; i++) reg_w(gspca_dev, 0x84, reg84, sizeof reg84); - data = 0x08; - reg_w(gspca_dev, 0x9a, &data, 1); - data = 0x59; - reg_w(gspca_dev, 0x99, &data, 1); + reg_w1(gspca_dev, 0x9a, 0x08); + reg_w1(gspca_dev, 0x99, 0x59); break; } mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; - reg1 = 0x02; + if (mode) + reg1 = 0x46; /* 320 clk 48Mhz */ + else + reg1 = 0x06; /* 640 clk 24Mz */ reg17 = 0x61; switch (sd->sensor) { case SENSOR_HV7131R: hv7131R_InitSensor(gspca_dev); - if (mode) - reg1 = 0x46; /* 320 clk 48Mhz */ - else - reg1 = 0x06; /* 640 clk 24Mz */ break; case SENSOR_MI0360: mi0360_InitSensor(gspca_dev); - if (mode) - reg1 = 0x46; /* 320 clk 48Mhz */ - else - reg1 = 0x06; /* 640 clk 24Mz */ break; case SENSOR_MO4000: mo4000_InitSensor(gspca_dev); @@ -1274,13 +1266,13 @@ static void sd_start(struct gspca_dev *gspca_dev) reg1 = 0x06; /* clk 24Mz */ } else { reg17 = 0x22; /* 640 MCKSIZE */ - reg1 = 0x06; /* 640 clk 24Mz */ +/* reg1 = 0x06; * 640 clk 24Mz (done) */ } break; case SENSOR_OV7648: + ov7648_InitSensor(gspca_dev); reg17 = 0xa2; reg1 = 0x44; - ov7648_InitSensor(gspca_dev); /* if (mode) ; * 320x2... else @@ -1292,7 +1284,7 @@ static void sd_start(struct gspca_dev *gspca_dev) if (mode) { /* reg17 = 0x21; * 320 */ /* reg1 = 0x44; */ - reg1 = 0x46; +/* reg1 = 0x46; (done) */ } else { reg17 = 0xa2; /* 640 */ reg1 = 0x40; @@ -1321,16 +1313,16 @@ static void sd_start(struct gspca_dev *gspca_dev) /* here change size mode 0 -> VGA; 1 -> CIF */ data = 0x40 | sn9c1xx[0x18] | (mode << 4); - reg_w(gspca_dev, 0x18, &data, 1); + reg_w1(gspca_dev, 0x18, data); reg_w(gspca_dev, 0x100, qtable4, 0x40); reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40); data = sn9c1xx[0x18] | (mode << 4); - reg_w(gspca_dev, 0x18, &data, 1); + reg_w1(gspca_dev, 0x18, data); - reg_w(gspca_dev, 0x17, ®17, 1); - reg_w(gspca_dev, 0x01, ®1, 1); + reg_w1(gspca_dev, 0x17, reg17); + reg_w1(gspca_dev, 0x01, reg1); setbrightness(gspca_dev); setcontrast(gspca_dev); } @@ -1342,7 +1334,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev) { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 }; static const __u8 stopmi0360[] = { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 }; - __u8 regF1; __u8 data; const __u8 *sn9c1xx; @@ -1366,12 +1357,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev) break; } sn9c1xx = sn_tb[(int) sd->sensor]; - reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); - reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 1); - reg_w(gspca_dev, 0x01, &sn9c1xx[1], 1); - reg_w(gspca_dev, 0x01, &data, 1); - regF1 = 0x01; - reg_w(gspca_dev, 0xf1, ®F1, 1); + reg_w1(gspca_dev, 0x01, sn9c1xx[1]); + reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); + reg_w1(gspca_dev, 0x01, sn9c1xx[1]); + reg_w1(gspca_dev, 0x01, data); + reg_w1(gspca_dev, 0xf1, 0x01); } static void sd_stop0(struct gspca_dev *gspca_dev) -- cgit v1.2.3 From bb64e86c3ad55e70a8001d87c050fd3a82004d17 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 19 Jul 2008 06:49:28 -0300 Subject: V4L/DVB (8436): gspca: Version number only in the main driver. The version numbers of the subrivers will be removed as these ones will be changed for any other purpose. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8170a6937b8c..8e8d3c6121b3 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -43,8 +43,7 @@ MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0) static int video_nr = -1; @@ -1886,7 +1885,10 @@ EXPORT_SYMBOL(gspca_auto_gain_n_exposure); /* -- module insert / remove -- */ static int __init gspca_init(void) { - info("main v%s registered", version); + info("main v%d.%d.%d registered", + (DRIVER_VERSION_NUMBER >> 16) & 0xff, + (DRIVER_VERSION_NUMBER >> 8) & 0xff, + DRIVER_VERSION_NUMBER & 0xff); return 0; } static void __exit gspca_exit(void) -- cgit v1.2.3 From 63fc4a038d8ca5e2da8c14c01b16876685beacf4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 21 Jul 2008 05:42:17 -0300 Subject: V4L/DVB (8438): gspca: Lack of matrix for zc3xx - tas5130c (vf0250). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 362 +++++++++++++++++++------------------- 1 file changed, 185 insertions(+), 177 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index b761b11c5c6a..f8d6f1780a45 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -24,9 +24,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard , " "Serge A. Suchkov "); MODULE_DESCRIPTION("GSPCA ZC03xx/VC3xx USB Camera Driver"); @@ -49,7 +46,7 @@ struct sd { __u8 sharpness; char qindex; - char sensor; /* Type of image sensor chip */ + signed char sensor; /* Type of image sensor chip */ /* !! values used in different tables */ #define SENSOR_CS2102 0 #define SENSOR_CS2102K 1 @@ -2205,10 +2202,10 @@ static const struct usb_action hdcs2020xb_InitialScale[] = { }; static const struct usb_action hdcs2020b_50HZ[] = { {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ - {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ + {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0005}, /* 00,0e,05,aa */ + {0xaa, 0x19, 0x001f}, /* 00,19,1f,aa */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ {0xa0, 0x76, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,76,cc */ @@ -2226,10 +2223,10 @@ static const struct usb_action hdcs2020b_50HZ[] = { }; static const struct usb_action hdcs2020b_60HZ[] = { {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ - {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ + {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ + {0xaa, 0x19, 0x00cd}, /* 00,19,cd,aa */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ {0xa0, 0x62, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,62,cc */ @@ -2247,10 +2244,10 @@ static const struct usb_action hdcs2020b_60HZ[] = { }; static const struct usb_action hdcs2020b_NoFliker[] = { {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ - {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ - {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ - {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ - {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ + {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ + {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ + {0xaa, 0x0e, 0x0004}, /* 00,0e,04,aa */ + {0xaa, 0x19, 0x0000}, /* 00,19,00,aa */ {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* 01,90,00,cc */ {0xa0, 0x02, ZC3XX_R191_EXPOSURELIMITMID}, /* 01,91,02,cc */ {0xa0, 0x70, ZC3XX_R192_EXPOSURELIMITLOW}, /* 01,92,70,cc */ @@ -4102,27 +4099,27 @@ static const struct usb_action pas106b_Initial_com[] = { static const struct usb_action pas106b_Initial[] = { /* 176x144 */ /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* Sream and Sensor specific */ - {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ + {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* Picture size */ - {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh 00 */ - {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow B0 */ - {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh 00 */ - {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow 90 */ + {0xa0, 0x00, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0xb0, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x00, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0x90, ZC3XX_R006_FRAMEHEIGHTLOW}, /* System */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* Sream and Sensor specific */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* Sensor Interface */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Window inside sensor array */ - {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ - {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ - {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ - {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ + {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* Init the sensor */ {0xaa, 0x02, 0x0004}, {0xaa, 0x08, 0x0000}, @@ -4135,40 +4132,40 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xaa, 0x14, 0x0081}, /* Other registors */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* Frame retreiving */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* Gains */ - {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ + {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* Unknown */ {0xa0, 0x00, 0x01ad}, /* Sharpness */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Other registors */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ {0xa0, 0xf4, ZC3XX_R10B_RGB01}, @@ -4180,67 +4177,67 @@ static const struct usb_action pas106b_Initial[] = { /* 176x144 */ {0xa0, 0xf4, ZC3XX_R111_RGB21}, {0xa0, 0x58, ZC3XX_R112_RGB22}, /* Auto correction */ - {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ - {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ - {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ - {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ - {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ - {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x03, ZC3XX_R181_WINXSTART}, + {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, + {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, + {0xa0, 0x03, ZC3XX_R184_WINYSTART}, + {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, + {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* Auto exposure and white balance */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ - {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow */ - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow */ - {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow */ - {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze */ - {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, + {0xa0, 0x0c, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x18, ZC3XX_R18F_AEUNFREEZE}, /* sensor on */ {0xaa, 0x07, 0x00b1}, {0xaa, 0x05, 0x0003}, {0xaa, 0x04, 0x0001}, {0xaa, 0x03, 0x003b}, /* Gains */ - {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ - {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ + {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* Auto correction */ - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* Gains */ - {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ - {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ - {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {} }; static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* Sream and Sensor specific */ - {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* CMOSSensorSelect */ + {0xa0, 0x0f, ZC3XX_R010_CMOSSENSORSELECT}, /* Picture size */ - {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, /* FrameWidthHigh */ - {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, /* FrameWidthLow */ - {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* FrameHeightHigh */ - {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* FrameHightLow */ + {0xa0, 0x01, ZC3XX_R003_FRAMEWIDTHHIGH}, + {0xa0, 0x60, ZC3XX_R004_FRAMEWIDTHLOW}, + {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, + {0xa0, 0x20, ZC3XX_R006_FRAMEHEIGHTLOW}, /* System */ - {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* SystemOperating */ + {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* Sream and Sensor specific */ - {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ - {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* VideoControlFunction */ + {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, + {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* Sensor Interface */ - {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Compatibily Mode */ + {0xa0, 0x08, ZC3XX_R08D_COMPABILITYMODE}, /* Window inside sensor array */ - {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, /* WinXStartLow */ - {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* FirstYLow */ - {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, /* FirstxLow */ - {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, /* WinHeightLow */ - {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* WinWidthLow */ + {0xa0, 0x03, ZC3XX_R09A_WINXSTARTLOW}, + {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, + {0xa0, 0x03, ZC3XX_R11C_FIRSTXLOW}, + {0xa0, 0x28, ZC3XX_R09C_WINHEIGHTLOW}, + {0xa0, 0x68, ZC3XX_R09E_WINWIDTHLOW}, /* Init the sensor */ {0xaa, 0x02, 0x0004}, {0xaa, 0x08, 0x0000}, @@ -4253,41 +4250,41 @@ static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xaa, 0x14, 0x0081}, /* Other registors */ - {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* SensorCorrection */ + {0xa0, 0x37, ZC3XX_R101_SENSORCORRECTION}, /* Frame retreiving */ - {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* AutoAdjustFPS */ + {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* Gains */ - {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* DigitalGain */ + {0xa0, 0xa0, ZC3XX_R1A8_DIGITALGAIN}, /* Unknown */ {0xa0, 0x00, 0x01ad}, /* Sharpness */ - {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* SharpnessMode */ - {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Sharpness05 */ + {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, + {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* Other registors */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ - {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /* ????????? */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, + {0xa0, 0x80, ZC3XX_R18D_YTARGET}, /*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* Other registers */ - {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* OperationMode */ + {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* Auto exposure and white balance */ - {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* AWBStatus */ + {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /*Dead pixels */ - {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* DeadPixelsMode */ + {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* EEPROM */ - {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* EEPROMAccess */ + {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* JPEG control */ - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* ClockSetting */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ - {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, + {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */ {0xa0, 0xf4, ZC3XX_R10B_RGB01}, @@ -4299,43 +4296,43 @@ static const struct usb_action pas106b_InitialScale[] = { /* 352x288 */ {0xa0, 0xf4, ZC3XX_R111_RGB21}, {0xa0, 0x58, ZC3XX_R112_RGB22}, /* Auto correction */ - {0xa0, 0x03, ZC3XX_R181_WINXSTART}, /* WinXstart */ - {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, /* WinXWidth */ - {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, /* WinXCenter */ - {0xa0, 0x03, ZC3XX_R184_WINYSTART}, /* WinYStart */ - {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, /* WinYWidth */ - {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, /* WinYCenter */ - {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x03, ZC3XX_R181_WINXSTART}, + {0xa0, 0x08, ZC3XX_R182_WINXWIDTH}, + {0xa0, 0x16, ZC3XX_R183_WINXCENTER}, + {0xa0, 0x03, ZC3XX_R184_WINYSTART}, + {0xa0, 0x05, ZC3XX_R185_WINYWIDTH}, + {0xa0, 0x14, ZC3XX_R186_WINYCENTER}, + {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE}, /* Auto exposure and white balance */ - {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, /* ExposureLimitHigh 0 */ - {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, /* ExposureLimitMid */ - {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, /* ExposureLimitLow 0xb1 */ + {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH}, + {0xa0, 0x03, ZC3XX_R191_EXPOSURELIMITMID}, + {0xa0, 0xb1, ZC3XX_R192_EXPOSURELIMITLOW}, - {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, /* AntiFlickerHigh 0x00 */ - {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, /* AntiFlickerLow 0x00 */ - {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, /* AntiFlickerLow 0x87 */ + {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH}, + {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID}, + {0xa0, 0x87, ZC3XX_R197_ANTIFLICKERLOW}, - {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, /* AEBFreeze 0x10 0x0c */ - {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* AEBUnfreeze 0x30 0x18 */ + {0xa0, 0x10, ZC3XX_R18C_AEFREEZE}, + {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE}, /* sensor on */ {0xaa, 0x07, 0x00b1}, {0xaa, 0x05, 0x0003}, {0xaa, 0x04, 0x0001}, {0xaa, 0x03, 0x003b}, /* Gains */ - {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, /* DigitalLimitDiff */ - {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, /* DigitalGainStep */ - {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ - {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* GlobalGain */ + {0xa0, 0x20, ZC3XX_R1A9_DIGITALLIMITDIFF}, + {0xa0, 0x26, ZC3XX_R1AA_DIGITALGAINSTEP}, + {0xa0, 0xa0, ZC3XX_R11D_GLOBALGAIN}, + {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN}, /* Auto correction */ - {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x40, ZC3XX_R180_AUTOCORRECTENABLE}, {0xa1, 0x01, 0x0180}, /* AutoCorrectEnable */ - {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* AutoCorrectEnable */ + {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE}, /* Gains */ - {0xa0, 0x40, ZC3XX_R116_RGAIN}, /* RGain */ - {0xa0, 0x40, ZC3XX_R117_GGAIN}, /* GGain */ - {0xa0, 0x40, ZC3XX_R118_BGAIN}, /* BGain */ + {0xa0, 0x40, ZC3XX_R116_RGAIN}, + {0xa0, 0x40, ZC3XX_R117_GGAIN}, + {0xa0, 0x40, ZC3XX_R118_BGAIN}, {0xa0, 0x00, 0x0007}, /* AutoCorrectEnable */ {0xa0, 0xff, ZC3XX_R018_FRAMELOST}, /* Frame adjust */ @@ -4459,8 +4456,8 @@ static const struct usb_action pb03303x_Initial[] = { {0xa0, 0x50, ZC3XX_R112_RGB22}, {0xa1, 0x01, 0x0008}, - {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */ - {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */ + {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, + {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, {0xa1, 0x01, 0x01c8}, {0xa1, 0x01, 0x01c9}, {0xa1, 0x01, 0x01ca}, @@ -5984,7 +5981,7 @@ static const struct usb_action tas5130c_vf0250_Initial[] = { {0xaa, 0x1b, 0x0000}, /* 00,1b,00,aa, */ {0xaa, 0x13, 0x0002}, /* 00,13,02,aa, */ {0xaa, 0x15, 0x0004}, /* 00,15,04,aa */ - {0xaa, 0x01, 0x0000}, +/*?? {0xaa, 0x01, 0x0000}, */ {0xaa, 0x01, 0x0000}, {0xaa, 0x1a, 0x0000}, /* 00,1a,00,aa, */ {0xaa, 0x1c, 0x0017}, /* 00,1c,17,aa, */ @@ -6000,8 +5997,8 @@ static const struct usb_action tas5130c_vf0250_Initial[] = { {0xaa, 0x0f, 0x00a0}, /* 00,0f,a0,aa, */ {0xaa, 0x10, 0x0000}, /* 00,10,00,aa, */ {0xaa, 0x11, 0x00a0}, /* 00,11,a0,aa, */ - {0xa0, 0x00, 0x0039}, - {0xa1, 0x01, 0x0037}, +/*?? {0xa0, 0x00, 0x0039}, + {0xa1, 0x01, 0x0037}, */ {0xaa, 0x16, 0x0001}, /* 00,16,01,aa, */ {0xaa, 0x17, 0x00e8}, /* 00,17,e6,aa, (e6 -> e8) */ {0xaa, 0x18, 0x0002}, /* 00,18,02,aa, */ @@ -6272,7 +6269,7 @@ static void reg_w(struct usb_device *dev, __u8 value, __u16 index) { - PDEBUG(D_USBO, "reg w %02x -> [%04x]", value, index); + PDEBUG(D_USBO, "reg w [%04x] = %02x", index, value); reg_w_i(dev, value, index); } @@ -6280,17 +6277,17 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev, __u8 reg) { __u8 retbyte; - __u8 retval[2]; + __u16 retval; reg_w_i(gspca_dev->dev, reg, 0x92); reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */ msleep(25); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ - retval[0] = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ - retval[1] = reg_r_i(gspca_dev, 0x0096); /* read Hightbyte */ - PDEBUG(D_USBO, "i2c r [%02x] -> (%02x) %02x%02x", - reg, retbyte, retval[1], retval[0]); - return (retval[1] << 8) | retval[0]; + retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */ + retval |= reg_r_i(gspca_dev, 0x0096) << 8; /* read Hightbyte */ + PDEBUG(D_USBO, "i2c r [%02x] -> %04x (%02x)", + reg, retval, retbyte); + return retval; } static __u8 i2c_write(struct gspca_dev *gspca_dev, @@ -6306,7 +6303,7 @@ static __u8 i2c_write(struct gspca_dev *gspca_dev, reg_w_i(gspca_dev->dev, 0x01, 0x90); /* <- write command */ msleep(5); retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */ - PDEBUG(D_USBO, "i2c w [%02x] %02x%02x (%02x)", + PDEBUG(D_USBO, "i2c w [%02x] = %02x%02x (%02x)", reg, valH, valL, retbyte); return retbyte; } @@ -6349,6 +6346,8 @@ static void setmatrix(struct gspca_dev *gspca_dev) {0x58, 0xf4, 0xf4, 0xf4, 0x58, 0xf4, 0xf4, 0xf4, 0x58}; static const __u8 po2030_matrix[9] = {0x60, 0xf0, 0xf0, 0xf0, 0x60, 0xf0, 0xf0, 0xf0, 0x60}; + static const __u8 vf0250_matrix[9] = + {0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b}; switch (sd->sensor) { case SENSOR_GC0305: @@ -6363,8 +6362,9 @@ static void setmatrix(struct gspca_dev *gspca_dev) case SENSOR_PO2030: matrix = po2030_matrix; break; - case SENSOR_TAS5130C_VF0250: /* no matrix? */ - return; + case SENSOR_TAS5130C_VF0250: + matrix = vf0250_matrix; + break; default: /* matrix already loaded */ return; } @@ -6744,7 +6744,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) return 0x04; /* CS2102 */ start_2wr_probe(dev, 0x06); /* OmniVision */ - reg_w(dev, 0x08, 0x8d); + reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x11, 0xaa, 0x00); retbyte = i2c_read(gspca_dev, 0x11); if (retbyte != 0) { @@ -6778,7 +6778,7 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev) return 0x0c; /* ICM105A */ start_2wr_probe(dev, 0x0e); /* PAS202BCB */ - reg_w(dev, 0x08, 0x8d); + reg_w(dev, 0x08, 0x008d); i2c_write(gspca_dev, 0x03, 0xaa, 0x00); msleep(500); retbyte = i2c_read(gspca_dev, 0x03); @@ -6830,7 +6830,6 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = { {0x8001, 0x13}, {0x8000, 0x14}, /* CS2102K */ {0x8400, 0x15}, /* TAS5130K */ - {0, 0} }; static int vga_3wr_probe(struct gspca_dev *gspca_dev) @@ -6843,7 +6842,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/ reg_w(dev, 0x02, 0x0010); - reg_r(gspca_dev, 0x10); + reg_r(gspca_dev, 0x0010); reg_w(dev, 0x01, 0x0000); reg_w(dev, 0x00, 0x0010); reg_w(dev, 0x01, 0x0001); @@ -6869,17 +6868,15 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword); reg_r(gspca_dev, 0x0010); /* this is tested only once anyway */ - i = 0; - while (chipset_revision_sensor[i].revision) { + for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) { if (chipset_revision_sensor[i].revision == checkword) { sd->chip_revision = checkword; send_unknown(dev, SENSOR_PB0330); return chipset_revision_sensor[i].internal_sensor_id; } - i++; } - reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x01, 0x0000); /* check ?? */ reg_w(dev, 0x01, 0x0001); reg_w(dev, 0xdd, 0x008b); reg_w(dev, 0x0a, 0x0010); @@ -6901,8 +6898,11 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) retbyte = i2c_read(gspca_dev, 0x00); if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte); - send_unknown(dev, SENSOR_GC0305); - return retbyte; /* 0x29 = gc0305 - should continue? */ + if (retbyte == 0x11) /* VF0250 */ + return 0x0250; + if (retbyte == 0x29) /* gc0305 */ + send_unknown(dev, SENSOR_GC0305); + return retbyte; } reg_w(dev, 0x01, 0x0000); /* check OmniVision */ @@ -6918,18 +6918,18 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) return 0x06; /* OmniVision confirm ? */ } - reg_w(dev, 0x01, 0x00); - reg_w(dev, 0x00, 0x02); - reg_w(dev, 0x01, 0x10); - reg_w(dev, 0x01, 0x01); - reg_w(dev, 0xee, 0x8b); - reg_w(dev, 0x03, 0x12); + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x00, 0x0002); + reg_w(dev, 0x01, 0x0010); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0xee, 0x008b); + reg_w(dev, 0x03, 0x0012); /* msleep(150); */ - reg_w(dev, 0x01, 0x12); - reg_w(dev, 0x05, 0x12); - retbyte = i2c_read(gspca_dev, 0x00); /* ID 0 */ + reg_w(dev, 0x01, 0x0012); + reg_w(dev, 0x05, 0x0012); + retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */ checkword = retbyte << 8; - retbyte = i2c_read(gspca_dev, 0x01); /* ID 1 */ + retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */ checkword |= retbyte; PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword); if (checkword == 0x2030) { @@ -6939,14 +6939,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev) return checkword; } - reg_w(dev, 0x01, 0x00); - reg_w(dev, 0x0a, 0x10); - reg_w(dev, 0xd3, 0x8b); - reg_w(dev, 0x01, 0x01); - reg_w(dev, 0x03, 0x12); - reg_w(dev, 0x01, 0x12); - reg_w(dev, 0x05, 0x01); - reg_w(dev, 0xd3, 0x8b); + reg_w(dev, 0x01, 0x0000); + reg_w(dev, 0x0a, 0x0010); + reg_w(dev, 0xd3, 0x008b); + reg_w(dev, 0x01, 0x0001); + reg_w(dev, 0x03, 0x0012); + reg_w(dev, 0x01, 0x0012); + reg_w(dev, 0x05, 0x0001); + reg_w(dev, 0xd3, 0x008b); retbyte = i2c_read(gspca_dev, 0x01); if (retbyte != 0) { PDEBUG(D_PROBE, "probe 3wr vga type 0a ?"); @@ -6962,7 +6962,9 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_MC501CB: + return -1; /* don't probe */ case SENSOR_TAS5130C_VF0250: + /* may probe but with write in reg 0x0010 */ return -1; /* don't probe */ } sensor = vga_2wr_probe(gspca_dev); @@ -7010,6 +7012,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* define some sensors from the vendor/product */ sd->sharpness = 2; + sd->sensor = -1; switch (id->idVendor) { case 0x041e: /* Creative */ switch (id->idProduct) { @@ -7119,6 +7122,10 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Find Sensor GC0305"); sd->sensor = SENSOR_GC0305; break; + case 0x0250: + PDEBUG(D_PROBE, "Sensor Tas5130 (VF0250)"); + sd->sensor = SENSOR_TAS5130C_VF0250; + break; case 0x2030: PDEBUG(D_PROBE, "Find Sensor PO2030"); sd->sensor = SENSOR_PO2030; @@ -7235,6 +7242,7 @@ static void sd_start(struct gspca_dev *gspca_dev) case SENSOR_GC0305: case SENSOR_OV7620: case SENSOR_PO2030: + case SENSOR_TAS5130C_VF0250: msleep(100); /* ?? */ reg_r(gspca_dev, 0x0002); /* --> 0x40 */ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */ @@ -7605,7 +7613,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } -- cgit v1.2.3 From 903e10aa664473ce19c30c0f80ffd7bbbbd8fc33 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 22 Jul 2008 02:35:05 -0300 Subject: V4L/DVB (8440): gspca: Makes some needlessly global functions static. Signed-off-by: Adrian Bunk Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 2 +- drivers/media/video/gspca/pac207.c | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 8e8d3c6121b3..f815340511e8 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -399,7 +399,7 @@ static struct usb_host_endpoint *alt_isoc(struct usb_host_interface *alt, * This routine may be called many times when the bandwidth is too small * (the bandwidth is checked on urb submit). */ -struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) +static struct usb_host_endpoint *get_isoc_ep(struct gspca_dev *gspca_dev) { struct usb_interface *intf; struct usb_host_endpoint *ep; diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index fa7abc411090..f790746370d7 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -27,9 +27,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Hans de Goede "); MODULE_DESCRIPTION("Pixart PAC207"); MODULE_LICENSE("GPL"); @@ -208,7 +205,7 @@ static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index, } -int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) +static int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) { struct usb_device *udev = gspca_dev->dev; int err; @@ -223,8 +220,7 @@ int pac207_write_reg(struct gspca_dev *gspca_dev, u16 index, u16 value) return err; } - -int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) +static int pac207_read_reg(struct gspca_dev *gspca_dev, u16 index) { struct usb_device *udev = gspca_dev->dev; int res; @@ -609,7 +605,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) -- cgit v1.2.3 From 06ca78fa3a77c955bd46ba3dbe529c399d260aa4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 22 Jul 2008 03:45:08 -0300 Subject: V4L/DVB (8441): gspca: Bad handling of start of frames in sonixj. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index f815340511e8..0f09784631ad 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -209,6 +209,8 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev, &frame->v4l2_buf.timestamp); frame->v4l2_buf.sequence = ++gspca_dev->sequence; } else if (gspca_dev->last_packet_type == DISCARD_PACKET) { + if (packet_type == LAST_PACKET) + gspca_dev->last_packet_type = packet_type; return frame; } -- cgit v1.2.3 From 10b0e96ed9a1ce0412ef981cf6250f9de3c80b02 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Tue, 22 Jul 2008 05:35:10 -0300 Subject: V4L/DVB (8442): gspca: Remove the version from the subdrivers. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/gspca.txt | 2 +- drivers/media/video/gspca/conex.c | 5 +---- drivers/media/video/gspca/etoms.c | 5 +---- drivers/media/video/gspca/mars.c | 5 +---- drivers/media/video/gspca/ov519.c | 5 +---- drivers/media/video/gspca/pac7311.c | 5 +---- drivers/media/video/gspca/sonixb.c | 5 +---- drivers/media/video/gspca/sonixj.c | 5 +---- drivers/media/video/gspca/spca500.c | 5 +---- drivers/media/video/gspca/spca501.c | 5 +---- drivers/media/video/gspca/spca505.c | 5 +---- drivers/media/video/gspca/spca506.c | 5 +---- drivers/media/video/gspca/spca508.c | 5 +---- drivers/media/video/gspca/spca561.c | 5 +---- drivers/media/video/gspca/stk014.c | 5 +---- drivers/media/video/gspca/sunplus.c | 5 +---- drivers/media/video/gspca/t613.c | 22 ++++++++++------------ drivers/media/video/gspca/tv8532.c | 5 +---- drivers/media/video/gspca/vc032x.c | 5 +---- 19 files changed, 28 insertions(+), 81 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 0c4880af57a3..bcaf4ab383be 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -1,4 +1,4 @@ -List of the webcams know by gspca. +List of the webcams known by gspca. The modules are: gspca_main main driver diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 013d593b0c67..18c1dec2f769 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -25,9 +25,6 @@ #define CONEX_CAM 1 /* special JPEG header */ #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver"); MODULE_LICENSE("GPL"); @@ -1038,7 +1035,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 8ab4ea7201a9..6f2f1d24b7eb 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -22,9 +22,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("Etoms USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -942,7 +939,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 88c2b02f380a..a4706162f415 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -24,9 +24,6 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/Mars USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -451,7 +448,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 08d99c3b78e2..f15bec7080c9 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -24,9 +24,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("OV519 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -2169,7 +2166,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 5c052e31be4a..2267ae7cb87f 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -23,9 +23,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li"); MODULE_DESCRIPTION("Pixart PAC7311"); MODULE_LICENSE("GPL"); @@ -747,7 +744,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index dbeebe8625c5..f6bef896d3a5 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -24,9 +24,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) -static const char version[] = "2.1.8"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1464,7 +1461,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index aa4d10b823ea..35b1a3ee4c3f 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -24,9 +24,6 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1648,7 +1645,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - info("v%s registered", version); + info("registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 156206118795..8c83823745f0 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -24,9 +24,6 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1203,7 +1200,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 50e929de0203..6537acee89dd 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -23,9 +23,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA501 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -2216,7 +2213,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index ddea6e140aa8..1bb23d03f048 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -23,9 +23,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA505 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -938,7 +935,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 143203c1fd9f..40e8541b2b89 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -25,9 +25,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA506 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -834,7 +831,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index d8cd93866a4a..362f645d08c6 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -22,9 +22,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA508 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1778,7 +1775,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index b659bd0f788d..85c37f396aaf 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -24,9 +24,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1039,7 +1036,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index c78ee0d3e59b..90efde17b08b 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -23,9 +23,6 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Jean-Francois Moine "); MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -576,7 +573,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - info("v%s registered", version); + info("registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index abd7bef9b3d1..53e20275f26d 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -24,9 +24,6 @@ #include "gspca.h" #include "jpeg.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 8) -static const char version[] = "2.1.8"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/SPCA5xx USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1664,7 +1661,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index 00f47e463a05..fc1c62e5a2fd 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -1,12 +1,4 @@ /* - *Notes: * t613 + tas5130A - * * Focus to light do not balance well as in win. - * Quality in win is not good, but its kinda better. - * * Fix some "extraneous bytes", most of apps will show the image anyway - * * Gamma table, is there, but its really doing something? - * * 7~8 Fps, its ok, max on win its 10. - * Costantino Leandro - * * V4L2 by Jean-Francois Moine * * This program is free software; you can redistribute it and/or modify @@ -22,16 +14,22 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + *Notes: * t613 + tas5130A + * * Focus to light do not balance well as in win. + * Quality in win is not good, but its kinda better. + * * Fix some "extraneous bytes", most of apps will show the image anyway + * * Gamma table, is there, but its really doing something? + * * 7~8 Fps, its ok, max on win its 10. + * Costantino Leandro */ #define MODULE_NAME "t613" + #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; #define MAX_GAMMA 0x10 /* 0 to 15 */ -/* From LUVCVIEW */ #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 3) MODULE_AUTHOR("Leandro Costantino "); @@ -1025,7 +1023,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index 0b793899095f..cb2d9da2a224 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -22,9 +22,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("TV8532 USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -656,7 +653,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index fcf2c9e32573..e306ac420298 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -24,9 +24,6 @@ #include "gspca.h" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) -static const char version[] = "2.1.7"; - MODULE_AUTHOR("Michel Xhaard "); MODULE_DESCRIPTION("GSPCA/VC032X USB Camera Driver"); MODULE_LICENSE("GPL"); @@ -1805,7 +1802,7 @@ static int __init sd_mod_init(void) { if (usb_register(&sd_driver) < 0) return -1; - PDEBUG(D_PROBE, "v%s registered", version); + PDEBUG(D_PROBE, "registered"); return 0; } static void __exit sd_mod_exit(void) -- cgit v1.2.3 From 4c7827eec78abe6fe68fd29305806467f2a51e63 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 7 Jul 2008 20:04:29 -0300 Subject: V4L/DVB (8234a): uvcvideo: Fix build for uvc input Fix a bug introduced by some trouble on my -git tree that resulted on a hunk to be lost (probably caused by some rebase). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index f606d2951fde..2a747db6dc3e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -806,13 +806,7 @@ menuconfig V4L_USB_DRIVERS if V4L_USB_DRIVERS && USB -config USB_VIDEO_CLASS - tristate "USB Video Class (UVC)" - ---help--- - Support for the USB Video Class (UVC). Currently only video - input devices, such as webcams, are supported. - - For more information see: +source "drivers/media/video/uvc/Kconfig" source "drivers/media/video/gspca/Kconfig" -- cgit v1.2.3 From 27ac792ca0b0a1e7e65f20342260650516c95864 Mon Sep 17 00:00:00 2001 From: Andrea Righi Date: Wed, 23 Jul 2008 21:28:13 -0700 Subject: PAGE_ALIGN(): correctly handle 64-bit values on 32-bit architectures On 32-bit architectures PAGE_ALIGN() truncates 64-bit values to the 32-bit boundary. For example: u64 val = PAGE_ALIGN(size); always returns a value < 4GB even if size is greater than 4GB. The problem resides in PAGE_MASK definition (from include/asm-x86/page.h for example): #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) ... #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) The "~" is performed on a 32-bit value, so everything in "and" with PAGE_MASK greater than 4GB will be truncated to the 32-bit boundary. Using the ALIGN() macro seems to be the right way, because it uses typeof(addr) for the mask. Also move the PAGE_ALIGN() definitions out of include/asm-*/page.h in include/linux/mm.h. See also lkml discussion: http://lkml.org/lkml/2008/6/11/237 [akpm@linux-foundation.org: fix drivers/media/video/uvc/uvc_queue.c] [akpm@linux-foundation.org: fix v850] [akpm@linux-foundation.org: fix powerpc] [akpm@linux-foundation.org: fix arm] [akpm@linux-foundation.org: fix mips] [akpm@linux-foundation.org: fix drivers/media/video/pvrusb2/pvrusb2-dvb.c] [akpm@linux-foundation.org: fix drivers/mtd/maps/uclinux.c] [akpm@linux-foundation.org: fix powerpc] Signed-off-by: Andrea Righi Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kernel/module.c | 1 + arch/arm/plat-omap/fb.c | 1 + arch/avr32/mm/ioremap.c | 1 + arch/h8300/kernel/setup.c | 1 + arch/m68k/amiga/chipram.c | 1 + arch/m68knommu/kernel/setup.c | 1 + arch/mips/kernel/module.c | 1 + arch/mips/sgi-ip27/ip27-klnuma.c | 1 + arch/powerpc/kernel/suspend.c | 1 + arch/powerpc/lib/code-patching.c | 1 + arch/sparc64/kernel/iommu_common.h | 2 +- arch/x86/kernel/module_64.c | 1 + arch/xtensa/kernel/setup.c | 1 + drivers/char/random.c | 1 + drivers/ieee1394/iso.c | 1 + drivers/media/video/pvrusb2/pvrusb2-dvb.c | 1 + drivers/media/video/pvrusb2/pvrusb2-ioread.c | 1 + drivers/media/video/uvc/uvc_queue.c | 1 + drivers/media/video/videobuf-core.c | 1 + drivers/mtd/maps/uclinux.c | 1 + drivers/net/mlx4/eq.c | 1 + drivers/pcmcia/electra_cf.c | 1 + drivers/scsi/sun_esp.c | 1 + drivers/video/acornfb.c | 1 + drivers/video/imxfb.c | 1 + drivers/video/omap/dispc.c | 1 + drivers/video/omap/omapfb_main.c | 1 + drivers/video/pxafb.c | 1 + drivers/video/sa1100fb.c | 1 + include/asm-alpha/page.h | 3 --- include/asm-arm/page-nommu.h | 4 +--- include/asm-arm/page.h | 3 --- include/asm-avr32/page.h | 3 --- include/asm-blackfin/page.h | 3 --- include/asm-cris/page.h | 3 --- include/asm-frv/page.h | 3 --- include/asm-h8300/page.h | 3 --- include/asm-ia64/page.h | 1 - include/asm-m32r/page.h | 3 --- include/asm-m68k/dvma.h | 2 +- include/asm-m68k/page.h | 3 --- include/asm-m68knommu/page.h | 3 --- include/asm-mips/page.h | 3 --- include/asm-mips/processor.h | 2 +- include/asm-mn10300/page.h | 3 --- include/asm-parisc/page.h | 4 ---- include/asm-powerpc/page.h | 3 --- include/asm-s390/page.h | 3 --- include/asm-sh/page.h | 3 --- include/asm-sparc/page_32.h | 3 --- include/asm-sparc/page_64.h | 3 --- include/asm-um/page.h | 3 --- include/asm-v850/page.h | 4 ---- include/asm-x86/page.h | 3 --- include/asm-xtensa/page.h | 2 -- include/linux/mm.h | 3 +++ sound/core/info.c | 1 + 57 files changed, 36 insertions(+), 74 deletions(-) (limited to 'drivers/media') diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 79b7e5cf5416..a68259a0cccd 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c index 96d6f0619733..5d107520e6b9 100644 --- a/arch/arm/plat-omap/fb.c +++ b/arch/arm/plat-omap/fb.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c index 3437c82434ac..f03b79f0e0ab 100644 --- a/arch/avr32/mm/ioremap.c +++ b/arch/avr32/mm/ioremap.c @@ -6,6 +6,7 @@ * published by the Free Software Foundation. */ #include +#include #include #include diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index b1f25c20a5db..7fda657110eb 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index cbe36538af47..61df1d33c050 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 03f4fe6a2fc0..5985f1989021 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index e7ed0ac48537..1f60e27523d9 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 48932ce1d730..d9c79d8be81d 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c @@ -4,6 +4,7 @@ * Copyright 2000 - 2001 Kanoj Sarcar (kanoj@sgi.com) */ #include +#include #include #include #include diff --git a/arch/powerpc/kernel/suspend.c b/arch/powerpc/kernel/suspend.c index 8cee57107541..6fc6328dc626 100644 --- a/arch/powerpc/kernel/suspend.c +++ b/arch/powerpc/kernel/suspend.c @@ -7,6 +7,7 @@ * Copyright (c) 2001 Patrick Mochel */ +#include #include /* References to section boundaries */ diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 0559fe086eb4..7c975d43e3f3 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h index f3575a614fa2..53b19c8231a9 100644 --- a/arch/sparc64/kernel/iommu_common.h +++ b/arch/sparc64/kernel/iommu_common.h @@ -23,7 +23,7 @@ #define IO_PAGE_SHIFT 13 #define IO_PAGE_SIZE (1UL << IO_PAGE_SHIFT) #define IO_PAGE_MASK (~(IO_PAGE_SIZE-1)) -#define IO_PAGE_ALIGN(addr) (((addr)+IO_PAGE_SIZE-1)&IO_PAGE_MASK) +#define IO_PAGE_ALIGN(addr) ALIGN(addr, IO_PAGE_SIZE) #define IO_TSB_ENTRIES (128*1024) #define IO_TSB_SIZE (IO_TSB_ENTRIES * 8) diff --git a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c index 0e867676b5a5..6ba87830d4b1 100644 --- a/arch/x86/kernel/module_64.c +++ b/arch/x86/kernel/module_64.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 5e6d75c9f92b..a00359e8f7a8 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/char/random.c b/drivers/char/random.c index 0cf98bd4f2d2..e0d0e371909c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -236,6 +236,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c index 07ca35c98f96..1cf6487b65ba 100644 --- a/drivers/ieee1394/iso.c +++ b/drivers/ieee1394/iso.c @@ -11,6 +11,7 @@ #include #include +#include #include #include "hosts.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c index 6ec4bf81fc7f..77b3c3385066 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c +++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c @@ -20,6 +20,7 @@ #include #include +#include #include "dvbdev.h" #include "pvrusb2-debug.h" #include "pvrusb2-hdw-internal.h" diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c index 05a1376405e7..b4824782d858 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c @@ -22,6 +22,7 @@ #include "pvrusb2-debug.h" #include #include +#include #include #include #include diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 7388d0cee3d4..5646a6a32939 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -13,6 +13,7 @@ #include #include +#include #include #include #include diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c index 0a88c44ace00..b7b05842cf28 100644 --- a/drivers/media/video/videobuf-core.c +++ b/drivers/media/video/videobuf-core.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index c42f4b83f686..3fcf92130aa4 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index e141a1513f07..ea3a09aaa844 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index c21f9a9c3e3f..a34284b1482a 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c index 2c87db98cdfb..f9cf70151366 100644 --- a/drivers/scsi/sun_esp.c +++ b/drivers/scsi/sun_esp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index eedb8285e32f..017233d0c481 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 94e4d3ac1a05..0c5a475c1cae 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c index ab32ceb06178..ab77c51fe9d6 100644 --- a/drivers/video/omap/dispc.c +++ b/drivers/video/omap/dispc.c @@ -20,6 +20,7 @@ */ #include #include +#include #include #include #include diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 14d0f7a11145..f85af5c4fa68 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -25,6 +25,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index bb2514369507..5e8a140399fc 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index ab2b2110478b..4a9f7e121807 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -167,6 +167,7 @@ #include #include #include +#include #include #include #include diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h index 22ff9762d17b..0995f9d13417 100644 --- a/include/asm-alpha/page.h +++ b/include/asm-alpha/page.h @@ -80,9 +80,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #ifndef CONFIG_DISCONTIGMEM diff --git a/include/asm-arm/page-nommu.h b/include/asm-arm/page-nommu.h index a1bcad060480..ea1cde84f500 100644 --- a/include/asm-arm/page-nommu.h +++ b/include/asm-arm/page-nommu.h @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ + #ifndef _ASMARM_PAGE_NOMMU_H #define _ASMARM_PAGE_NOMMU_H @@ -42,9 +43,6 @@ typedef unsigned long pgprot_t; #define __pmd(x) (x) #define __pgprot(x) (x) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 8e05bdb5f12f..7c5fc5582e5d 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h @@ -15,9 +15,6 @@ #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #ifndef CONFIG_MMU diff --git a/include/asm-avr32/page.h b/include/asm-avr32/page.h index cbbc5ca9728b..f805d1cb11bc 100644 --- a/include/asm-avr32/page.h +++ b/include/asm-avr32/page.h @@ -57,9 +57,6 @@ static inline int get_order(unsigned long size) #endif /* !__ASSEMBLY__ */ -/* Align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff * permanently to the physical addresses 0x00000000 -> 0x1fffffff when diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h index c7db0220fbd6..344f6a8c1f22 100644 --- a/include/asm-blackfin/page.h +++ b/include/asm-blackfin/page.h @@ -51,9 +51,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-cris/page.h b/include/asm-cris/page.h index c45bb1ef397c..d19272ba6b69 100644 --- a/include/asm-cris/page.h +++ b/include/asm-cris/page.h @@ -60,9 +60,6 @@ typedef struct page *pgtable_t; #define page_to_phys(page) __pa((((page) - mem_map) << PAGE_SHIFT) + PAGE_OFFSET) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h index c2c1e89e747d..bd9c220094c7 100644 --- a/include/asm-frv/page.h +++ b/include/asm-frv/page.h @@ -40,9 +40,6 @@ typedef struct page *pgtable_t; #define __pgprot(x) ((pgprot_t) { (x) } ) #define PTE_MASK PAGE_MASK -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - #define devmem_is_allowed(pfn) 1 #define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h index d6a3eaf3b27e..0b6acf0b03aa 100644 --- a/include/asm-h8300/page.h +++ b/include/asm-h8300/page.h @@ -43,9 +43,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 36f39321b768..5f271bc712ee 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -40,7 +40,6 @@ #define PAGE_SIZE (__IA64_UL_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE - 1)) -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) #define PERCPU_PAGE_SHIFT 16 /* log2() of max. size of per-CPU area */ #define PERCPU_PAGE_SIZE (__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT) diff --git a/include/asm-m32r/page.h b/include/asm-m32r/page.h index 8a677f3fca68..c9333089fe11 100644 --- a/include/asm-m32r/page.h +++ b/include/asm-m32r/page.h @@ -41,9 +41,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * This handles the memory map.. We could make this a config * option, but too many people screw it up, and too few need diff --git a/include/asm-m68k/dvma.h b/include/asm-m68k/dvma.h index 4fff408d0150..890bbf7e7758 100644 --- a/include/asm-m68k/dvma.h +++ b/include/asm-m68k/dvma.h @@ -13,7 +13,7 @@ #define DVMA_PAGE_SHIFT 13 #define DVMA_PAGE_SIZE (1UL << DVMA_PAGE_SHIFT) #define DVMA_PAGE_MASK (~(DVMA_PAGE_SIZE-1)) -#define DVMA_PAGE_ALIGN(addr) (((addr)+DVMA_PAGE_SIZE-1)&DVMA_PAGE_MASK) +#define DVMA_PAGE_ALIGN(addr) ALIGN(addr, DVMA_PAGE_SIZE) extern void dvma_init(void); extern int dvma_map_iommu(unsigned long kaddr, unsigned long baddr, diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index 880c2cbff8a6..a34b8bad7847 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h @@ -103,9 +103,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #endif /* !__ASSEMBLY__ */ #include diff --git a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h index 1e82ebb7d644..3a1ede4544cb 100644 --- a/include/asm-m68knommu/page.h +++ b/include/asm-m68knommu/page.h @@ -43,9 +43,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long memory_start; extern unsigned long memory_end; diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index 494f00ba9541..fe7a88ea066e 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -137,9 +137,6 @@ typedef struct { unsigned long pgprot; } pgprot_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * __pa()/__va() should be used only during mem init. */ diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 58cbac5a64e4..a1e4453469f9 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_count; * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ -#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3)) +#define TASK_UNMAPPED_BASE ((TASK_SIZE / 3) & ~(PAGE_SIZE)) #endif #ifdef CONFIG_64BIT diff --git a/include/asm-mn10300/page.h b/include/asm-mn10300/page.h index 124971b9fb9b..8288e124165b 100644 --- a/include/asm-mn10300/page.h +++ b/include/asm-mn10300/page.h @@ -61,9 +61,6 @@ typedef struct page *pgtable_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - /* * This handles the memory map.. We could make this a config * option, but too many people screw it up, and too few need diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 27d50b859541..c3941f09a878 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h @@ -119,10 +119,6 @@ extern int npmem_ranges; #define PMD_ENTRY_SIZE (1UL << BITS_PER_PMD_ENTRY) #define PTE_ENTRY_SIZE (1UL << BITS_PER_PTE_ENTRY) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - - #define LINUX_GATEWAY_SPACE 0 /* This governs the relationship between virtual and physical addresses. diff --git a/include/asm-powerpc/page.h b/include/asm-powerpc/page.h index cffdf0eb0df6..e088545cb3f5 100644 --- a/include/asm-powerpc/page.h +++ b/include/asm-powerpc/page.h @@ -119,9 +119,6 @@ extern phys_addr_t kernstart_addr; /* align addr on a size boundary - adjust address up if needed */ #define _ALIGN(addr,size) _ALIGN_UP(addr,size) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) - /* * Don't compare things with KERNELBASE or PAGE_OFFSET to test for * "kernelness", use is_kernel_addr() - it should do what you want. diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index 12fd9c4f0f15..991ba939408c 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h @@ -138,9 +138,6 @@ void arch_alloc_page(struct page *page, int order); #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define __PAGE_OFFSET 0x0UL #define PAGE_OFFSET 0x0UL #define __pa(x) (unsigned long)(x) diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h index 304c30b5d947..5dc01d2fcc4c 100644 --- a/include/asm-sh/page.h +++ b/include/asm-sh/page.h @@ -22,9 +22,6 @@ #define PAGE_MASK (~(PAGE_SIZE-1)) #define PTE_MASK PAGE_MASK -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #if defined(CONFIG_HUGETLB_PAGE_SIZE_64K) #define HPAGE_SHIFT 16 #elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K) diff --git a/include/asm-sparc/page_32.h b/include/asm-sparc/page_32.h index 14de518cc38f..cf5fb70ca1c1 100644 --- a/include/asm-sparc/page_32.h +++ b/include/asm-sparc/page_32.h @@ -134,9 +134,6 @@ BTFIXUPDEF_SETHI(sparc_unmapped_base) #endif /* !(__ASSEMBLY__) */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #define PAGE_OFFSET 0xf0000000 #ifndef __ASSEMBLY__ extern unsigned long phys_base; diff --git a/include/asm-sparc/page_64.h b/include/asm-sparc/page_64.h index a8a2bba032c1..b579b910ef51 100644 --- a/include/asm-sparc/page_64.h +++ b/include/asm-sparc/page_64.h @@ -106,9 +106,6 @@ typedef struct page *pgtable_t; #endif /* !(__ASSEMBLY__) */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - /* We used to stick this into a hard-coded global register (%g4) * but that does not make sense anymore. */ diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 916e1a61999f..335c57383c02 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h @@ -92,9 +92,6 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) } ) #define __pgprot(x) ((pgprot_t) { (x) } ) -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - extern unsigned long uml_physmem; #define PAGE_OFFSET (uml_physmem) diff --git a/include/asm-v850/page.h b/include/asm-v850/page.h index 74a539a9bd59..f9de35d873fa 100644 --- a/include/asm-v850/page.h +++ b/include/asm-v850/page.h @@ -94,10 +94,6 @@ typedef unsigned long pgprot_t; #endif /* !__ASSEMBLY__ */ -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) - - /* No current v850 processor has virtual memory. */ #define __virt_to_phys(addr) (addr) #define __phys_to_virt(addr) (addr) diff --git a/include/asm-x86/page.h b/include/asm-x86/page.h index 6e02098b1605..49982110e4d9 100644 --- a/include/asm-x86/page.h +++ b/include/asm-x86/page.h @@ -34,9 +34,6 @@ #define HUGE_MAX_HSTATE 2 -/* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) - #ifndef __ASSEMBLY__ #include #endif diff --git a/include/asm-xtensa/page.h b/include/asm-xtensa/page.h index 80a6ae0dd259..11f7dc2dbec7 100644 --- a/include/asm-xtensa/page.h +++ b/include/asm-xtensa/page.h @@ -26,13 +26,11 @@ /* * PAGE_SHIFT determines the page size - * PAGE_ALIGN(x) aligns the pointer to the (next) page boundary */ #define PAGE_SHIFT 12 #define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE - 1) & PAGE_MASK) #define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR #define MAX_MEM_PFN XCHAL_KSEG_SIZE diff --git a/include/linux/mm.h b/include/linux/mm.h index df322fb4df31..d87a5a5fe87d 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -41,6 +41,9 @@ extern unsigned long mmap_min_addr; #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n)) +/* to align the pointer to the (next) page boundary */ +#define PAGE_ALIGN(addr) ALIGN(addr, PAGE_SIZE) + /* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way diff --git a/sound/core/info.c b/sound/core/info.c index cb5ead3e202d..c67773ad9298 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From e5b13acf563e98ffc5dea8bebf80299a2a4ea088 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Jul 2008 14:37:55 -0300 Subject: V4L/DVB (8451): dw2102: fix in-kernel compilation Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/dw2102.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h index cb5873752e46..7a310f906837 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.h +++ b/drivers/media/dvb/dvb-usb/dw2102.h @@ -2,7 +2,7 @@ #define _DW2102_H_ #define DVB_USB_LOG_PREFIX "dw2102" -#include +#include "dvb-usb.h" extern int dvb_usb_dw2102_debug; #define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) -- cgit v1.2.3 From c5e0bd1a982ee449b3598600f85895dc3bc8c13f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Jul 2008 23:17:36 -0300 Subject: V4L/DVB (8453): sms1xxx: dvb/siano/: cleanups This patch contains the following cleanups: - mark smscore_module_init() as __init - mark smscore_module_exit as __exit - make the following needlessly global code static: - smscoreapi.c: struct g_smscore_notifyees - smscoreapi.c: struct g_smscore_devices - smscoreapi.c: struct g_smscore_deviceslock - smscoreapi.c: struct g_smscore_registry - smscoreapi.c: struct g_smscore_registrylock - smscoreapi.c: smscore_module_init() - smscoreapi.c: smscore_module_exit() - smsdvb.c: struct g_smsdvb_clients - smsdvb.c: struct g_smsdvb_clientslock Signed-off-by: Adrian Bunk Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/siano/smscoreapi.c | 14 +++++++------- drivers/media/dvb/siano/smsdvb.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index b4b8ed795c95..c5f45fed69dc 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -110,12 +110,12 @@ struct smscore_registry_entry_t { enum sms_device_type_st type; }; -struct list_head g_smscore_notifyees; -struct list_head g_smscore_devices; -struct mutex g_smscore_deviceslock; +static struct list_head g_smscore_notifyees; +static struct list_head g_smscore_devices; +static struct mutex g_smscore_deviceslock; -struct list_head g_smscore_registry; -struct mutex g_smscore_registrylock; +static struct list_head g_smscore_registry; +static struct mutex g_smscore_registrylock; static int default_mode = 4; @@ -1187,7 +1187,7 @@ int smsclient_sendrequest(struct smscore_client_t *client, } -int smscore_module_init(void) +static int __init smscore_module_init(void) { int rc = 0; @@ -1209,7 +1209,7 @@ int smscore_module_init(void) return rc; } -void smscore_module_exit(void) +static void __exit smscore_module_exit(void) { kmutex_lock(&g_smscore_deviceslock); diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 6f9c18563867..229274a14110 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c @@ -27,8 +27,8 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -struct list_head g_smsdvb_clients; -struct mutex g_smsdvb_clientslock; +static struct list_head g_smsdvb_clients; +static struct mutex g_smsdvb_clientslock; static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { -- cgit v1.2.3 From 6af492e56648e786e0dfb84d538fb7f9ecc02504 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Jul 2008 07:09:33 -0300 Subject: V4L/DVB (8455): gspca_sonixb sn9c103 + ov7630 autoexposure and cleanup Andoni Zubimendi has been doing some testing with his sn9c103 cam with ov7630 sensor, and with this patch the exposure setting and autoexposure now work. This patch also removes some special cases in the shared ov6650 / ov7630 code which now are handled the same for both sensors and it adds a new special case which stops us from changing the hsync / vsync polarity settings from their default on the ov7630 (which we were doing as a side-effect of using the ov6650 exposure code for the ov7630). Last this patch removes the superficial difference between the OV7630 and OV7630_3 sensors. Signed-off-by: Andoni Zubimendi Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 174 +++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 92 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f6bef896d3a5..4f9c9ecb06e8 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -41,6 +41,7 @@ struct sd { unsigned char brightness; unsigned char autogain; unsigned char autogain_ignore_frames; + unsigned char frames_to_drop; unsigned char freq; /* light freq filter setting */ unsigned char saturation; unsigned char hue; @@ -51,13 +52,13 @@ struct sd { #define SENSOR_HV7131R 0 #define SENSOR_OV6650 1 #define SENSOR_OV7630 2 -#define SENSOR_OV7630_3 3 -#define SENSOR_PAS106 4 -#define SENSOR_PAS202 5 -#define SENSOR_TAS5110 6 -#define SENSOR_TAS5130CXX 7 +#define SENSOR_PAS106 3 +#define SENSOR_PAS202 4 +#define SENSOR_TAS5110 5 +#define SENSOR_TAS5130CXX 6 char sensor_has_gain; __u8 sensor_addr; + __u8 reg11; }; #define COMP2 0x8f @@ -318,7 +319,7 @@ static const __u8 initOv7630_3[] = { 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */ 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */ }; -static const __u8 ov7630_sensor_init_com[][8] = { +static const __u8 ov7630_sensor_init[][8] = { {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10}, /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */ @@ -339,17 +340,6 @@ static const __u8 ov7630_sensor_init_com[][8] = { {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10}, {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10}, }; -static const __u8 ov7630_sensor_init[][8] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */ - {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10}, /* jfm */ - {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16}, - {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15}, /* gain */ -}; -static const __u8 ov7630_sensor_init_3[][8] = { - {0xa0, 0x21, 0x2a, 0xa0, 0x00, 0x00, 0x00, 0x10}, - {0xa0, 0x21, 0x2a, 0x80, 0x00, 0x00, 0x00, 0x10}, -}; static const __u8 initPas106[] = { 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00, @@ -539,7 +529,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV6650: - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2cOV[] = {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}; @@ -632,7 +621,7 @@ static void setsensorgain(struct gspca_dev *gspca_dev) case SENSOR_OV6650: gain >>= 1; /* fall thru */ - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -687,7 +676,7 @@ static void setexposure(struct gspca_dev *gspca_dev) break; } case SENSOR_OV6650: - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { /* The ov6650 / ov7630 have 2 registers which both influence exposure, register 11, whose low nibble sets the nr off fps according to: fps = 30 / (low_nibble + 1) @@ -702,16 +691,20 @@ static void setexposure(struct gspca_dev *gspca_dev) The code maps our 0 - 510 ms exposure ctrl to these 2 registers, trying to keep fps as high as possible. */ - __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0xc0, 0x00, 0x00, 0x10}; - int reg10, reg11; + __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10}; + int reg10, reg11, reg10_max; + /* ov6645 datasheet says reg10_max is 9a, but that uses tline * 2 * reg10 as formula for calculating texpo, the ov6650 probably uses the same formula as the 7730 which uses tline * 4 * reg10, which explains why the reg10max we've found experimentally for the ov6650 is exactly half that of the ov6645. The ov7630 datasheet says the max is 0x41. */ - const int reg10_max = (sd->sensor == SENSOR_OV6650) - ? 0x4d : 0x41; + if (sd->sensor == SENSOR_OV6650) { + reg10_max = 0x4d; + i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */ + } else + reg10_max = 0x41; reg11 = (60 * sd->exposure + 999) / 1000; if (reg11 < 1) @@ -732,20 +725,23 @@ static void setexposure(struct gspca_dev *gspca_dev) else if (reg10 > reg10_max) reg10 = reg10_max; + /* In 640x480, if the reg11 has less than 3, the image is + unstable (not enough bandwidth). */ + if (gspca_dev->width == 640 && reg11 < 3) + reg11 = 3; + /* Write reg 10 and reg11 low nibble */ i2c[1] = sd->sensor_addr; i2c[3] = reg10; i2c[4] |= reg11 - 1; - if (sd->sensor == SENSOR_OV7630_3) { - __u8 reg76 = reg10 & 0x03; - __u8 i2c_reg76[] = {0xa0, 0x21, 0x76, 0x00, - 0x00, 0x00, 0x00, 0x10}; - reg10 >>= 2; - i2c_reg76[3] = reg76; - if (i2c_w(gspca_dev, i2c_reg76) < 0) - PDEBUG(D_ERR, "i2c error exposure"); - } - if (i2c_w(gspca_dev, i2c) < 0) + + /* If register 11 didn't change, don't change it */ + if (sd->reg11 == reg11 ) + i2c[0] = 0xa0; + + if (i2c_w(gspca_dev, i2c) == 0) + sd->reg11 = reg11; + else PDEBUG(D_ERR, "i2c error exposure"); break; } @@ -758,11 +754,11 @@ static void setfreq(struct gspca_dev *gspca_dev) switch (sd->sensor) { case SENSOR_OV6650: - case SENSOR_OV7630_3: { + case SENSOR_OV7630: { /* Framerate adjust register for artificial light 50 hz flicker - compensation, identical to ov6630 0x2b register, see ov6630 - datasheet. - 0x4f -> (30 fps -> 25 fps), 0x00 -> no adjustment */ + compensation, for the ov6650 this is identical to ov6630 + 0x2b register, see ov6630 datasheet. + 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; switch (sd->freq) { default: @@ -789,7 +785,6 @@ static void setsaturation(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -810,7 +805,6 @@ static void sethue(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -830,7 +824,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) switch (sd->sensor) { /* case SENSOR_OV6650: */ - case SENSOR_OV7630_3: case SENSOR_OV7630: { __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; i2c[1] = sd->sensor_addr; @@ -880,8 +873,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->fr_h_sz = 12; /* default size of the frame header */ sd->sd_desc.nctrls = 2; /* default nb of ctrls */ - sd->autogain = AUTOGAIN_DEF; /* default is autogain active */ - product = id->idProduct; /* switch (id->idVendor) { */ /* case 0x0c45: * Sonix */ @@ -912,17 +903,14 @@ static int sd_config(struct gspca_dev *gspca_dev, case 0x6019: /* SN9C101 */ case 0x602c: /* SN9C102 */ case 0x602e: /* SN9C102 */ - sd->sensor = SENSOR_OV7630; - sd->sensor_addr = 0x21; - break; case 0x60b0: /* SN9C103 */ - sd->sensor = SENSOR_OV7630_3; + sd->sensor = SENSOR_OV7630; sd->sensor_addr = 0x21; - sd->fr_h_sz = 18; /* size of frame header */ sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 8; + sd->sd_desc.nctrls = 5; sd->sd_desc.dq_callback = do_autogain; - sd->autogain = 0; + if (product == 0x60b0) + sd->fr_h_sz = 18; /* size of frame header */ break; case 0x6024: /* SN9C102 */ case 0x6025: /* SN9C102 */ @@ -948,7 +936,7 @@ static int sd_config(struct gspca_dev *gspca_dev, if (!sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - if (sd->sensor == SENSOR_OV7630_3) { + if (product == 0x60b0) { /* SN9C103 with OV7630 */ /* We only have 320x240 & 640x480 */ cam->cam_mode++; cam->nmodes--; @@ -960,12 +948,15 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->brightness = BRIGHTNESS_DEF; sd->gain = GAIN_DEF; sd->exposure = EXPOSURE_DEF; + sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; sd->contrast = CONTRAST_DEF; sd->saturation = SATURATION_DEF; sd->hue = HUE_DEF; - if (sd->sensor == SENSOR_OV7630_3) /* jfm: from win trace */ + + if (product == 0x60b0) /* SN9C103 with OV7630 */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); + return 0; } @@ -999,7 +990,7 @@ static void pas106_i2cinit(struct gspca_dev *gspca_dev) static void sd_start(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - int mode, l; + int mode, l = 0x1f; const __u8 *sn9c10x; __u8 reg01, reg17; __u8 reg17_19[3]; @@ -1019,13 +1010,11 @@ static void sd_start(struct gspca_dev *gspca_dev) reg17_19[2] = 0x20; break; case SENSOR_OV7630: - sn9c10x = initOv7630; - reg17_19[0] = 0x68; - reg17_19[1] = (mode << 4) | COMP2; - reg17_19[2] = MCK_INIT1; - break; - case SENSOR_OV7630_3: - sn9c10x = initOv7630_3; + if (sd->fr_h_sz == 18) { /* SN9C103 */ + sn9c10x = initOv7630_3; + l = sizeof initOv7630_3; + } else + sn9c10x = initOv7630; reg17_19[0] = 0x68; reg17_19[1] = (mode << 4) | COMP2; reg17_19[2] = MCK_INIT1; @@ -1056,30 +1045,22 @@ static void sd_start(struct gspca_dev *gspca_dev) reg17_19[2] = mode ? 0x23 : 0x43; break; } - switch (sd->sensor) { - case SENSOR_OV7630: + + /* Special case for SN9C101/2 with OV 7630 */ + /* HDG: is this really necessary we overwrite the values immediately + afterwards with the ones from the template ?? */ + if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) { reg01 = 0x06; reg17 = 0x29; - l = sizeof initOv7630; - break; - case SENSOR_OV7630_3: - reg01 = 0x44; - reg17 = 0x68; - l = sizeof initOv7630_3; - break; - default: + } else { reg01 = sn9c10x[0]; reg17 = sn9c10x[0x17 - 1]; - l = 0x1f; - break; } /* reg 0x01 bit 2 video transfert on */ reg_w(gspca_dev, 0x01, ®01, 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ reg_w(gspca_dev, 0x17, ®17, 1); -/*fixme: for ov7630 102 - reg_w(gspca_dev, 0x01, {0x06, sn9c10x[1]}, 2); */ /* Set the registers from the template */ reg_w_big(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { @@ -1092,17 +1073,13 @@ static void sd_start(struct gspca_dev *gspca_dev) sizeof ov6650_sensor_init); break; case SENSOR_OV7630: - i2c_w_vector(gspca_dev, ov7630_sensor_init_com, - sizeof ov7630_sensor_init_com); - msleep(200); i2c_w_vector(gspca_dev, ov7630_sensor_init, sizeof ov7630_sensor_init); - break; - case SENSOR_OV7630_3: - i2c_w_vector(gspca_dev, ov7630_sensor_init_com, - sizeof ov7630_sensor_init_com); - msleep(200); - i2c_w(gspca_dev, ov7630_sensor_init_3[mode]); + if (sd->fr_h_sz == 18) { /* SN9C103 */ + const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00, + 0x00, 0x00, 0x10 }; + i2c_w(gspca_dev, i2c); + } break; case SENSOR_PAS106: pas106_i2cinit(gspca_dev); @@ -1142,6 +1119,8 @@ static void sd_start(struct gspca_dev *gspca_dev) reg_w(gspca_dev, 0x18, ®17_19[1], 2); msleep(20); + sd->reg11 = -1; + setgain(gspca_dev); setbrightness(gspca_dev); setexposure(gspca_dev); @@ -1150,6 +1129,7 @@ static void sd_start(struct gspca_dev *gspca_dev) sethue(gspca_dev); setcontrast(gspca_dev); + sd->frames_to_drop = 0; sd->autogain_ignore_frames = 0; atomic_set(&sd->avg_lum, -1); } @@ -1195,21 +1175,31 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, && data[3 + i] == 0xc4 && data[4 + i] == 0xc4 && data[5 + i] == 0x96) { /* start of frame */ - frame = gspca_frame_add(gspca_dev, LAST_PACKET, - frame, data, 0); + int lum = -1; + int pkt_type = LAST_PACKET; + if (len - i < sd->fr_h_sz) { - atomic_set(&sd->avg_lum, -1); PDEBUG(D_STREAM, "packet too short to" " get avg brightness"); } else if (sd->fr_h_sz == 12) { - atomic_set(&sd->avg_lum, - data[i + 8] + - (data[i + 9] << 8)); + lum = data[i + 8] + (data[i + 9] << 8); } else { - atomic_set(&sd->avg_lum, - data[i + 9] + - (data[i + 10] << 8)); + lum = data[i + 9] + + (data[i + 10] << 8); } + if (lum == 0) { + lum = -1; + sd->frames_to_drop = 2; + } + atomic_set(&sd->avg_lum, lum); + + if (sd->frames_to_drop) { + sd->frames_to_drop--; + pkt_type = DISCARD_PACKET; + } + + frame = gspca_frame_add(gspca_dev, pkt_type, + frame, data, 0); data += i + sd->fr_h_sz; len -= i + sd->fr_h_sz; gspca_frame_add(gspca_dev, FIRST_PACKET, -- cgit v1.2.3 From e0a33d4d6e028bf40a18069c00884671be75c6b4 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 22 Jul 2008 07:13:21 -0300 Subject: V4L/DVB (8456): gspca_sonixb remove non working ovXXXX contrast, hue and saturation ctrls gspca_sonixb remove non working ovXXXX contrast, hue and saturation ctrls Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 171 ------------------------------------- 1 file changed, 171 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 4f9c9ecb06e8..f8e510cfdf96 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -43,9 +43,6 @@ struct sd { unsigned char autogain_ignore_frames; unsigned char frames_to_drop; unsigned char freq; /* light freq filter setting */ - unsigned char saturation; - unsigned char hue; - unsigned char contrast; unsigned char fr_h_sz; /* size of frame header */ char sensor; /* Type of image sensor chip */ @@ -90,12 +87,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val); static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val); -static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val); -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val); -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -172,48 +163,6 @@ static struct ctrl sd_ctrls[] = { .set = sd_setfreq, .get = sd_getfreq, }, - { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, -#define SATURATION_DEF 127 - .default_value = SATURATION_DEF, - }, - .set = sd_setsaturation, - .get = sd_getsaturation, - }, - { - { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = 0, - .maximum = 255, - .step = 1, -#define HUE_DEF 127 - .default_value = HUE_DEF, - }, - .set = sd_sethue, - .get = sd_gethue, - }, - { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, -#define CONTRAST_DEF 127 - .default_value = CONTRAST_DEF, - }, - .set = sd_setcontrast, - .get = sd_getcontrast, - }, }; static struct v4l2_pix_format vga_mode[] = { @@ -779,66 +728,6 @@ static void setfreq(struct gspca_dev *gspca_dev) } } -static void setsaturation(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = sd->saturation & 0xf0; - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setsaturation"); - else - PDEBUG(D_CONF, "saturation set to: %d", - (int)sd->saturation); - break; - } - } -} - -static void sethue(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = 0x20 | (sd->hue >> 3); - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setsaturation"); - else - PDEBUG(D_CONF, "hue set to: %d", (int)sd->hue); - break; - } - } -} - -static void setcontrast(struct gspca_dev *gspca_dev) -{ - struct sd *sd = (struct sd *) gspca_dev; - - switch (sd->sensor) { -/* case SENSOR_OV6650: */ - case SENSOR_OV7630: { - __u8 i2c[] = {0xa0, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10}; - i2c[1] = sd->sensor_addr; - i2c[3] = 0x20 | (sd->contrast >> 3); - if (i2c_w(gspca_dev, i2c) < 0) - PDEBUG(D_ERR, "i2c error setcontrast"); - else - PDEBUG(D_CONF, "contrast set to: %d", - (int)sd->contrast); - break; - } - } -} - - static void do_autogain(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; @@ -950,9 +839,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->exposure = EXPOSURE_DEF; sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; - sd->contrast = CONTRAST_DEF; - sd->saturation = SATURATION_DEF; - sd->hue = HUE_DEF; if (product == 0x60b0) /* SN9C103 with OV7630 */ reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); @@ -1125,9 +1011,6 @@ static void sd_start(struct gspca_dev *gspca_dev) setbrightness(gspca_dev); setexposure(gspca_dev); setfreq(gspca_dev); - setsaturation(gspca_dev); - sethue(gspca_dev); - setcontrast(gspca_dev); sd->frames_to_drop = 0; sd->autogain_ignore_frames = 0; @@ -1314,60 +1197,6 @@ static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val) return 0; } -static int sd_setsaturation(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->saturation = val; - if (gspca_dev->streaming) - setsaturation(gspca_dev); - return 0; -} - -static int sd_getsaturation(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->saturation; - return 0; -} - -static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->hue = val; - if (gspca_dev->streaming) - sethue(gspca_dev); - return 0; -} - -static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->hue; - return 0; -} - -static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->contrast = val; - if (gspca_dev->streaming) - setcontrast(gspca_dev); - return 0; -} - -static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - *val = sd->contrast; - return 0; -} - static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { -- cgit v1.2.3 From 84754319e30a25626f6bf0d84efc7935ba1d0b3d Mon Sep 17 00:00:00 2001 From: Andoni Zubimendi Date: Tue, 22 Jul 2008 08:39:24 -0300 Subject: V4L/DVB (8457): gspca_sonixb remove some no longer needed sn9c103+ov7630 special cases gspca_sonixb remove some no longer needed sn9c103+ov7630 special cases Signed-off-by: Andoni Zubimendi Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index f8e510cfdf96..fd91f43e0786 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -195,8 +195,6 @@ static struct v4l2_pix_format sif_mode[] = { .priv = 0}, }; -static const __u8 probe_ov7630[] = {0x08, 0x44}; - static const __u8 initHv7131[] = { 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -825,11 +823,6 @@ static int sd_config(struct gspca_dev *gspca_dev, if (!sif) { cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - if (product == 0x60b0) { /* SN9C103 with OV7630 */ - /* We only have 320x240 & 640x480 */ - cam->cam_mode++; - cam->nmodes--; - } } else { cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); @@ -840,9 +833,6 @@ static int sd_config(struct gspca_dev *gspca_dev, sd->autogain = AUTOGAIN_DEF; sd->freq = FREQ_DEF; - if (product == 0x60b0) /* SN9C103 with OV7630 */ - reg_w(gspca_dev, 0x01, probe_ov7630, sizeof probe_ov7630); - return 0; } -- cgit v1.2.3 From fff4205f1d64163132609942314e94ec3ba2ed6b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 23 Jul 2008 07:04:39 -0300 Subject: V4L/DVB (8458): gspca_sonixb remove one more no longer needed special case from the code gspca_sonixb remove one more no longer needed special case from the code Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index fd91f43e0786..93d365456591 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -868,7 +868,6 @@ static void sd_start(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int mode, l = 0x1f; const __u8 *sn9c10x; - __u8 reg01, reg17; __u8 reg17_19[3]; mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv; @@ -922,21 +921,10 @@ static void sd_start(struct gspca_dev *gspca_dev) break; } - /* Special case for SN9C101/2 with OV 7630 */ - /* HDG: is this really necessary we overwrite the values immediately - afterwards with the ones from the template ?? */ - if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) { - reg01 = 0x06; - reg17 = 0x29; - } else { - reg01 = sn9c10x[0]; - reg17 = sn9c10x[0x17 - 1]; - } - /* reg 0x01 bit 2 video transfert on */ - reg_w(gspca_dev, 0x01, ®01, 1); + reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1); /* reg 0x17 SensorClk enable inv Clk 0x60 */ - reg_w(gspca_dev, 0x17, ®17, 1); + reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1); /* Set the registers from the template */ reg_w_big(gspca_dev, 0x01, sn9c10x, l); switch (sd->sensor) { -- cgit v1.2.3 From f8f6296adad30cadd65555dfde489d1080b2001c Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Wed, 23 Jul 2008 20:28:23 -0300 Subject: V4L/DVB (8461): cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input cx18: Fix 32 kHz audio sample output rate for analog tuner SIF input so it works. The AUX_PLL VCO was being operated at 196.6 MHz out of the spec'ed 200-600 MHz range. Fixed the multipler and post dividers to operate the VCO within specification and added comments on how magic numbers are derived. Thanks to Hans Verkuil for pointing out this interesting problem to solve. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-audio.c | 41 ++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index c40a286de1b9..7245d37ef34f 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c @@ -30,7 +30,6 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) if (freq != 32000 && freq != 44100 && freq != 48000) return -EINVAL; - /* common for all inputs and rates */ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ cx18_av_write(cx, 0x127, 0x50); @@ -38,15 +37,20 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) switch (freq) { case 32000: /* VID_PLL and AUX_PLL */ - cx18_av_write4(cx, 0x108, 0x1006040f); + cx18_av_write4(cx, 0x108, 0x1408040f); /* AUX_PLL_FRAC */ - cx18_av_write4(cx, 0x110, 0x01bb39ee); + /* 0x8.9504318a * 28,636,363.636 / 0x14 = 32000 * 384 */ + cx18_av_write4(cx, 0x110, 0x012a0863); - /* src3/4/6_ctl = 0x0801f77f */ + /* src3/4/6_ctl */ + /* 0x1.f77f = (4 * 15734.26) / 32000 */ cx18_av_write4(cx, 0x900, 0x0801f77f); cx18_av_write4(cx, 0x904, 0x0801f77f); cx18_av_write4(cx, 0x90c, 0x0801f77f); + + /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ + cx18_av_write(cx, 0x127, 0x54); break; case 44100: @@ -54,9 +58,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1009040f); /* AUX_PLL_FRAC */ + /* 0x9.7635eb * 28,636,363 / 0x10 = 44100 * 384 */ cx18_av_write4(cx, 0x110, 0x00ec6bd6); - /* src3/4/6_ctl = 0x08016d59 */ + /* src3/4/6_ctl */ + /* 0x1.6d59 = (4 * 15734.26) / 44100 */ cx18_av_write4(cx, 0x900, 0x08016d59); cx18_av_write4(cx, 0x904, 0x08016d59); cx18_av_write4(cx, 0x90c, 0x08016d59); @@ -67,9 +73,11 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x100a040f); /* AUX_PLL_FRAC */ + /* 0xa.4c6b728 * 28,636,363 / 0x10 = 48000 * 384 */ cx18_av_write4(cx, 0x110, 0x0098d6e5); - /* src3/4/6_ctl = 0x08014faa */ + /* src3/4/6_ctl */ + /* 0x1.4faa = (4 * 15734.26) / 48000 */ cx18_av_write4(cx, 0x900, 0x08014faa); cx18_av_write4(cx, 0x904, 0x08014faa); cx18_av_write4(cx, 0x90c, 0x08014faa); @@ -82,12 +90,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1e08040f); /* AUX_PLL_FRAC */ + /* 0x8.9504348 * 28,636,363 / 0x1e = 32000 * 256 */ cx18_av_write4(cx, 0x110, 0x012a0869); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.0000 = 32000/32000 */ cx18_av_write4(cx, 0x8f8, 0x08010000); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x2.0000 = 2 * (32000/32000) */ cx18_av_write4(cx, 0x900, 0x08020000); cx18_av_write4(cx, 0x904, 0x08020000); cx18_av_write4(cx, 0x90c, 0x08020000); @@ -101,12 +112,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1809040f); /* AUX_PLL_FRAC */ + /* 0x9.76346B * 28,636,363 / 0x18 = 44100 * 256 */ cx18_av_write4(cx, 0x110, 0x00ec6bd6); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.60cd = 44100/32000 */ cx18_av_write4(cx, 0x8f8, 0x080160cd); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x1.7385 = 2 * (32000/44100) */ cx18_av_write4(cx, 0x900, 0x08017385); cx18_av_write4(cx, 0x904, 0x08017385); cx18_av_write4(cx, 0x90c, 0x08017385); @@ -117,12 +131,15 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x180a040f); /* AUX_PLL_FRAC */ + /* 0xa.4c6b728 * 28,636,363 / 0x18 = 48000 * 256 */ cx18_av_write4(cx, 0x110, 0x0098d6e5); - /* src1_ctl = 0x08010000 */ + /* src1_ctl */ + /* 0x1.8000 = 48000/32000 */ cx18_av_write4(cx, 0x8f8, 0x08018000); - /* src3/4/6_ctl = 0x08020000 */ + /* src3/4/6_ctl */ + /* 0x1.5555 = 2 * (32000/48000) */ cx18_av_write4(cx, 0x900, 0x08015555); cx18_av_write4(cx, 0x904, 0x08015555); cx18_av_write4(cx, 0x90c, 0x08015555); -- cgit v1.2.3 From 35f92b2af8230ffc1146e2317e2068fefd7caacb Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Fri, 25 Jul 2008 15:03:08 -0300 Subject: V4L/DVB (8462): cx18: Lock the aux PLL to the video pixle rate for analog captures cx18: Lock the aux PLL to the video pixel rate for analog captures. The datasheet for the CX25840 says this is important for MPEG encoding applications. To ensure the PLL locking was correct, also fixed the aux PLL's multiplier to be computed based on a precise crystal freq of 4.5 MHz/286 * 455/2 * 8 = 28636363.6363... instead of the imporperly rounded 28636363. Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/cx18-av-audio.c | 80 ++++++++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c index 7245d37ef34f..0b55837880a7 100644 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ b/drivers/media/video/cx18/cx18-av-audio.c @@ -51,6 +51,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ cx18_av_write(cx, 0x127, 0x54); + + /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11202fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = + * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa10d2ef8); break; case 44100: @@ -58,14 +68,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1009040f); /* AUX_PLL_FRAC */ - /* 0x9.7635eb * 28,636,363 / 0x10 = 44100 * 384 */ - cx18_av_write4(cx, 0x110, 0x00ec6bd6); + /* 0x9.7635e7 * 28,636,363.63 / 0x10 = 44100 * 384 */ + cx18_av_write4(cx, 0x110, 0x00ec6bce); /* src3/4/6_ctl */ /* 0x1.6d59 = (4 * 15734.26) / 44100 */ cx18_av_write4(cx, 0x900, 0x08016d59); cx18_av_write4(cx, 0x904, 0x08016d59); cx18_av_write4(cx, 0x90c, 0x08016d59); + + /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x112092ff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = + * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11d4bf8); break; case 48000: @@ -73,14 +93,24 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x100a040f); /* AUX_PLL_FRAC */ - /* 0xa.4c6b728 * 28,636,363 / 0x10 = 48000 * 384 */ - cx18_av_write4(cx, 0x110, 0x0098d6e5); + /* 0xa.4c6b6ea * 28,636,363.63 / 0x10 = 48000 * 384 */ + cx18_av_write4(cx, 0x110, 0x0098d6dd); /* src3/4/6_ctl */ /* 0x1.4faa = (4 * 15734.26) / 48000 */ cx18_av_write4(cx, 0x900, 0x08014faa); cx18_av_write4(cx, 0x904, 0x08014faa); cx18_av_write4(cx, 0x90c, 0x08014faa); + + /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11205fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1193f8 = 143999.000 * 8 = + * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11193f8); break; } } else { @@ -90,8 +120,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1e08040f); /* AUX_PLL_FRAC */ - /* 0x8.9504348 * 28,636,363 / 0x1e = 32000 * 256 */ - cx18_av_write4(cx, 0x110, 0x012a0869); + /* 0x8.9504318 * 28,636,363.63 / 0x1e = 32000 * 256 */ + cx18_av_write4(cx, 0x110, 0x012a0863); /* src1_ctl */ /* 0x1.0000 = 32000/32000 */ @@ -105,6 +135,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */ cx18_av_write(cx, 0x127, 0x54); + + /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11201fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = + * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa10d2ef8); break; case 44100: @@ -112,8 +152,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x1809040f); /* AUX_PLL_FRAC */ - /* 0x9.76346B * 28,636,363 / 0x18 = 44100 * 256 */ - cx18_av_write4(cx, 0x110, 0x00ec6bd6); + /* 0x9.7635e74 * 28,636,363.63 / 0x18 = 44100 * 256 */ + cx18_av_write4(cx, 0x110, 0x00ec6bce); /* src1_ctl */ /* 0x1.60cd = 44100/32000 */ @@ -124,6 +164,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x900, 0x08017385); cx18_av_write4(cx, 0x904, 0x08017385); cx18_av_write4(cx, 0x90c, 0x08017385); + + /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x112061ff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = + * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11d4bf8); break; case 48000: @@ -131,8 +181,8 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x108, 0x180a040f); /* AUX_PLL_FRAC */ - /* 0xa.4c6b728 * 28,636,363 / 0x18 = 48000 * 256 */ - cx18_av_write4(cx, 0x110, 0x0098d6e5); + /* 0xa.4c6b6ea * 28,636,363.63 / 0x18 = 48000 * 256 */ + cx18_av_write4(cx, 0x110, 0x0098d6dd); /* src1_ctl */ /* 0x1.8000 = 48000/32000 */ @@ -143,6 +193,16 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq) cx18_av_write4(cx, 0x900, 0x08015555); cx18_av_write4(cx, 0x904, 0x08015555); cx18_av_write4(cx, 0x90c, 0x08015555); + + /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */ + cx18_av_write4(cx, 0x12c, 0x11203fff); + + /* + * EN_AV_LOCK = 1 + * VID_COUNT = 0x1193f8 = 143999.000 * 8 = + * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 + */ + cx18_av_write4(cx, 0x128, 0xa11193f8); break; } } -- cgit v1.2.3 From 28901ab621bb56cd2aa9670dc7ce016ba80ec45c Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 28 Jun 2008 00:48:18 -0300 Subject: V4L/DVB (8464): cx23885: Bugfix for concurrent use of /dev/video0 and /dev/video1 With the HVR1800, trying to use video0 and video1 simultaneously caused buffer corruption in the PCIe bridge. This fix reallocates video1 buffer locations to avoid the issue. Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index d17343ea0d33..e14371ef1269 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -104,8 +104,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH03] = { .name = "TS1 B", .cmds_start = 0x100A0, - .ctrl_start = 0x10780, - .cdt = 0x10400, + .ctrl_start = 0x10670, + .cdt = 0x10810, .fifo_start = 0x5000, .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, -- cgit v1.2.3 From ecda5966c90746a044ff68e78b1062adcddd9664 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 28 Jun 2008 00:52:45 -0300 Subject: V4L/DVB (8465): cx23885: Ensure PAD_CTRL is always reset to a sensible default PAD_CTRL controls TS1 and TS2 input and output states, if the register became corrupt the driver was never able to recover. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index e14371ef1269..f5afc8d7cb12 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -460,6 +460,7 @@ static void cx23885_reset(struct cx23885_dev *dev) cx_write(AUDIO_INT_INT_STAT, 0xffffffff); cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); + cx_write(PAD_CTRL, 0x00500300); mdelay(100); -- cgit v1.2.3 From 52ce27bfc4d302a3e28267a5820a8b031ceccee9 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 28 Jun 2008 00:58:35 -0300 Subject: V4L/DVB (8466): cx23885: Bugfix - DVB Transport cards using DVB port VIDB/TS1 did not stream. Certain DVB cards that have demodulators on TS1/VIDB were not streaming packets. This ensure the pin directions on PAD_CTRL are set correctly, solving the issue. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index f5afc8d7cb12..b96016d1d0fe 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1084,7 +1084,21 @@ static int cx23885_start_dma(struct cx23885_tsport *port, cx_write(port->reg_gpcnt_ctl, 3); q->count = 1; - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + /* Set VIDB pins to input */ + if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + /* Set VIDC pins to input */ + if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { + reg = cx_read(PAD_CTRL); + reg &= ~0x4; /* Clear TS2_SOP_OE */ + cx_write(PAD_CTRL, reg); + } + + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); reg = reg & ~0x1; /* Clear TS1_OE */ @@ -1134,7 +1148,7 @@ static int cx23885_stop_dma(struct cx23885_tsport *port) cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - if (cx23885_boards[dev->board].portb & CX23885_MPEG_ENCODER) { + if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { reg = cx_read(PAD_CTRL); -- cgit v1.2.3 From 7b9139086abca60b762d1b01231db88abfb666d5 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 20:54:34 -0300 Subject: V4L/DVB (8467): cx23885: Minor cleanup to the debuging output for a specific register. Don't display the register when it's not appropriate for the specific port. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index b96016d1d0fe..83067a49a7b7 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -1011,8 +1011,9 @@ static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, - port->reg_src_sel, cx_read(port->reg_src_sel)); + if (port->reg_src_sel) + dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, + port->reg_src_sel, cx_read(port->reg_src_sel)); dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, port->reg_lngth, cx_read(port->reg_lngth)); dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, -- cgit v1.2.3 From aaadeac88add22c4b2e2e7d17af1c5bae2d3fe17 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 20:58:38 -0300 Subject: V4L/DVB (8468): cx23885: Ensure the second transport port is enabled for streaming. It was previously disabled pending a bugfix, which has since been resolved. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index fd7112c11d35..f325c123295c 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -145,6 +145,7 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { .name = "DViCO FusionHDTV7 Dual Express", + .portb = CX23885_MPEG_DVB, .portc = CX23885_MPEG_DVB, }, }; -- cgit v1.2.3 From 1ecc5aed1ea426dbb7e5cd9a0c980c14c879277b Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 21:23:50 -0300 Subject: V4L/DVB (8469): cx23885: FusionHDTV7 Dual Express toggle reset. Ensure the tuners and demods are brought in and out of reset during driver startup. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index f325c123295c..691b35279c20 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -436,6 +436,19 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx_set(GP0_IO, 0x00050005); break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + /* GPIO-0 xc5000 tuner reset i2c bus 0 */ + /* GPIO-1 s5h1409 demod reset i2c bus 0 */ + /* GPIO-2 xc5000 tuner reset i2c bus 1 */ + /* GPIO-3 s5h1409 demod reset i2c bus 0 */ + + /* Put the parts into reset and back */ + cx_set(GP0_IO, 0x000f0000); + mdelay(20); + cx_clear(GP0_IO, 0x0000000f); + mdelay(20); + cx_set(GP0_IO, 0x000f000f); + break; } } -- cgit v1.2.3 From 6df516905b5c53b306d90be33f9c56434e8db053 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 30 Jun 2008 22:17:05 -0300 Subject: V4L/DVB (8470): cx23885: Add DViCO HDTV7 Dual Express tuner callback support. Ensure the correct tuner gets reset on demand. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-cards.c | 40 ++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 691b35279c20..a19de850955d 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -326,25 +326,41 @@ int cx23885_tuner_callback(void *priv, int command, int arg) { struct cx23885_i2c *bus = priv; struct cx23885_dev *dev = bus->dev; + u32 bitmask = 0; + + if (command != 0) { + printk(KERN_ERR "%s(): Unknown command 0x%x.\n", + __func__, command); + return -EINVAL; + } switch(dev->board) { case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - if(command == 0) { /* Tuner Reset Command from xc5000 */ - /* Drive the tuner into reset and out */ - cx_clear(GP0_IO, 0x00000004); - mdelay(200); - cx_set(GP0_IO, 0x00000004); - return 0; - } - else { - printk(KERN_ERR - "%s(): Unknow command.\n", __func__); - return -EINVAL; + /* Tuner Reset Command from xc5000 */ + if (command == 0) + bitmask = 0x04; + break; + case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: + if (command == 0) { + + /* Two identical tuners on two different i2c buses, + * we need to reset the correct gpio. */ + if (bus->nr == 0) + bitmask = 0x01; + else if (bus->nr == 1) + bitmask = 0x04; } break; } - return 0; /* Should never be here */ + if (bitmask) { + /* Drive the tuner into reset and back out */ + cx_clear(GP0_IO, bitmask); + mdelay(200); + cx_set(GP0_IO, bitmask); + } + + return 0; } void cx23885_gpio_setup(struct cx23885_dev *dev) -- cgit v1.2.3 From d8d12b4367e2e759f65c5f9dcb94d21ec237bbc5 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 1 Jul 2008 10:43:27 -0300 Subject: V4L/DVB (8471): cx23885: Reallocated the sram to avoid concurrent VIDB/C issues. This may be cx23885 chip specific and may not work on the cx23887. Analog and mpeg encoder streaming are still to be tested. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 83067a49a7b7..3ae04d6e1362 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -80,8 +80,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH01] = { .name = "VID A", .cmds_start = 0x10000, - .ctrl_start = 0x105b0, - .cdt = 0x107b0, + .ctrl_start = 0x10380, + .cdt = 0x104c0, .fifo_start = 0x40, .fifo_size = 0x2800, .ptr1_reg = DMA1_PTR1, @@ -104,8 +104,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH03] = { .name = "TS1 B", .cmds_start = 0x100A0, - .ctrl_start = 0x10670, - .cdt = 0x10810, + .ctrl_start = 0x10400, + .cdt = 0x10580, .fifo_start = 0x5000, .fifo_size = 0x1000, .ptr1_reg = DMA3_PTR1, @@ -140,8 +140,8 @@ static struct sram_channel cx23887_sram_channels[] = { [SRAM_CH06] = { .name = "TS2 C", .cmds_start = 0x10140, - .ctrl_start = 0x10680, - .cdt = 0x108d0, + .ctrl_start = 0x10440, + .cdt = 0x105e0, .fifo_start = 0x6000, .fifo_size = 0x1000, .ptr1_reg = DMA5_PTR1, @@ -1044,6 +1044,9 @@ static int cx23885_start_dma(struct cx23885_tsport *port, dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, buf->vb.width, buf->vb.height, buf->vb.field); + /* Stop the fifo and risc engine for this port */ + cx_clear(port->reg_dma_ctl, port->dma_ctl_val); + /* setup fifo + format */ cx23885_sram_channel_setup(dev, &dev->sram_channels[ port->sram_chno ], -- cgit v1.2.3 From 7e994302ed3fc6d209ce247ad5b6d9c2499bf7c2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 1 Jul 2008 21:18:00 -0300 Subject: V4L/DVB (8472): cx23885: SRAM changes for the 885 and 887 silicon parts. In a previous patch I merged both memory maps into a single struct, believing that they could be combined. We've since found problems with streaming multiple channels on the 885. I'm restoring the multiple memory map structs - in line with the windows driver. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx23885/cx23885-core.c | 116 ++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 3ae04d6e1362..6286a9cf957e 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c @@ -76,7 +76,7 @@ LIST_HEAD(cx23885_devlist); * 0x00010ea0 0x00010xxx Free */ -static struct sram_channel cx23887_sram_channels[] = { +static struct sram_channel cx23885_sram_channels[] = { [SRAM_CH01] = { .name = "VID A", .cmds_start = 0x10000, @@ -187,6 +187,117 @@ static struct sram_channel cx23887_sram_channels[] = { }, }; +static struct sram_channel cx23887_sram_channels[] = { + [SRAM_CH01] = { + .name = "VID A", + .cmds_start = 0x10000, + .ctrl_start = 0x105b0, + .cdt = 0x107b0, + .fifo_start = 0x40, + .fifo_size = 0x2800, + .ptr1_reg = DMA1_PTR1, + .ptr2_reg = DMA1_PTR2, + .cnt1_reg = DMA1_CNT1, + .cnt2_reg = DMA1_CNT2, + }, + [SRAM_CH02] = { + .name = "ch2", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA2_PTR1, + .ptr2_reg = DMA2_PTR2, + .cnt1_reg = DMA2_CNT1, + .cnt2_reg = DMA2_CNT2, + }, + [SRAM_CH03] = { + .name = "TS1 B", + .cmds_start = 0x100A0, + .ctrl_start = 0x10630, + .cdt = 0x10870, + .fifo_start = 0x5000, + .fifo_size = 0x1000, + .ptr1_reg = DMA3_PTR1, + .ptr2_reg = DMA3_PTR2, + .cnt1_reg = DMA3_CNT1, + .cnt2_reg = DMA3_CNT2, + }, + [SRAM_CH04] = { + .name = "ch4", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA4_PTR1, + .ptr2_reg = DMA4_PTR2, + .cnt1_reg = DMA4_CNT1, + .cnt2_reg = DMA4_CNT2, + }, + [SRAM_CH05] = { + .name = "ch5", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH06] = { + .name = "TS2 C", + .cmds_start = 0x10140, + .ctrl_start = 0x10670, + .cdt = 0x108d0, + .fifo_start = 0x6000, + .fifo_size = 0x1000, + .ptr1_reg = DMA5_PTR1, + .ptr2_reg = DMA5_PTR2, + .cnt1_reg = DMA5_CNT1, + .cnt2_reg = DMA5_CNT2, + }, + [SRAM_CH07] = { + .name = "ch7", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA6_PTR1, + .ptr2_reg = DMA6_PTR2, + .cnt1_reg = DMA6_CNT1, + .cnt2_reg = DMA6_CNT2, + }, + [SRAM_CH08] = { + .name = "ch8", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA7_PTR1, + .ptr2_reg = DMA7_PTR2, + .cnt1_reg = DMA7_CNT1, + .cnt2_reg = DMA7_CNT2, + }, + [SRAM_CH09] = { + .name = "ch9", + .cmds_start = 0x0, + .ctrl_start = 0x0, + .cdt = 0x0, + .fifo_start = 0x0, + .fifo_size = 0x0, + .ptr1_reg = DMA8_PTR1, + .ptr2_reg = DMA8_PTR2, + .cnt1_reg = DMA8_CNT1, + .cnt2_reg = DMA8_CNT2, + }, +}; + static int cx23885_risc_decode(u32 risc) { static char *instr[16] = { @@ -626,7 +737,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) atomic_inc(&dev->refcount); dev->nr = cx23885_devcount++; - dev->sram_channels = cx23887_sram_channels; sprintf(dev->name, "cx23885[%d]", dev->nr); mutex_lock(&devlist); @@ -638,11 +748,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev) dev->bridge = CX23885_BRIDGE_887; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 25000000; + dev->sram_channels = cx23887_sram_channels; } else if(dev->pci->device == 0x8852) { dev->bridge = CX23885_BRIDGE_885; /* Apply a sensible clock frequency for the PCIe bridge */ dev->clk_freq = 28000000; + dev->sram_channels = cx23885_sram_channels; } else BUG(); -- cgit v1.2.3 From 31335b13ca3925f361702ca4fc895ab165beddb9 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Fri, 25 Jul 2008 19:35:31 -0300 Subject: V4L/DVB (8474): pvrusb2: Enable IR chip on HVR-1900 class devices The Zilog IR chip on HVR-1900 devices is held in reset when the device initializes. We have to bring this chip out of reset before LIRC has any chance of operating the chip. So do it. Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 5 ++++- drivers/media/video/pvrusb2/pvrusb2-devattr.h | 26 +++++++++++++++++--------- drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h | 2 ++ drivers/media/video/pvrusb2/pvrusb2-hdw.c | 9 +++++++++ drivers/media/video/pvrusb2/pvrusb2-i2c-core.c | 4 +++- 5 files changed, 35 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index 5d036e7e3f07..e3b051197087 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -97,13 +97,13 @@ static const struct pvr2_device_desc pvr2_device_24xxx = { .flag_has_cx25840 = !0, .flag_has_wm8775 = !0, .flag_has_hauppauge_rom = !0, - .flag_has_hauppauge_custom_ir = !0, .flag_has_analogtuner = !0, .flag_has_fmradio = !0, .flag_has_composite = !0, .flag_has_svideo = !0, .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_24XXX, }; @@ -344,6 +344,7 @@ static const struct pvr2_device_desc pvr2_device_73xxx = { .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE, .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_73xxx_dvb_props, #endif @@ -453,6 +454,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_750xx_dvb_props, #endif @@ -474,6 +476,7 @@ static const struct pvr2_device_desc pvr2_device_751xx = { .digital_control_scheme = PVR2_DIGITAL_SCHEME_HAUPPAUGE, .default_std_mask = V4L2_STD_NTSC_M, .led_scheme = PVR2_LED_SCHEME_HAUPPAUGE, + .ir_scheme = PVR2_IR_SCHEME_ZILOG, #ifdef CONFIG_VIDEO_PVRUSB2_DVB .dvb_props = &pvr2_751xx_dvb_props, #endif diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h index e23ce1d2edd7..cb3a33eb0276 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h @@ -48,6 +48,10 @@ struct pvr2_string_table { #define PVR2_LED_SCHEME_NONE 0 #define PVR2_LED_SCHEME_HAUPPAUGE 1 +#define PVR2_IR_SCHEME_NONE 0 +#define PVR2_IR_SCHEME_24XXX 1 +#define PVR2_IR_SCHEME_ZILOG 2 + /* This describes a particular hardware type (except for the USB device ID which must live in a separate structure due to environmental constraints). See the top of pvrusb2-hdw.c for where this is @@ -126,15 +130,19 @@ struct pvr2_device_desc { ensure that it is found. */ unsigned int flag_has_wm8775:1; - /* Device has IR hardware that can be faked into looking like a - normal Hauppauge i2c IR receiver. This is currently very - specific to the 24xxx device, where Hauppauge had replaced their - 'standard' I2C IR receiver with a bunch of FPGA logic controlled - directly via the FX2. Turning this on tells the pvrusb2 driver - to virtualize the presence of the non-existant IR receiver chip and - implement the virtual receiver in terms of appropriate FX2 - commands. */ - unsigned int flag_has_hauppauge_custom_ir:1; + /* Indicate any specialized IR scheme that might need to be + supported by this driver. If not set, then it is assumed that + IR can work without help from the driver (which is frequently + the case). This is otherwise set to one of + PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a + Hauppauge 24xxx class device which has an FPGA-hosted IR + receiver that can only be reached via FX2 command codes. In + that case the pvrusb2 driver will emulate the behavior of the + older 29xxx device's IR receiver (a "virtual" I2C chip) in terms + of those command codes. For the value "ZILOG", we're dealing + with an IR chip that must be taken out of reset via another FX2 + command code (which is the case for HVR-1950 devices). */ + unsigned int ir_scheme:2; /* These bits define which kinds of sources the device can handle. Note: Digital tuner presence is inferred by the diff --git a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h index b58369e7f30b..614755ea2ea3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h +++ b/drivers/media/video/pvrusb2/pvrusb2-fx2-cmd.h @@ -24,6 +24,8 @@ #define FX2CMD_MEM_WRITE_DWORD 0x01u #define FX2CMD_MEM_READ_DWORD 0x02u +#define FX2CMD_HCW_ZILOG_RESET 0x10u /* 1=reset 0=release */ + #define FX2CMD_MEM_READ_64BYTES 0x28u #define FX2CMD_REG_WRITE 0x04u diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index a5217a2cf4c0..f051c6aa7f1f 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -250,6 +250,7 @@ struct pvr2_fx2cmd_descdef { static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = { {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, + {FX2CMD_HCW_ZILOG_RESET, "zilog IR reset control"}, {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, {FX2CMD_REG_WRITE, "write encoder register"}, {FX2CMD_REG_READ, "read encoder register"}, @@ -1711,6 +1712,14 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) if (!pvr2_hdw_dev_ok(hdw)) return; } + /* Take the IR chip out of reset, if appropriate */ + if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) { + pvr2_issue_simple_cmd(hdw, + FX2CMD_HCW_ZILOG_RESET | + (1 << 8) | + ((0) << 16)); + } + // This step MUST happen after the earlier powerup step. pvr2_i2c_core_init(hdw); if (!pvr2_hdw_dev_ok(hdw)) return; diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c index 9d3c18b24744..e600576a6c4b 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c @@ -979,7 +979,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw) printk(KERN_INFO "%s: IR disabled\n",hdw->name); hdw->i2c_func[0x18] = i2c_black_hole; } else if (ir_mode[hdw->unit_number] == 1) { - if (hdw->hdw_desc->flag_has_hauppauge_custom_ir) { + if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) { + /* This comment is present PURELY to get + checkpatch.pl to STFU. Lovely, eh? */ hdw->i2c_func[0x18] = i2c_24xxx_ir; } } -- cgit v1.2.3 From d417f711b9180c4851cfdc19db030878918eac88 Mon Sep 17 00:00:00 2001 From: Mike Isely Date: Fri, 25 Jul 2008 19:50:52 -0300 Subject: V4L/DVB (8475): pvrusb2: Cosmetic macro fix (benign) Signed-off-by: Mike Isely Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-context.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.h b/drivers/media/video/pvrusb2/pvrusb2-context.h index 61801291c2af..d657e53bbfa3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.h +++ b/drivers/media/video/pvrusb2/pvrusb2-context.h @@ -16,8 +16,8 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#ifndef __PVRUSB2_BASE_H -#define __PVRUSB2_BASE_H +#ifndef __PVRUSB2_CONTEXT_H +#define __PVRUSB2_CONTEXT_H #include #include -- cgit v1.2.3 From 38f9d308597fe3f8d52bfa30e7ed6c742b85a1db Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 23 Jul 2008 05:09:15 -0300 Subject: V4L/DVB (8477): v4l: remove obsolete audiochip.h Converted the last users of audiochip.h to the v4l2-chip-ident.h header and remove the now unused audiochip.h header. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx88/cx88-cards.c | 2 +- drivers/media/video/cx88/cx88-video.c | 4 +- drivers/media/video/cx88/cx88.h | 4 +- drivers/media/video/em28xx/em28xx-cards.c | 4 +- drivers/media/video/tveeprom.c | 104 ++++++++++++------------ drivers/media/video/usbvision/usbvision-core.c | 1 - drivers/media/video/usbvision/usbvision-video.c | 1 - include/media/audiochip.h | 26 ------ include/media/v4l2-chip-ident.h | 7 +- 9 files changed, 65 insertions(+), 88 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index fa6d398e97b9..de199a206a15 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c @@ -1348,7 +1348,7 @@ static const struct cx88_board cx88_boards[] = { .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, .tda9887_conf = TDA9887_PRESENT, - .audio_chip = AUDIO_CHIP_WM8775, + .audio_chip = V4L2_IDENT_WM8775, .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index d08c11eb8a75..f8cc55db9f42 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -448,7 +448,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input) the initialization. Some boards may use different routes for different inputs. HVR-1300 surely does */ if (core->board.audio_chip && - core->board.audio_chip == AUDIO_CHIP_WM8775) { + core->board.audio_chip == V4L2_IDENT_WM8775) { struct v4l2_routing route; route.input = INPUT(input).audioroute; @@ -1867,7 +1867,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* load and configure helper modules */ - if (core->board.audio_chip == AUDIO_CHIP_WM8775) + if (core->board.audio_chip == V4L2_IDENT_WM8775) request_module("wm8775"); switch (core->boardnr) { diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 14ac173f4071..54fe65094711 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h @@ -29,8 +29,8 @@ #include #include #include +#include #include -#include #if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE) #include #endif @@ -252,7 +252,7 @@ struct cx88_board { struct cx88_input input[MAX_CX88_INPUT]; struct cx88_input radio; enum cx88_board_type mpeg; - enum audiochip audio_chip; + unsigned int audio_chip; }; struct cx88_subid { diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 05f0d5a15058..6e0eb950ab81 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -32,8 +32,8 @@ #include #include #include -#include #include +#include #include "em28xx.h" @@ -836,7 +836,7 @@ void em28xx_card_setup(struct em28xx *dev) dev->tuner_type = tv.tuner_type; - if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { + if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { dev->i2s_speed = 2048000; dev->has_msp34xx = 1; } diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 9da0e1807ffb..93954c143237 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); MODULE_AUTHOR("John Klar"); @@ -261,70 +261,72 @@ hauppauge_tuner[] = { TUNER_ABSENT, "MaxLinear MXL5005_v2"}, { TUNER_PHILIPS_TDA8290, "Philips 18271_8295"}, /* 150-159 */ - { TUNER_ABSENT, "Xceive XC5000"}, + { TUNER_ABSENT, "Xceive XC5000"}, }; +/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are + * internal to a video chip, i.e. not a separate audio chip. */ static struct HAUPPAUGE_AUDIOIC { - enum audiochip id; + u32 id; char *name; } audioIC[] = { /* 0-4 */ - {AUDIO_CHIP_NONE, "None"}, - {AUDIO_CHIP_TEA6300, "TEA6300"}, - {AUDIO_CHIP_TEA6300, "TEA6320"}, - {AUDIO_CHIP_TDA985X, "TDA9850"}, - {AUDIO_CHIP_MSP34XX, "MSP3400C"}, + { V4L2_IDENT_NONE, "None" }, + { V4L2_IDENT_UNKNOWN, "TEA6300" }, + { V4L2_IDENT_UNKNOWN, "TEA6320" }, + { V4L2_IDENT_UNKNOWN, "TDA9850" }, + { V4L2_IDENT_MSPX4XX, "MSP3400C" }, /* 5-9 */ - {AUDIO_CHIP_MSP34XX, "MSP3410D"}, - {AUDIO_CHIP_MSP34XX, "MSP3415"}, - {AUDIO_CHIP_MSP34XX, "MSP3430"}, - {AUDIO_CHIP_MSP34XX, "MSP3438"}, - {AUDIO_CHIP_UNKNOWN, "CS5331"}, + { V4L2_IDENT_MSPX4XX, "MSP3410D" }, + { V4L2_IDENT_MSPX4XX, "MSP3415" }, + { V4L2_IDENT_MSPX4XX, "MSP3430" }, + { V4L2_IDENT_MSPX4XX, "MSP3438" }, + { V4L2_IDENT_UNKNOWN, "CS5331" }, /* 10-14 */ - {AUDIO_CHIP_MSP34XX, "MSP3435"}, - {AUDIO_CHIP_MSP34XX, "MSP3440"}, - {AUDIO_CHIP_MSP34XX, "MSP3445"}, - {AUDIO_CHIP_MSP34XX, "MSP3411"}, - {AUDIO_CHIP_MSP34XX, "MSP3416"}, + { V4L2_IDENT_MSPX4XX, "MSP3435" }, + { V4L2_IDENT_MSPX4XX, "MSP3440" }, + { V4L2_IDENT_MSPX4XX, "MSP3445" }, + { V4L2_IDENT_MSPX4XX, "MSP3411" }, + { V4L2_IDENT_MSPX4XX, "MSP3416" }, /* 15-19 */ - {AUDIO_CHIP_MSP34XX, "MSP3425"}, - {AUDIO_CHIP_MSP34XX, "MSP3451"}, - {AUDIO_CHIP_MSP34XX, "MSP3418"}, - {AUDIO_CHIP_UNKNOWN, "Type 0x12"}, - {AUDIO_CHIP_UNKNOWN, "OKI7716"}, + { V4L2_IDENT_MSPX4XX, "MSP3425" }, + { V4L2_IDENT_MSPX4XX, "MSP3451" }, + { V4L2_IDENT_MSPX4XX, "MSP3418" }, + { V4L2_IDENT_UNKNOWN, "Type 0x12" }, + { V4L2_IDENT_UNKNOWN, "OKI7716" }, /* 20-24 */ - {AUDIO_CHIP_MSP34XX, "MSP4410"}, - {AUDIO_CHIP_MSP34XX, "MSP4420"}, - {AUDIO_CHIP_MSP34XX, "MSP4440"}, - {AUDIO_CHIP_MSP34XX, "MSP4450"}, - {AUDIO_CHIP_MSP34XX, "MSP4408"}, + { V4L2_IDENT_MSPX4XX, "MSP4410" }, + { V4L2_IDENT_MSPX4XX, "MSP4420" }, + { V4L2_IDENT_MSPX4XX, "MSP4440" }, + { V4L2_IDENT_MSPX4XX, "MSP4450" }, + { V4L2_IDENT_MSPX4XX, "MSP4408" }, /* 25-29 */ - {AUDIO_CHIP_MSP34XX, "MSP4418"}, - {AUDIO_CHIP_MSP34XX, "MSP4428"}, - {AUDIO_CHIP_MSP34XX, "MSP4448"}, - {AUDIO_CHIP_MSP34XX, "MSP4458"}, - {AUDIO_CHIP_MSP34XX, "Type 0x1d"}, + { V4L2_IDENT_MSPX4XX, "MSP4418" }, + { V4L2_IDENT_MSPX4XX, "MSP4428" }, + { V4L2_IDENT_MSPX4XX, "MSP4448" }, + { V4L2_IDENT_MSPX4XX, "MSP4458" }, + { V4L2_IDENT_MSPX4XX, "Type 0x1d" }, /* 30-34 */ - {AUDIO_CHIP_INTERNAL, "CX880"}, - {AUDIO_CHIP_INTERNAL, "CX881"}, - {AUDIO_CHIP_INTERNAL, "CX883"}, - {AUDIO_CHIP_INTERNAL, "CX882"}, - {AUDIO_CHIP_INTERNAL, "CX25840"}, + { V4L2_IDENT_AMBIGUOUS, "CX880" }, + { V4L2_IDENT_AMBIGUOUS, "CX881" }, + { V4L2_IDENT_AMBIGUOUS, "CX883" }, + { V4L2_IDENT_AMBIGUOUS, "CX882" }, + { V4L2_IDENT_AMBIGUOUS, "CX25840" }, /* 35-39 */ - {AUDIO_CHIP_INTERNAL, "CX25841"}, - {AUDIO_CHIP_INTERNAL, "CX25842"}, - {AUDIO_CHIP_INTERNAL, "CX25843"}, - {AUDIO_CHIP_INTERNAL, "CX23418"}, - {AUDIO_CHIP_INTERNAL, "CX23885"}, + { V4L2_IDENT_AMBIGUOUS, "CX25841" }, + { V4L2_IDENT_AMBIGUOUS, "CX25842" }, + { V4L2_IDENT_AMBIGUOUS, "CX25843" }, + { V4L2_IDENT_AMBIGUOUS, "CX23418" }, + { V4L2_IDENT_AMBIGUOUS, "CX23885" }, /* 40-44 */ - {AUDIO_CHIP_INTERNAL, "CX23888"}, - {AUDIO_CHIP_INTERNAL, "SAA7131"}, - {AUDIO_CHIP_INTERNAL, "CX23887"}, - {AUDIO_CHIP_INTERNAL, "SAA7164"}, - {AUDIO_CHIP_INTERNAL, "AU8522"}, + { V4L2_IDENT_AMBIGUOUS, "CX23888" }, + { V4L2_IDENT_AMBIGUOUS, "SAA7131" }, + { V4L2_IDENT_AMBIGUOUS, "CX23887" }, + { V4L2_IDENT_AMBIGUOUS, "SAA7164" }, + { V4L2_IDENT_AMBIGUOUS, "AU8522" }, }; /* This list is supplied by Hauppauge. Thanks! */ @@ -509,7 +511,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, if (audioic < ARRAY_SIZE(audioIC)) tvee->audio_processor = audioIC[audioic].id; else - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; break; /* case 0x03: tag 'EEInfo' */ @@ -542,7 +544,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, if (audioic < ARRAY_SIZE(audioIC)) tvee->audio_processor = audioIC[audioic].id; else - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; break; @@ -690,7 +692,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, t_fmt_name2[6], t_fmt_name2[7], t_format2); if (audioic < 0) { tveeprom_info("audio processor is unknown (no idx)\n"); - tvee->audio_processor = AUDIO_CHIP_UNKNOWN; + tvee->audio_processor = V4L2_IDENT_UNKNOWN; } else { if (audioic < ARRAY_SIZE(audioIC)) tveeprom_info("audio processor is %s (idx %d)\n", diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index abf685464b7c..7d53de531c44 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c @@ -43,7 +43,6 @@ #include #include #include -#include #include diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 56cd685d35ea..5984c7562035 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -67,7 +67,6 @@ #include #include #include -#include #include diff --git a/include/media/audiochip.h b/include/media/audiochip.h index db8823d45a7d..e69de29bb2d1 100644 --- a/include/media/audiochip.h +++ b/include/media/audiochip.h @@ -1,26 +0,0 @@ -/* - */ - -#ifndef AUDIOCHIP_H -#define AUDIOCHIP_H - -enum audiochip { - AUDIO_CHIP_NONE, - AUDIO_CHIP_UNKNOWN, - /* Provided by video chip */ - AUDIO_CHIP_INTERNAL, - /* Provided by tvaudio.c */ - AUDIO_CHIP_TDA8425, - AUDIO_CHIP_TEA6300, - AUDIO_CHIP_TEA6420, - AUDIO_CHIP_TDA9840, - AUDIO_CHIP_TDA985X, - AUDIO_CHIP_TDA9874, - AUDIO_CHIP_PIC16C54, - /* Provided by msp3400.c */ - AUDIO_CHIP_MSP34XX, - /* Provided by wm8775.c */ - AUDIO_CHIP_WM8775 -}; - -#endif /* AUDIOCHIP_H */ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 2a527742701a..41b509babf3f 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -90,7 +90,10 @@ enum { /* module m52790: just ident 52790 */ V4L2_IDENT_M52790 = 52790, - /* module msp34xx: reserved range 34000-34999 */ + /* module msp3400: reserved range 34000-34999 and 44000-44999 */ + V4L2_IDENT_MSPX4XX = 34000, /* generic MSPX4XX identifier, only + use internally (tveeprom.c). */ + V4L2_IDENT_MSP3400B = 34002, V4L2_IDENT_MSP3410B = 34102, @@ -142,7 +145,7 @@ enum { V4L2_IDENT_MSP3457G = 34577, V4L2_IDENT_MSP3467G = 34677, - /* module msp44xx: reserved range 44000-44999 */ + /* module msp3400: reserved range 34000-34999 and 44000-44999 */ V4L2_IDENT_MSP4400G = 44007, V4L2_IDENT_MSP4410G = 44107, V4L2_IDENT_MSP4420G = 44207, -- cgit v1.2.3 From b654fcdc0ea3b6e5724c9873ae062bdfe7f28efe Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 22 Jul 2008 15:50:31 -0300 Subject: V4L/DVB (8479): tveeprom/ivtv: fix usage of has_ir field has_ir was set to and compared to -1 in several cases, even though it is an u32. ivtv also contained a FIXME for an old kernel that could be removed. Thanks to Roel Kluin for creating an initial patch for this. Although I chose a different solution here it did help in pointing out the problem. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.c | 5 ++--- drivers/media/video/tveeprom.c | 16 ++++++++-------- include/media/tveeprom.h | 7 ++++++- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 41fd79279bb5..aea1664948ce 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -465,9 +465,8 @@ static void ivtv_process_eeprom(struct ivtv *itv) if (itv->options.radio == -1) itv->options.radio = (tv.has_radio != 0); /* only enable newi2c if an IR blaster is present */ - /* FIXME: for 2.6.20 the test against 2 should be removed */ - if (itv->options.newi2c == -1 && tv.has_ir != -1 && tv.has_ir != 2) { - itv->options.newi2c = (tv.has_ir & 2) ? 1 : 0; + if (itv->options.newi2c == -1 && tv.has_ir) { + itv->options.newi2c = (tv.has_ir & 4) ? 1 : 0; if (itv->options.newi2c) { IVTV_INFO("Reopen i2c bus for IR-blaster support\n"); exit_ivtv_i2c(itv); diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 93954c143237..fbfac1b3bd02 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -485,7 +485,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, tvee->has_radio = eeprom_data[i+len-1]; /* old style tag, don't know how to detect IR presence, mark as unknown. */ - tvee->has_ir = -1; + tvee->has_ir = 0; tvee->model = eeprom_data[i+8] + (eeprom_data[i+9] << 8); @@ -605,7 +605,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, case 0x0f: /* tag 'IRInfo' */ - tvee->has_ir = eeprom_data[i+1]; + tvee->has_ir = 1 | (eeprom_data[i+1] << 1); break; /* case 0x10: tag 'VBIInfo' */ @@ -705,14 +705,14 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, tveeprom_info("decoder processor is %s (idx %d)\n", STRM(decoderIC, tvee->decoder_processor), tvee->decoder_processor); - if (tvee->has_ir == -1) - tveeprom_info("has %sradio\n", - tvee->has_radio ? "" : "no "); - else + if (tvee->has_ir) tveeprom_info("has %sradio, has %sIR receiver, has %sIR transmitter\n", tvee->has_radio ? "" : "no ", - (tvee->has_ir & 1) ? "" : "no ", - (tvee->has_ir & 2) ? "" : "no "); + (tvee->has_ir & 2) ? "" : "no ", + (tvee->has_ir & 4) ? "" : "no "); + else + tveeprom_info("has %sradio\n", + tvee->has_radio ? "" : "no "); } EXPORT_SYMBOL(tveeprom_hauppauge_analog); diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h index 5660ea24996b..a8ad75a9152a 100644 --- a/include/media/tveeprom.h +++ b/include/media/tveeprom.h @@ -3,7 +3,12 @@ struct tveeprom { u32 has_radio; - u32 has_ir; /* bit 0: IR receiver present, bit 1: IR transmitter (blaster) present. -1 == unknown */ + /* If has_ir == 0, then it is unknown what the IR capabilities are, + otherwise: + bit 0: 1 (= IR capabilities are known) + bit 1: IR receiver present + bit 2: IR transmitter (blaster) present */ + u32 has_ir; u32 has_MAC_address; /* 0: no MAC, 1: MAC present, 2: unknown */ u32 tuner_type; -- cgit v1.2.3 From a399810ca69d9d4bd30ab8c1678c7439e567f90b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Jul 2008 02:57:38 -0300 Subject: V4L/DVB (8482): videodev: move all ioctl callbacks to a new v4l2_ioctl_ops struct All ioctl callbacks are now stored in a new v4l2_ioctl_ops struct. Drivers fill in a const struct v4l2_ioctl_ops and video_device just contains a const pointer to it. This ensures a clean separation between the const ops struct and the non-const video_device struct. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 19 +- drivers/media/radio/radio-aimslab.c | 15 +- drivers/media/radio/radio-aztech.c | 15 +- drivers/media/radio/radio-cadet.c | 15 +- drivers/media/radio/radio-gemtek-pci.c | 14 +- drivers/media/radio/radio-gemtek.c | 14 +- drivers/media/radio/radio-maestro.c | 12 +- drivers/media/radio/radio-maxiradio.c | 16 +- drivers/media/radio/radio-rtrack2.c | 15 +- drivers/media/radio/radio-sf16fmi.c | 15 +- drivers/media/radio/radio-sf16fmr2.c | 15 +- drivers/media/radio/radio-si470x.c | 21 +- drivers/media/radio/radio-terratec.c | 15 +- drivers/media/radio/radio-trust.c | 15 +- drivers/media/radio/radio-typhoon.c | 15 +- drivers/media/radio/radio-zoltrix.c | 15 +- drivers/media/video/bt8xx/bttv-driver.c | 26 +- drivers/media/video/cafe_ccic.c | 25 +- drivers/media/video/cx18/cx18-ioctl.c | 92 +++--- drivers/media/video/cx23885/cx23885-417.c | 20 +- drivers/media/video/cx23885/cx23885-video.c | 16 +- drivers/media/video/cx88/cx88-blackbird.c | 16 +- drivers/media/video/cx88/cx88-video.c | 33 +- drivers/media/video/em28xx/em28xx-video.c | 46 +-- drivers/media/video/gspca/gspca.c | 16 +- drivers/media/video/ivtv/ivtv-ioctl.c | 130 ++++---- drivers/media/video/meye.c | 18 +- drivers/media/video/s2255drv.c | 16 +- drivers/media/video/saa7134/saa7134-empress.c | 22 +- drivers/media/video/saa7134/saa7134-video.c | 61 ++-- drivers/media/video/soc_camera.c | 56 ++-- drivers/media/video/stk-webcam.c | 31 +- drivers/media/video/usbvision/usbvision-video.c | 38 ++- drivers/media/video/v4l2-ioctl.c | 418 ++++++++++++------------ drivers/media/video/vivi.c | 18 +- drivers/media/video/zr364xx.c | 19 +- include/media/v4l2-dev.h | 222 +------------ include/media/v4l2-ioctl.h | 223 +++++++++++++ 38 files changed, 980 insertions(+), 828 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 97c6853ad1d3..08bf5e8031da 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -445,14 +445,7 @@ static const struct file_operations usb_dsbr100_fops = { .llseek = no_llseek, }; -/* V4L2 interface */ -static struct video_device dsbr100_videodev_template = -{ - .owner = THIS_MODULE, - .name = "D-Link DSB-R 100", - .type = VID_TYPE_TUNER, - .fops = &usb_dsbr100_fops, - .release = video_device_release, +static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -467,6 +460,16 @@ static struct video_device dsbr100_videodev_template = .vidioc_s_input = vidioc_s_input, }; +/* V4L2 interface */ +static struct video_device dsbr100_videodev_template = { + .owner = THIS_MODULE, + .name = "D-Link DSB-R 100", + .type = VID_TYPE_TUNER, + .fops = &usb_dsbr100_fops, + .ioctl_ops = &usb_dsbr100_ioctl_ops, + .release = video_device_release, +}; + /* check if the device is present and register with v4l and usb if it is */ static int usb_dsbr100_probe(struct usb_interface *intf, diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index ec8d64704dd0..be9bd7adaf61 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -389,12 +389,7 @@ static const struct file_operations rtrack_fops = { .llseek = no_llseek, }; -static struct video_device rtrack_radio= -{ - .owner = THIS_MODULE, - .name = "RadioTrack radio", - .type = VID_TYPE_TUNER, - .fops = &rtrack_fops, +static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -409,6 +404,14 @@ static struct video_device rtrack_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device rtrack_radio = { + .owner = THIS_MODULE, + .name = "RadioTrack radio", + .type = VID_TYPE_TUNER, + .fops = &rtrack_fops, + .ioctl_ops = &rtrack_ioctl_ops, +}; + static int __init rtrack_init(void) { if(io==-1) diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 639164a974a1..04c738b62d06 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -353,12 +353,7 @@ static const struct file_operations aztech_fops = { .llseek = no_llseek, }; -static struct video_device aztech_radio= -{ - .owner = THIS_MODULE, - .name = "Aztech radio", - .type = VID_TYPE_TUNER, - .fops = &aztech_fops, +static const struct v4l2_ioctl_ops aztech_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -373,6 +368,14 @@ static struct video_device aztech_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device aztech_radio = { + .owner = THIS_MODULE, + .name = "Aztech radio", + .type = VID_TYPE_TUNER, + .fops = &aztech_fops, + .ioctl_ops = &aztech_ioctl_ops, +}; + module_param_named(debug,aztech_radio.debug, int, 0644); MODULE_PARM_DESC(debug,"activates debug info"); diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 484ea87d7fba..36b850fc14b4 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -570,12 +570,7 @@ static const struct file_operations cadet_fops = { .llseek = no_llseek, }; -static struct video_device cadet_radio= -{ - .owner = THIS_MODULE, - .name = "Cadet radio", - .type = VID_TYPE_TUNER, - .fops = &cadet_fops, +static const struct v4l2_ioctl_ops cadet_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -590,6 +585,14 @@ static struct video_device cadet_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device cadet_radio = { + .owner = THIS_MODULE, + .name = "Cadet radio", + .type = VID_TYPE_TUNER, + .fops = &cadet_fops, + .ioctl_ops = &cadet_ioctl_ops, +}; + #ifdef CONFIG_PNP static struct pnp_device_id cadet_pnp_devices[] = { diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 2b834b95f3e7..c41b35f3b125 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -375,11 +375,7 @@ static const struct file_operations gemtek_pci_fops = { .llseek = no_llseek, }; -static struct video_device vdev_template = { - .owner = THIS_MODULE, - .name = "Gemtek PCI Radio", - .type = VID_TYPE_TUNER, - .fops = &gemtek_pci_fops, +static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -394,6 +390,14 @@ static struct video_device vdev_template = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device vdev_template = { + .owner = THIS_MODULE, + .name = "Gemtek PCI Radio", + .type = VID_TYPE_TUNER, + .fops = &gemtek_pci_fops, + .ioctl_ops = &gemtek_pci_ioctl_ops, +}; + static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id ) { struct gemtek_pci_card *card; diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 4740bacc2f88..f82b59f35e33 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -553,11 +553,7 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) return 0; } -static struct video_device gemtek_radio = { - .owner = THIS_MODULE, - .name = "GemTek Radio card", - .type = VID_TYPE_TUNER, - .fops = &gemtek_fops, +static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -572,6 +568,14 @@ static struct video_device gemtek_radio = { .vidioc_s_ctrl = vidioc_s_ctrl }; +static struct video_device gemtek_radio = { + .owner = THIS_MODULE, + .name = "GemTek Radio card", + .type = VID_TYPE_TUNER, + .fops = &gemtek_fops, + .ioctl_ops = &gemtek_ioctl_ops, +}; + /* * Initialization / cleanup related stuff. */ diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 040a73fac694..d074a8c90674 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -355,10 +355,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev) return (ofreq == radio_bits_get(dev)); } -static struct video_device maestro_radio = { - .name = "Maestro radio", - .type = VID_TYPE_TUNER, - .fops = &maestro_fops, +static const struct v4l2_ioctl_ops maestro_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -373,6 +370,13 @@ static struct video_device maestro_radio = { .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device maestro_radio = { + .name = "Maestro radio", + .type = VID_TYPE_TUNER, + .fops = &maestro_fops, + .ioctl_ops = &maestro_ioctl_ops, +}; + static int __devinit maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 9e824a7d5cc4..780516daebba 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -374,13 +374,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv, return -EINVAL; } -static struct video_device maxiradio_radio = -{ - .owner = THIS_MODULE, - .name = "Maxi Radio FM2000 radio", - .type = VID_TYPE_TUNER, - .fops = &maxiradio_fops, - +static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -395,6 +389,14 @@ static struct video_device maxiradio_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device maxiradio_radio = { + .owner = THIS_MODULE, + .name = "Maxi Radio FM2000 radio", + .type = VID_TYPE_TUNER, + .fops = &maxiradio_fops, + .ioctl_ops = &maxiradio_ioctl_ops, +}; + static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { if(!request_region(pci_resource_start(pdev, 0), diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index c3fb270f211b..045ae9d1067c 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -295,12 +295,7 @@ static const struct file_operations rtrack2_fops = { .llseek = no_llseek, }; -static struct video_device rtrack2_radio= -{ - .owner = THIS_MODULE, - .name = "RadioTrack II radio", - .type = VID_TYPE_TUNER, - .fops = &rtrack2_fops, +static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -315,6 +310,14 @@ static struct video_device rtrack2_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device rtrack2_radio = { + .owner = THIS_MODULE, + .name = "RadioTrack II radio", + .type = VID_TYPE_TUNER, + .fops = &rtrack2_fops, + .ioctl_ops = &rtrack2_ioctl_ops, +}; + static int __init rtrack2_init(void) { if(io==-1) diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index bb8b1c9107b1..75b68a024541 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -295,12 +295,7 @@ static const struct file_operations fmi_fops = { .llseek = no_llseek, }; -static struct video_device fmi_radio= -{ - .owner = THIS_MODULE, - .name = "SF16FMx radio", - .type = VID_TYPE_TUNER, - .fops = &fmi_fops, +static const struct v4l2_ioctl_ops fmi_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -315,6 +310,14 @@ static struct video_device fmi_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmi_radio = { + .owner = THIS_MODULE, + .name = "SF16FMx radio", + .type = VID_TYPE_TUNER, + .fops = &fmi_fops, + .ioctl_ops = &fmi_ioctl_ops, +}; + /* ladis: this is my card. does any other types exist? */ static struct isapnp_device_id id_table[] __devinitdata = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 9fa025b704cb..5ffddce80011 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -411,12 +411,7 @@ static const struct file_operations fmr2_fops = { .llseek = no_llseek, }; -static struct video_device fmr2_radio= -{ - .owner = THIS_MODULE, - .name = "SF16FMR2 radio", - . type = VID_TYPE_TUNER, - .fops = &fmr2_fops, +static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -431,6 +426,14 @@ static struct video_device fmr2_radio= .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device fmr2_radio = { + .owner = THIS_MODULE, + .name = "SF16FMR2 radio", + .type = VID_TYPE_TUNER, + .fops = &fmr2_fops, + .ioctl_ops = &fmr2_ioctl_ops, +}; + static int __init fmr2_init(void) { fmr2_unit.port = io; diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 333612180176..b829c67ecf0c 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -1586,15 +1586,7 @@ done: return retval; } - -/* - * si470x_viddev_tamples - video device interface - */ -static struct video_device si470x_viddev_template = { - .fops = &si470x_fops, - .name = DRIVER_NAME, - .type = VID_TYPE_TUNER, - .release = video_device_release, +static const struct v4l2_ioctl_ops si470x_ioctl_ops = { .vidioc_querycap = si470x_vidioc_querycap, .vidioc_g_input = si470x_vidioc_g_input, .vidioc_s_input = si470x_vidioc_s_input, @@ -1608,6 +1600,17 @@ static struct video_device si470x_viddev_template = { .vidioc_g_frequency = si470x_vidioc_g_frequency, .vidioc_s_frequency = si470x_vidioc_s_frequency, .vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek, +}; + +/* + * si470x_viddev_tamples - video device interface + */ +static struct video_device si470x_viddev_template = { + .fops = &si470x_fops, + .ioctl_ops = &si470x_ioctl_ops, + .name = DRIVER_NAME, + .type = VID_TYPE_TUNER, + .release = video_device_release, .owner = THIS_MODULE, }; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index a9914dbcf493..3a67471f999c 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -367,12 +367,7 @@ static const struct file_operations terratec_fops = { .llseek = no_llseek, }; -static struct video_device terratec_radio= -{ - .owner = THIS_MODULE, - .name = "TerraTec ActiveRadio", - .type = VID_TYPE_TUNER, - .fops = &terratec_fops, +static const struct v4l2_ioctl_ops terratec_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -387,6 +382,14 @@ static struct video_device terratec_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device terratec_radio = { + .owner = THIS_MODULE, + .name = "TerraTec ActiveRadio", + .type = VID_TYPE_TUNER, + .fops = &terratec_fops, + .ioctl_ops = &terratec_ioctl_ops, +}; + static int __init terratec_init(void) { if(io==-1) diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 560c49481a2d..e33400180915 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -347,12 +347,7 @@ static const struct file_operations trust_fops = { .llseek = no_llseek, }; -static struct video_device trust_radio= -{ - .owner = THIS_MODULE, - .name = "Trust FM Radio", - .type = VID_TYPE_TUNER, - .fops = &trust_fops, +static const struct v4l2_ioctl_ops trust_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -367,6 +362,14 @@ static struct video_device trust_radio= .vidioc_s_input = vidioc_s_input, }; +static struct video_device trust_radio = { + .owner = THIS_MODULE, + .name = "Trust FM Radio", + .type = VID_TYPE_TUNER, + .fops = &trust_fops, + .ioctl_ops = &trust_ioctl_ops, +}; + static int __init trust_init(void) { if(io == -1) { diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 023d6f3c751c..48b5d2bc6276 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -345,12 +345,7 @@ static const struct file_operations typhoon_fops = { .llseek = no_llseek, }; -static struct video_device typhoon_radio = -{ - .owner = THIS_MODULE, - .name = "Typhoon Radio", - .type = VID_TYPE_TUNER, - .fops = &typhoon_fops, +static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -365,6 +360,14 @@ static struct video_device typhoon_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device typhoon_radio = { + .owner = THIS_MODULE, + .name = "Typhoon Radio", + .type = VID_TYPE_TUNER, + .fops = &typhoon_fops, + .ioctl_ops = &typhoon_ioctl_ops, +}; + #ifdef CONFIG_RADIO_TYPHOON_PROC_FS static int typhoon_proc_show(struct seq_file *m, void *v) diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index cf0355bb6ef7..c60344326cd6 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -408,12 +408,7 @@ static const struct file_operations zoltrix_fops = .llseek = no_llseek, }; -static struct video_device zoltrix_radio = -{ - .owner = THIS_MODULE, - .name = "Zoltrix Radio Plus", - .type = VID_TYPE_TUNER, - .fops = &zoltrix_fops, +static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, @@ -428,6 +423,14 @@ static struct video_device zoltrix_radio = .vidioc_s_ctrl = vidioc_s_ctrl, }; +static struct video_device zoltrix_radio = { + .owner = THIS_MODULE, + .name = "Zoltrix Radio Plus", + .type = VID_TYPE_TUNER, + .fops = &zoltrix_fops, + .ioctl_ops = &zoltrix_ioctl_ops, +}; + static int __init zoltrix_init(void) { if (io == -1) { diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index 33c72055447d..dfa399da587d 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -3358,10 +3358,7 @@ static const struct file_operations bttv_fops = .poll = bttv_poll, }; -static struct video_device bttv_video_template = -{ - .fops = &bttv_fops, - .minor = -1, +static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_querycap = bttv_querycap, .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, @@ -3412,8 +3409,14 @@ static struct video_device bttv_video_template = .vidioc_g_register = bttv_g_register, .vidioc_s_register = bttv_s_register, #endif - .tvnorms = BTTV_NORMS, - .current_norm = V4L2_STD_PAL, +}; + +static struct video_device bttv_video_template = { + .fops = &bttv_fops, + .minor = -1, + .ioctl_ops = &bttv_ioctl_ops, + .tvnorms = BTTV_NORMS, + .current_norm = V4L2_STD_PAL, }; /* ----------------------------------------------------------------------- */ @@ -3636,10 +3639,7 @@ static const struct file_operations radio_fops = .poll = radio_poll, }; -static struct video_device radio_template = -{ - .fops = &radio_fops, - .minor = -1, +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -3656,6 +3656,12 @@ static struct video_device radio_template = .vidioc_s_frequency = bttv_s_frequency, }; +static struct video_device radio_template = { + .fops = &radio_fops, + .minor = -1, + .ioctl_ops = &radio_ioctl_ops, +}; + /* ----------------------------------------------------------------------- */ /* some debug code */ diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 302c57f151c2..4bbea458d0c0 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -1769,17 +1769,7 @@ static const struct file_operations cafe_v4l_fops = { .llseek = no_llseek, }; -static struct video_device cafe_v4l_template = { - .name = "cafe", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, - .minor = -1, /* Get one dynamically */ - .tvnorms = V4L2_STD_NTSC_M, - .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ - - .fops = &cafe_v4l_fops, - .release = cafe_v4l_dev_release, - +static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { .vidioc_querycap = cafe_vidioc_querycap, .vidioc_enum_fmt_vid_cap = cafe_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = cafe_vidioc_try_fmt_vid_cap, @@ -1802,6 +1792,19 @@ static struct video_device cafe_v4l_template = { .vidioc_s_parm = cafe_vidioc_s_parm, }; +static struct video_device cafe_v4l_template = { + .name = "cafe", + .type = VFL_TYPE_GRABBER, + .type2 = VID_TYPE_CAPTURE, + .minor = -1, /* Get one dynamically */ + .tvnorms = V4L2_STD_NTSC_M, + .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ + + .fops = &cafe_v4l_fops, + .ioctl_ops = &cafe_v4l_ioctl_ops, + .release = cafe_v4l_dev_release, +}; + diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 0d74e59e503e..a7f839631d6a 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c @@ -787,50 +787,54 @@ int cx18_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return res; } -void cx18_set_funcs(struct video_device *vdev) -{ - vdev->vidioc_querycap = cx18_querycap; - vdev->vidioc_g_priority = cx18_g_priority; - vdev->vidioc_s_priority = cx18_s_priority; - vdev->vidioc_s_audio = cx18_s_audio; - vdev->vidioc_g_audio = cx18_g_audio; - vdev->vidioc_enumaudio = cx18_enumaudio; - vdev->vidioc_enum_input = cx18_enum_input; - vdev->vidioc_cropcap = cx18_cropcap; - vdev->vidioc_s_crop = cx18_s_crop; - vdev->vidioc_g_crop = cx18_g_crop; - vdev->vidioc_g_input = cx18_g_input; - vdev->vidioc_s_input = cx18_s_input; - vdev->vidioc_g_frequency = cx18_g_frequency; - vdev->vidioc_s_frequency = cx18_s_frequency; - vdev->vidioc_s_tuner = cx18_s_tuner; - vdev->vidioc_g_tuner = cx18_g_tuner; - vdev->vidioc_g_enc_index = cx18_g_enc_index; - vdev->vidioc_g_std = cx18_g_std; - vdev->vidioc_s_std = cx18_s_std; - vdev->vidioc_log_status = cx18_log_status; - vdev->vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap; - vdev->vidioc_encoder_cmd = cx18_encoder_cmd; - vdev->vidioc_try_encoder_cmd = cx18_try_encoder_cmd; - vdev->vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap; - vdev->vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap; - vdev->vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap; - vdev->vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap; - vdev->vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap; - vdev->vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap; - vdev->vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap; - vdev->vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap; - vdev->vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap; - vdev->vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap; - vdev->vidioc_g_chip_ident = cx18_g_chip_ident; +static const struct v4l2_ioctl_ops cx18_ioctl_ops = { + .vidioc_querycap = cx18_querycap, + .vidioc_g_priority = cx18_g_priority, + .vidioc_s_priority = cx18_s_priority, + .vidioc_s_audio = cx18_s_audio, + .vidioc_g_audio = cx18_g_audio, + .vidioc_enumaudio = cx18_enumaudio, + .vidioc_enum_input = cx18_enum_input, + .vidioc_cropcap = cx18_cropcap, + .vidioc_s_crop = cx18_s_crop, + .vidioc_g_crop = cx18_g_crop, + .vidioc_g_input = cx18_g_input, + .vidioc_s_input = cx18_s_input, + .vidioc_g_frequency = cx18_g_frequency, + .vidioc_s_frequency = cx18_s_frequency, + .vidioc_s_tuner = cx18_s_tuner, + .vidioc_g_tuner = cx18_g_tuner, + .vidioc_g_enc_index = cx18_g_enc_index, + .vidioc_g_std = cx18_g_std, + .vidioc_s_std = cx18_s_std, + .vidioc_log_status = cx18_log_status, + .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap, + .vidioc_encoder_cmd = cx18_encoder_cmd, + .vidioc_try_encoder_cmd = cx18_try_encoder_cmd, + .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap, + .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap, + .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap, + .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap, + .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap, + .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap, + .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap, + .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap, + .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap, + .vidioc_g_chip_ident = cx18_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = cx18_g_register; - vdev->vidioc_s_register = cx18_s_register; + .vidioc_g_register = cx18_g_register, + .vidioc_s_register = cx18_s_register, #endif - vdev->vidioc_default = cx18_default; - vdev->vidioc_queryctrl = cx18_queryctrl; - vdev->vidioc_querymenu = cx18_querymenu; - vdev->vidioc_g_ext_ctrls = cx18_g_ext_ctrls; - vdev->vidioc_s_ext_ctrls = cx18_s_ext_ctrls; - vdev->vidioc_try_ext_ctrls = cx18_try_ext_ctrls; + .vidioc_default = cx18_default, + .vidioc_queryctrl = cx18_queryctrl, + .vidioc_querymenu = cx18_querymenu, + .vidioc_g_ext_ctrls = cx18_g_ext_ctrls, + .vidioc_s_ext_ctrls = cx18_s_ext_ctrls, + .vidioc_try_ext_ctrls = cx18_try_ext_ctrls, +}; + +void cx18_set_funcs(struct video_device *vdev) +{ + vdev->ioctl_ops = &cx18_ioctl_ops; } diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 4d0dcb06c19d..9d15d8a353fa 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1700,14 +1700,7 @@ static struct file_operations mpeg_fops = { .llseek = no_llseek, }; -static struct video_device cx23885_mpeg_template = { - .name = "cx23885", - .type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_SCALES | - VID_TYPE_MPEG_ENCODER, - .fops = &mpeg_fops, - .minor = -1, +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_s_std = vidioc_s_std, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1736,6 +1729,17 @@ static struct video_device cx23885_mpeg_template = { .vidioc_queryctrl = vidioc_queryctrl, }; +static struct video_device cx23885_mpeg_template = { + .name = "cx23885", + .type = VID_TYPE_CAPTURE | + VID_TYPE_TUNER | + VID_TYPE_SCALES | + VID_TYPE_MPEG_ENCODER, + .fops = &mpeg_fops, + .ioctl_ops = &mpeg_ioctl_ops, + .minor = -1, +}; + void cx23885_417_unregister(struct cx23885_dev *dev) { dprintk(1, "%s()\n", __func__); diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 245712e45f69..308caa2085ba 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1434,12 +1434,7 @@ static const struct file_operations video_fops = { .llseek = no_llseek, }; -static struct video_device cx23885_vbi_template; -static struct video_device cx23885_video_template = { - .name = "cx23885-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1472,6 +1467,15 @@ static struct video_device cx23885_video_template = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device cx23885_vbi_template; +static struct video_device cx23885_video_template = { + .name = "cx23885-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, + .fops = &video_fops, + .minor = -1, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX23885_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 4d1a461f329f..55c35482089e 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1175,12 +1175,7 @@ static const struct file_operations mpeg_fops = .llseek = no_llseek, }; -static struct video_device cx8802_mpeg_template = -{ - .name = "cx8802", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES|VID_TYPE_MPEG_ENCODER, - .fops = &mpeg_fops, - .minor = -1, +static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { .vidioc_querymenu = vidioc_querymenu, .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, @@ -1208,6 +1203,15 @@ static struct video_device cx8802_mpeg_template = .vidioc_g_tuner = vidioc_g_tuner, .vidioc_s_tuner = vidioc_s_tuner, .vidioc_s_std = vidioc_s_std, +}; + +static struct video_device cx8802_mpeg_template = { + .name = "cx8802", + .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | + VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER, + .fops = &mpeg_fops, + .ioctl_ops = &mpeg_ioctl_ops, + .minor = -1, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index f8cc55db9f42..24b403b238d1 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1683,13 +1683,7 @@ static const struct file_operations video_fops = .llseek = no_llseek, }; -static struct video_device cx8800_vbi_template; -static struct video_device cx8800_video_template = -{ - .name = "cx8800-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1722,6 +1716,16 @@ static struct video_device cx8800_video_template = .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device cx8800_vbi_template; + +static struct video_device cx8800_video_template = { + .name = "cx8800-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, + .fops = &video_fops, + .minor = -1, + .ioctl_ops = &video_ioctl_ops, .tvnorms = CX88_NORMS, .current_norm = V4L2_STD_NTSC_M, }; @@ -1736,12 +1740,7 @@ static const struct file_operations radio_fops = .llseek = no_llseek, }; -static struct video_device cx8800_radio_template = -{ - .name = "cx8800-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -1760,6 +1759,14 @@ static struct video_device cx8800_radio_template = #endif }; +static struct video_device cx8800_radio_template = { + .name = "cx8800-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .minor = -1, + .ioctl_ops = &radio_ioctl_ops, +}; + /* ----------------------------------------------------------- */ static void cx8800_unregister_video(struct cx8800_dev *dev) diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 67c62eaa5b6d..fcfc7413f74c 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1764,20 +1764,7 @@ static const struct file_operations em28xx_v4l_fops = { .compat_ioctl = v4l_compat_ioctl32, }; -static const struct file_operations radio_fops = { - .owner = THIS_MODULE, - .open = em28xx_v4l2_open, - .release = em28xx_v4l2_close, - .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, -}; - -static const struct video_device em28xx_video_template = { - .fops = &em28xx_v4l_fops, - .release = video_device_release, - - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1815,16 +1802,29 @@ static const struct video_device em28xx_video_template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif +}; + +static const struct video_device em28xx_video_template = { + .fops = &em28xx_v4l_fops, + .release = video_device_release, + .ioctl_ops = &video_ioctl_ops, + + .minor = -1, .tvnorms = V4L2_STD_ALL, .current_norm = V4L2_STD_PAL, }; -static struct video_device em28xx_radio_template = { - .name = "em28xx-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct file_operations radio_fops = { + .owner = THIS_MODULE, + .open = em28xx_v4l2_open, + .release = em28xx_v4l2_close, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .llseek = no_llseek, +}; + +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -1843,6 +1843,14 @@ static struct video_device em28xx_radio_template = { #endif }; +static struct video_device em28xx_radio_template = { + .name = "em28xx-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .ioctl_ops = &radio_ioctl_ops, + .minor = -1, +}; + /******************************** usb interface ******************************/ diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 0f09784631ad..2a416cf205aa 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1651,12 +1651,7 @@ static struct file_operations dev_fops = { .poll = dev_poll, }; -static struct video_device gspca_template = { - .name = "gspca main driver", - .type = VID_TYPE_CAPTURE, - .fops = &dev_fops, - .release = dev_release, /* mandatory */ - .minor = -1, +static const struct v4l2_ioctl_ops dev_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_dqbuf = vidioc_dqbuf, .vidioc_qbuf = vidioc_qbuf, @@ -1685,6 +1680,15 @@ static struct video_device gspca_template = { #endif }; +static struct video_device gspca_template = { + .name = "gspca main driver", + .type = VID_TYPE_CAPTURE, + .fops = &dev_fops, + .ioctl_ops = &dev_ioctl_ops, + .release = dev_release, /* mandatory */ + .minor = -1, +}; + /* * probe and create a new gspca device * diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 52e00a7f3110..61030309d0ad 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1842,69 +1842,73 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, return res; } -void ivtv_set_funcs(struct video_device *vdev) -{ - vdev->vidioc_querycap = ivtv_querycap; - vdev->vidioc_g_priority = ivtv_g_priority; - vdev->vidioc_s_priority = ivtv_s_priority; - vdev->vidioc_s_audio = ivtv_s_audio; - vdev->vidioc_g_audio = ivtv_g_audio; - vdev->vidioc_enumaudio = ivtv_enumaudio; - vdev->vidioc_s_audout = ivtv_s_audout; - vdev->vidioc_g_audout = ivtv_g_audout; - vdev->vidioc_enum_input = ivtv_enum_input; - vdev->vidioc_enum_output = ivtv_enum_output; - vdev->vidioc_enumaudout = ivtv_enumaudout; - vdev->vidioc_cropcap = ivtv_cropcap; - vdev->vidioc_s_crop = ivtv_s_crop; - vdev->vidioc_g_crop = ivtv_g_crop; - vdev->vidioc_g_input = ivtv_g_input; - vdev->vidioc_s_input = ivtv_s_input; - vdev->vidioc_g_output = ivtv_g_output; - vdev->vidioc_s_output = ivtv_s_output; - vdev->vidioc_g_frequency = ivtv_g_frequency; - vdev->vidioc_s_frequency = ivtv_s_frequency; - vdev->vidioc_s_tuner = ivtv_s_tuner; - vdev->vidioc_g_tuner = ivtv_g_tuner; - vdev->vidioc_g_enc_index = ivtv_g_enc_index; - vdev->vidioc_g_fbuf = ivtv_g_fbuf; - vdev->vidioc_s_fbuf = ivtv_s_fbuf; - vdev->vidioc_g_std = ivtv_g_std; - vdev->vidioc_s_std = ivtv_s_std; - vdev->vidioc_overlay = ivtv_overlay; - vdev->vidioc_log_status = ivtv_log_status; - vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap; - vdev->vidioc_encoder_cmd = ivtv_encoder_cmd; - vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd; - vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out; - vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap; - vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap; - vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap; - vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out; - vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay; - vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out; - vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap; - vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap; - vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap; - vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out; - vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay; - vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out; - vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap; - vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap; - vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap; - vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out; - vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay; - vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out; - vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap; - vdev->vidioc_g_chip_ident = ivtv_g_chip_ident; +static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { + .vidioc_querycap = ivtv_querycap, + .vidioc_g_priority = ivtv_g_priority, + .vidioc_s_priority = ivtv_s_priority, + .vidioc_s_audio = ivtv_s_audio, + .vidioc_g_audio = ivtv_g_audio, + .vidioc_enumaudio = ivtv_enumaudio, + .vidioc_s_audout = ivtv_s_audout, + .vidioc_g_audout = ivtv_g_audout, + .vidioc_enum_input = ivtv_enum_input, + .vidioc_enum_output = ivtv_enum_output, + .vidioc_enumaudout = ivtv_enumaudout, + .vidioc_cropcap = ivtv_cropcap, + .vidioc_s_crop = ivtv_s_crop, + .vidioc_g_crop = ivtv_g_crop, + .vidioc_g_input = ivtv_g_input, + .vidioc_s_input = ivtv_s_input, + .vidioc_g_output = ivtv_g_output, + .vidioc_s_output = ivtv_s_output, + .vidioc_g_frequency = ivtv_g_frequency, + .vidioc_s_frequency = ivtv_s_frequency, + .vidioc_s_tuner = ivtv_s_tuner, + .vidioc_g_tuner = ivtv_g_tuner, + .vidioc_g_enc_index = ivtv_g_enc_index, + .vidioc_g_fbuf = ivtv_g_fbuf, + .vidioc_s_fbuf = ivtv_s_fbuf, + .vidioc_g_std = ivtv_g_std, + .vidioc_s_std = ivtv_s_std, + .vidioc_overlay = ivtv_overlay, + .vidioc_log_status = ivtv_log_status, + .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap, + .vidioc_encoder_cmd = ivtv_encoder_cmd, + .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd, + .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out, + .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap, + .vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap, + .vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap, + .vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out, + .vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay, + .vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out, + .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap, + .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap, + .vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap, + .vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out, + .vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay, + .vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out, + .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap, + .vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap, + .vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap, + .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out, + .vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay, + .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out, + .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap, + .vidioc_g_chip_ident = ivtv_g_chip_ident, #ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = ivtv_g_register; - vdev->vidioc_s_register = ivtv_s_register; + .vidioc_g_register = ivtv_g_register, + .vidioc_s_register = ivtv_s_register, #endif - vdev->vidioc_default = ivtv_default; - vdev->vidioc_queryctrl = ivtv_queryctrl; - vdev->vidioc_querymenu = ivtv_querymenu; - vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls; - vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls; - vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls; + .vidioc_default = ivtv_default, + .vidioc_queryctrl = ivtv_queryctrl, + .vidioc_querymenu = ivtv_querymenu, + .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, + .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, + .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, +}; + +void ivtv_set_funcs(struct video_device *vdev) +{ + vdev->ioctl_ops = &ivtv_ioctl_ops; } diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index a1fb9874fdcf..fd16ef0a5868 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1698,13 +1698,7 @@ static const struct file_operations meye_fops = { .llseek = no_llseek, }; -static struct video_device meye_template = { - .owner = THIS_MODULE, - .name = "meye", - .type = VID_TYPE_CAPTURE, - .fops = &meye_fops, - .release = video_device_release, - .minor = -1, +static const struct v4l2_ioctl_ops meye_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1725,6 +1719,16 @@ static struct video_device meye_template = { .vidioc_default = vidioc_default, }; +static struct video_device meye_template = { + .owner = THIS_MODULE, + .name = "meye", + .type = VID_TYPE_CAPTURE, + .fops = &meye_fops, + .ioctl_ops = &meye_ioctl_ops, + .release = video_device_release, + .minor = -1, +}; + #ifdef CONFIG_PM static int meye_suspend(struct pci_dev *pdev, pm_message_t state) { diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index eb81915935b1..2428d441fe15 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1659,12 +1659,7 @@ static const struct file_operations s2255_fops_v4l = { .llseek = no_llseek, }; -static struct video_device template = { - .name = "s2255v", - .type = VID_TYPE_CAPTURE, - .fops = &s2255_fops_v4l, - .minor = -1, - .release = video_device_release, +static const struct v4l2_ioctl_ops s2255_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1686,6 +1681,15 @@ static struct video_device template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidioc_cgmbuf, #endif +}; + +static struct video_device template = { + .name = "s2255v", + .type = VID_TYPE_CAPTURE, + .fops = &s2255_fops_v4l, + .ioctl_ops = &s2255_ioctl_ops, + .minor = -1, + .release = video_device_release, .tvnorms = S2255_NORMS, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 3854cc29752d..8b3f95167781 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -400,16 +400,7 @@ static const struct file_operations ts_fops = .llseek = no_llseek, }; -/* ----------------------------------------------------------- */ - -static struct video_device saa7134_empress_template = -{ - .name = "saa7134-empress", - .type = 0 /* FIXME */, - .type2 = 0 /* FIXME */, - .fops = &ts_fops, - .minor = -1, - +static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_querycap = empress_querycap, .vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap, .vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap, @@ -430,6 +421,17 @@ static struct video_device saa7134_empress_template = .vidioc_querymenu = empress_querymenu, .vidioc_g_ctrl = saa7134_g_ctrl, .vidioc_s_ctrl = saa7134_s_ctrl, +}; + +/* ----------------------------------------------------------- */ + +static struct video_device saa7134_empress_template = { + .name = "saa7134-empress", + .type = 0 /* FIXME */, + .type2 = 0 /* FIXME */, + .fops = &ts_fops, + .minor = -1, + .ioctl_ops = &ts_ioctl_ops, .tvnorms = SAA7134_NORMS, .current_norm = V4L2_STD_PAL, diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 1a5137550e7a..5e9cfc891be8 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2353,26 +2353,7 @@ static const struct file_operations video_fops = .llseek = no_llseek, }; -static const struct file_operations radio_fops = -{ - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .ioctl = video_ioctl2, - .compat_ioctl = v4l_compat_ioctl32, - .llseek = no_llseek, -}; - -/* ----------------------------------------------------------- */ -/* exported stuff */ - -struct video_device saa7134_video_template = -{ - .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | - VID_TYPE_CLIPPING|VID_TYPE_SCALES, - .fops = &video_fops, - .minor = -1, +static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_querycap = saa7134_querycap, .vidioc_enum_fmt_vid_cap = saa7134_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap, @@ -2421,16 +2402,18 @@ struct video_device saa7134_video_template = .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif - .tvnorms = SAA7134_NORMS, - .current_norm = V4L2_STD_PAL, }; -struct video_device saa7134_radio_template = -{ - .name = "saa7134-radio", - .type = VID_TYPE_TUNER, - .fops = &radio_fops, - .minor = -1, +static const struct file_operations radio_fops = { + .owner = THIS_MODULE, + .open = video_open, + .release = video_release, + .ioctl = video_ioctl2, + .compat_ioctl = v4l_compat_ioctl32, + .llseek = no_llseek, +}; + +static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = radio_querycap, .vidioc_g_tuner = radio_g_tuner, .vidioc_enum_input = radio_enum_input, @@ -2447,6 +2430,28 @@ struct video_device saa7134_radio_template = .vidioc_s_frequency = saa7134_s_frequency, }; +/* ----------------------------------------------------------- */ +/* exported stuff */ + +struct video_device saa7134_video_template = { + .name = "saa7134-video", + .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | + VID_TYPE_CLIPPING|VID_TYPE_SCALES, + .fops = &video_fops, + .ioctl_ops = &video_ioctl_ops, + .minor = -1, + .tvnorms = SAA7134_NORMS, + .current_norm = V4L2_STD_PAL, +}; + +struct video_device saa7134_radio_template = { + .name = "saa7134-radio", + .type = VID_TYPE_TUNER, + .fops = &radio_fops, + .ioctl_ops = &radio_ioctl_ops, + .minor = -1, +}; + int saa7134_video_init1(struct saa7134_dev *dev) { /* sanitycheck insmod options */ diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b01749088472..9ff561452587 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -862,6 +862,35 @@ void soc_camera_device_unregister(struct soc_camera_device *icd) } EXPORT_SYMBOL(soc_camera_device_unregister); +static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { + .vidioc_querycap = soc_camera_querycap, + .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, + .vidioc_enum_input = soc_camera_enum_input, + .vidioc_g_input = soc_camera_g_input, + .vidioc_s_input = soc_camera_s_input, + .vidioc_s_std = soc_camera_s_std, + .vidioc_reqbufs = soc_camera_reqbufs, + .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, + .vidioc_querybuf = soc_camera_querybuf, + .vidioc_qbuf = soc_camera_qbuf, + .vidioc_dqbuf = soc_camera_dqbuf, + .vidioc_streamon = soc_camera_streamon, + .vidioc_streamoff = soc_camera_streamoff, + .vidioc_queryctrl = soc_camera_queryctrl, + .vidioc_g_ctrl = soc_camera_g_ctrl, + .vidioc_s_ctrl = soc_camera_s_ctrl, + .vidioc_cropcap = soc_camera_cropcap, + .vidioc_g_crop = soc_camera_g_crop, + .vidioc_s_crop = soc_camera_s_crop, + .vidioc_g_chip_ident = soc_camera_g_chip_ident, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .vidioc_g_register = soc_camera_g_register, + .vidioc_s_register = soc_camera_s_register, +#endif +}; + int soc_camera_video_start(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); @@ -882,35 +911,10 @@ int soc_camera_video_start(struct soc_camera_device *icd) vdev->type = VID_TYPE_CAPTURE; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; + vdev->ioctl_ops = &soc_camera_ioctl_ops; vdev->release = video_device_release; vdev->minor = -1; vdev->tvnorms = V4L2_STD_UNKNOWN, - vdev->vidioc_querycap = soc_camera_querycap; - vdev->vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap; - vdev->vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap; - vdev->vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap; - vdev->vidioc_enum_input = soc_camera_enum_input; - vdev->vidioc_g_input = soc_camera_g_input; - vdev->vidioc_s_input = soc_camera_s_input; - vdev->vidioc_s_std = soc_camera_s_std; - vdev->vidioc_reqbufs = soc_camera_reqbufs; - vdev->vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap; - vdev->vidioc_querybuf = soc_camera_querybuf; - vdev->vidioc_qbuf = soc_camera_qbuf; - vdev->vidioc_dqbuf = soc_camera_dqbuf; - vdev->vidioc_streamon = soc_camera_streamon; - vdev->vidioc_streamoff = soc_camera_streamoff; - vdev->vidioc_queryctrl = soc_camera_queryctrl; - vdev->vidioc_g_ctrl = soc_camera_g_ctrl; - vdev->vidioc_s_ctrl = soc_camera_s_ctrl; - vdev->vidioc_cropcap = soc_camera_cropcap; - vdev->vidioc_g_crop = soc_camera_g_crop; - vdev->vidioc_s_crop = soc_camera_s_crop; - vdev->vidioc_g_chip_ident = soc_camera_g_chip_ident; -#ifdef CONFIG_VIDEO_ADV_DEBUG - vdev->vidioc_g_register = soc_camera_g_register; - vdev->vidioc_s_register = soc_camera_s_register; -#endif icd->current_fmt = &icd->formats[0]; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 20028aeb842b..8d5fa95ad95a 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1328,20 +1328,7 @@ static struct file_operations v4l_stk_fops = { .llseek = no_llseek }; -static void stk_v4l_dev_release(struct video_device *vd) -{ -} - -static struct video_device stk_v4l_data = { - .name = "stkwebcam", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, - .minor = -1, - .tvnorms = V4L2_STD_UNKNOWN, - .current_norm = V4L2_STD_UNKNOWN, - .fops = &v4l_stk_fops, - .release = stk_v4l_dev_release, - +static const struct v4l2_ioctl_ops v4l_stk_ioctl_ops = { .vidioc_querycap = stk_vidioc_querycap, .vidioc_enum_fmt_vid_cap = stk_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = stk_vidioc_try_fmt_vid_cap, @@ -1363,6 +1350,22 @@ static struct video_device stk_v4l_data = { .vidioc_g_parm = stk_vidioc_g_parm, }; +static void stk_v4l_dev_release(struct video_device *vd) +{ +} + +static struct video_device stk_v4l_data = { + .name = "stkwebcam", + .type = VFL_TYPE_GRABBER, + .type2 = VID_TYPE_CAPTURE, + .minor = -1, + .tvnorms = V4L2_STD_UNKNOWN, + .current_norm = V4L2_STD_UNKNOWN, + .fops = &v4l_stk_fops, + .ioctl_ops = &v4l_stk_ioctl_ops, + .release = stk_v4l_dev_release, +}; + static int stk_register_video_device(struct stk_camera *dev) { diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 5984c7562035..7eccdc1ea2d7 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1370,13 +1370,8 @@ static const struct file_operations usbvision_fops = { /* .poll = video_poll, */ .compat_ioctl = v4l_compat_ioctl32, }; -static struct video_device usbvision_video_template = { - .owner = THIS_MODULE, - .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, - .fops = &usbvision_fops, - .name = "usbvision-video", - .release = video_device_release, - .minor = -1, + +static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1408,6 +1403,16 @@ static struct video_device usbvision_video_template = { .vidioc_g_register = vidioc_g_register, .vidioc_s_register = vidioc_s_register, #endif +}; + +static struct video_device usbvision_video_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, + .fops = &usbvision_fops, + .ioctl_ops = &usbvision_ioctl_ops, + .name = "usbvision-video", + .release = video_device_release, + .minor = -1, .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL }; @@ -1423,14 +1428,7 @@ static const struct file_operations usbvision_radio_fops = { .compat_ioctl = v4l_compat_ioctl32, }; -static struct video_device usbvision_radio_template= -{ - .owner = THIS_MODULE, - .type = VID_TYPE_TUNER, - .fops = &usbvision_radio_fops, - .name = "usbvision-radio", - .release = video_device_release, - .minor = -1, +static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_input = vidioc_enum_input, .vidioc_g_input = vidioc_g_input, @@ -1444,6 +1442,16 @@ static struct video_device usbvision_radio_template= .vidioc_s_tuner = vidioc_s_tuner, .vidioc_g_frequency = vidioc_g_frequency, .vidioc_s_frequency = vidioc_s_frequency, +}; + +static struct video_device usbvision_radio_template = { + .owner = THIS_MODULE, + .type = VID_TYPE_TUNER, + .fops = &usbvision_radio_fops, + .name = "usbvision-radio", + .release = video_device_release, + .minor = -1, + .ioctl_ops = &usbvision_radio_ioctl_ops, .tvnorms = USBVISION_NORMS, .current_norm = V4L2_STD_PAL diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 56a4fdee9160..fdfe7739c96e 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -579,43 +579,46 @@ static inline int check_ext_ctrls(struct v4l2_ext_controls *c, int allow_priv) return 1; } -static int check_fmt(struct video_device *vfd, enum v4l2_buf_type type) +static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type) { + if (ops == NULL) + return -EINVAL; + switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) + if (ops->vidioc_try_fmt_vid_cap) return 0; break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) + if (ops->vidioc_try_fmt_vid_overlay) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) + if (ops->vidioc_try_fmt_vid_out) return 0; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) + if (ops->vidioc_try_fmt_vid_out_overlay) return 0; break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) + if (ops->vidioc_try_fmt_vbi_cap) return 0; break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) + if (ops->vidioc_try_fmt_vbi_out) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) + if (ops->vidioc_try_fmt_sliced_vbi_cap) return 0; break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) + if (ops->vidioc_try_fmt_sliced_vbi_out) return 0; break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) + if (ops->vidioc_try_fmt_type_private) return 0; break; } @@ -626,6 +629,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct video_device *vfd = video_devdata(file); + const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; void *fh = file->private_data; int ret = -EINVAL; @@ -635,6 +639,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, printk(KERN_CONT "\n"); } + if (ops == NULL) { + printk(KERN_WARNING "videodev: \"%s\" has no ioctl_ops.\n", + vfd->name); + return -EINVAL; + } + #ifdef CONFIG_VIDEO_V4L1_COMPAT /*********************************************************** Handles calls to the obsoleted V4L1 API @@ -648,9 +658,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, memset(p, 0, sizeof(*p)); - if (!vfd->vidiocgmbuf) + if (!ops->vidiocgmbuf) return ret; - ret = vfd->vidiocgmbuf(file, fh, p); + ret = ops->vidiocgmbuf(file, fh, p); if (!ret) dbgarg(cmd, "size=%d, frames=%d, offsets=0x%08lx\n", p->size, p->frames, @@ -676,10 +686,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_capability *cap = (struct v4l2_capability *)arg; memset(cap, 0, sizeof(*cap)); - if (!vfd->vidioc_querycap) + if (!ops->vidioc_querycap) break; - ret = vfd->vidioc_querycap(file, fh, cap); + ret = ops->vidioc_querycap(file, fh, cap); if (!ret) dbgarg(cmd, "driver=%s, card=%s, bus=%s, " "version=0x%08x, " @@ -695,9 +705,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { enum v4l2_priority *p = arg; - if (!vfd->vidioc_g_priority) + if (!ops->vidioc_g_priority) break; - ret = vfd->vidioc_g_priority(file, fh, p); + ret = ops->vidioc_g_priority(file, fh, p); if (!ret) dbgarg(cmd, "priority is %d\n", *p); break; @@ -706,10 +716,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { enum v4l2_priority *p = arg; - if (!vfd->vidioc_s_priority) + if (!ops->vidioc_s_priority) break; dbgarg(cmd, "setting priority to %d\n", *p); - ret = vfd->vidioc_s_priority(file, fh, *p); + ret = ops->vidioc_s_priority(file, fh, *p); break; } @@ -728,12 +738,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_enum_fmt_vid_cap) - ret = vfd->vidioc_enum_fmt_vid_cap(file, fh, f); + if (ops->vidioc_enum_fmt_vid_cap) + ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_enum_fmt_vid_overlay) - ret = vfd->vidioc_enum_fmt_vid_overlay(file, + if (ops->vidioc_enum_fmt_vid_overlay) + ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, f); break; #if 1 @@ -742,19 +752,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, * it though, so just warn that this is deprecated and will be * removed in the near future. */ case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_enum_fmt_vbi_cap) { + if (ops->vidioc_enum_fmt_vbi_cap) { printk(KERN_WARNING "vidioc_enum_fmt_vbi_cap will be removed in 2.6.28!\n"); - ret = vfd->vidioc_enum_fmt_vbi_cap(file, fh, f); + ret = ops->vidioc_enum_fmt_vbi_cap(file, fh, f); } break; #endif case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_enum_fmt_vid_out) - ret = vfd->vidioc_enum_fmt_vid_out(file, fh, f); + if (ops->vidioc_enum_fmt_vid_out) + ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_enum_fmt_type_private) - ret = vfd->vidioc_enum_fmt_type_private(file, + if (ops->vidioc_enum_fmt_type_private) + ret = ops->vidioc_enum_fmt_type_private(file, fh, f); break; default: @@ -782,48 +792,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_g_fmt_vid_cap) - ret = vfd->vidioc_g_fmt_vid_cap(file, fh, f); + if (ops->vidioc_g_fmt_vid_cap) + ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_g_fmt_vid_overlay) - ret = vfd->vidioc_g_fmt_vid_overlay(file, + if (ops->vidioc_g_fmt_vid_overlay) + ret = ops->vidioc_g_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_g_fmt_vid_out) - ret = vfd->vidioc_g_fmt_vid_out(file, fh, f); + if (ops->vidioc_g_fmt_vid_out) + ret = ops->vidioc_g_fmt_vid_out(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_g_fmt_vid_out_overlay) - ret = vfd->vidioc_g_fmt_vid_out_overlay(file, + if (ops->vidioc_g_fmt_vid_out_overlay) + ret = ops->vidioc_g_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_vbi_cap) - ret = vfd->vidioc_g_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_g_fmt_vbi_cap) + ret = ops->vidioc_g_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_vbi_out) - ret = vfd->vidioc_g_fmt_vbi_out(file, fh, f); + if (ops->vidioc_g_fmt_vbi_out) + ret = ops->vidioc_g_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_g_fmt_sliced_vbi_cap) - ret = vfd->vidioc_g_fmt_sliced_vbi_cap(file, + if (ops->vidioc_g_fmt_sliced_vbi_cap) + ret = ops->vidioc_g_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_g_fmt_sliced_vbi_out) - ret = vfd->vidioc_g_fmt_sliced_vbi_out(file, + if (ops->vidioc_g_fmt_sliced_vbi_out) + ret = ops->vidioc_g_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_g_fmt_type_private) - ret = vfd->vidioc_g_fmt_type_private(file, + if (ops->vidioc_g_fmt_type_private) + ret = ops->vidioc_g_fmt_type_private(file, fh, f); break; } @@ -840,45 +850,45 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_cap) - ret = vfd->vidioc_s_fmt_vid_cap(file, fh, f); + if (ops->vidioc_s_fmt_vid_cap) + ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_s_fmt_vid_overlay) - ret = vfd->vidioc_s_fmt_vid_overlay(file, + if (ops->vidioc_s_fmt_vid_overlay) + ret = ops->vidioc_s_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: v4l_print_pix_fmt(vfd, &f->fmt.pix); - if (vfd->vidioc_s_fmt_vid_out) - ret = vfd->vidioc_s_fmt_vid_out(file, fh, f); + if (ops->vidioc_s_fmt_vid_out) + ret = ops->vidioc_s_fmt_vid_out(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_s_fmt_vid_out_overlay) - ret = vfd->vidioc_s_fmt_vid_out_overlay(file, + if (ops->vidioc_s_fmt_vid_out_overlay) + ret = ops->vidioc_s_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_vbi_cap) - ret = vfd->vidioc_s_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_s_fmt_vbi_cap) + ret = ops->vidioc_s_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_vbi_out) - ret = vfd->vidioc_s_fmt_vbi_out(file, fh, f); + if (ops->vidioc_s_fmt_vbi_out) + ret = ops->vidioc_s_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_s_fmt_sliced_vbi_cap) - ret = vfd->vidioc_s_fmt_sliced_vbi_cap(file, + if (ops->vidioc_s_fmt_sliced_vbi_cap) + ret = ops->vidioc_s_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_s_fmt_sliced_vbi_out) - ret = vfd->vidioc_s_fmt_sliced_vbi_out(file, + if (ops->vidioc_s_fmt_sliced_vbi_out) + ret = ops->vidioc_s_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_s_fmt_type_private) - ret = vfd->vidioc_s_fmt_type_private(file, + if (ops->vidioc_s_fmt_type_private) + ret = ops->vidioc_s_fmt_type_private(file, fh, f); break; } @@ -893,48 +903,48 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (vfd->vidioc_try_fmt_vid_cap) - ret = vfd->vidioc_try_fmt_vid_cap(file, fh, f); + if (ops->vidioc_try_fmt_vid_cap) + ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: - if (vfd->vidioc_try_fmt_vid_overlay) - ret = vfd->vidioc_try_fmt_vid_overlay(file, + if (ops->vidioc_try_fmt_vid_overlay) + ret = ops->vidioc_try_fmt_vid_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (vfd->vidioc_try_fmt_vid_out) - ret = vfd->vidioc_try_fmt_vid_out(file, fh, f); + if (ops->vidioc_try_fmt_vid_out) + ret = ops->vidioc_try_fmt_vid_out(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd, &f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: - if (vfd->vidioc_try_fmt_vid_out_overlay) - ret = vfd->vidioc_try_fmt_vid_out_overlay(file, + if (ops->vidioc_try_fmt_vid_out_overlay) + ret = ops->vidioc_try_fmt_vid_out_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_vbi_cap) - ret = vfd->vidioc_try_fmt_vbi_cap(file, fh, f); + if (ops->vidioc_try_fmt_vbi_cap) + ret = ops->vidioc_try_fmt_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_vbi_out) - ret = vfd->vidioc_try_fmt_vbi_out(file, fh, f); + if (ops->vidioc_try_fmt_vbi_out) + ret = ops->vidioc_try_fmt_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - if (vfd->vidioc_try_fmt_sliced_vbi_cap) - ret = vfd->vidioc_try_fmt_sliced_vbi_cap(file, + if (ops->vidioc_try_fmt_sliced_vbi_cap) + ret = ops->vidioc_try_fmt_sliced_vbi_cap(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: - if (vfd->vidioc_try_fmt_sliced_vbi_out) - ret = vfd->vidioc_try_fmt_sliced_vbi_out(file, + if (ops->vidioc_try_fmt_sliced_vbi_out) + ret = ops->vidioc_try_fmt_sliced_vbi_out(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: - if (vfd->vidioc_try_fmt_type_private) - ret = vfd->vidioc_try_fmt_type_private(file, + if (ops->vidioc_try_fmt_type_private) + ret = ops->vidioc_try_fmt_type_private(file, fh, f); break; } @@ -949,13 +959,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_requestbuffers *p = arg; - if (!vfd->vidioc_reqbufs) + if (!ops->vidioc_reqbufs) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_reqbufs(file, fh, p); + ret = ops->vidioc_reqbufs(file, fh, p); dbgarg(cmd, "count=%d, type=%s, memory=%s\n", p->count, prt_names(p->type, v4l2_type_names), @@ -966,13 +976,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_querybuf) + if (!ops->vidioc_querybuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_querybuf(file, fh, p); + ret = ops->vidioc_querybuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -981,13 +991,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_qbuf) + if (!ops->vidioc_qbuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_qbuf(file, fh, p); + ret = ops->vidioc_qbuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -996,13 +1006,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_buffer *p = arg; - if (!vfd->vidioc_dqbuf) + if (!ops->vidioc_dqbuf) break; - ret = check_fmt(vfd, p->type); + ret = check_fmt(ops, p->type); if (ret) break; - ret = vfd->vidioc_dqbuf(file, fh, p); + ret = ops->vidioc_dqbuf(file, fh, p); if (!ret) dbgbuf(cmd, vfd, p); break; @@ -1011,19 +1021,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { int *i = arg; - if (!vfd->vidioc_overlay) + if (!ops->vidioc_overlay) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_overlay(file, fh, *i); + ret = ops->vidioc_overlay(file, fh, *i); break; } case VIDIOC_G_FBUF: { struct v4l2_framebuffer *p = arg; - if (!vfd->vidioc_g_fbuf) + if (!ops->vidioc_g_fbuf) break; - ret = vfd->vidioc_g_fbuf(file, fh, arg); + ret = ops->vidioc_g_fbuf(file, fh, arg); if (!ret) { dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", p->capability, p->flags, @@ -1036,32 +1046,32 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_framebuffer *p = arg; - if (!vfd->vidioc_s_fbuf) + if (!ops->vidioc_s_fbuf) break; dbgarg(cmd, "capability=0x%x, flags=%d, base=0x%08lx\n", p->capability, p->flags, (unsigned long)p->base); v4l_print_pix_fmt(vfd, &p->fmt); - ret = vfd->vidioc_s_fbuf(file, fh, arg); + ret = ops->vidioc_s_fbuf(file, fh, arg); break; } case VIDIOC_STREAMON: { enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamon) + if (!ops->vidioc_streamon) break; dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret = vfd->vidioc_streamon(file, fh, i); + ret = ops->vidioc_streamon(file, fh, i); break; } case VIDIOC_STREAMOFF: { enum v4l2_buf_type i = *(int *)arg; - if (!vfd->vidioc_streamoff) + if (!ops->vidioc_streamoff) break; dbgarg(cmd, "type=%s\n", prt_names(i, v4l2_type_names)); - ret = vfd->vidioc_streamoff(file, fh, i); + ret = ops->vidioc_streamoff(file, fh, i); break; } /* ---------- tv norms ---------- */ @@ -1110,8 +1120,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret = 0; /* Calls the specific handler */ - if (vfd->vidioc_g_std) - ret = vfd->vidioc_g_std(file, fh, id); + if (ops->vidioc_g_std) + ret = ops->vidioc_g_std(file, fh, id); else *id = vfd->current_norm; @@ -1130,8 +1140,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, break; /* Calls the specific handler */ - if (vfd->vidioc_s_std) - ret = vfd->vidioc_s_std(file, fh, &norm); + if (ops->vidioc_s_std) + ret = ops->vidioc_s_std(file, fh, &norm); else ret = -EINVAL; @@ -1144,9 +1154,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { v4l2_std_id *p = arg; - if (!vfd->vidioc_querystd) + if (!ops->vidioc_querystd) break; - ret = vfd->vidioc_querystd(file, fh, arg); + ret = ops->vidioc_querystd(file, fh, arg); if (!ret) dbgarg(cmd, "detected std=%08Lx\n", (unsigned long long)*p); @@ -1159,12 +1169,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_input *p = arg; int i = p->index; - if (!vfd->vidioc_enum_input) + if (!ops->vidioc_enum_input) break; memset(p, 0, sizeof(*p)); p->index = i; - ret = vfd->vidioc_enum_input(file, fh, p); + ret = ops->vidioc_enum_input(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "audioset=%d, " @@ -1179,9 +1189,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_g_input) + if (!ops->vidioc_g_input) break; - ret = vfd->vidioc_g_input(file, fh, i); + ret = ops->vidioc_g_input(file, fh, i); if (!ret) dbgarg(cmd, "value=%d\n", *i); break; @@ -1190,10 +1200,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_s_input) + if (!ops->vidioc_s_input) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_s_input(file, fh, *i); + ret = ops->vidioc_s_input(file, fh, *i); break; } @@ -1203,12 +1213,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_output *p = arg; int i = p->index; - if (!vfd->vidioc_enum_output) + if (!ops->vidioc_enum_output) break; memset(p, 0, sizeof(*p)); p->index = i; - ret = vfd->vidioc_enum_output(file, fh, p); + ret = ops->vidioc_enum_output(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "audioset=0x%x, " @@ -1221,9 +1231,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_g_output) + if (!ops->vidioc_g_output) break; - ret = vfd->vidioc_g_output(file, fh, i); + ret = ops->vidioc_g_output(file, fh, i); if (!ret) dbgarg(cmd, "value=%d\n", *i); break; @@ -1232,10 +1242,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { unsigned int *i = arg; - if (!vfd->vidioc_s_output) + if (!ops->vidioc_s_output) break; dbgarg(cmd, "value=%d\n", *i); - ret = vfd->vidioc_s_output(file, fh, *i); + ret = ops->vidioc_s_output(file, fh, *i); break; } @@ -1244,9 +1254,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_queryctrl *p = arg; - if (!vfd->vidioc_queryctrl) + if (!ops->vidioc_queryctrl) break; - ret = vfd->vidioc_queryctrl(file, fh, p); + ret = ops->vidioc_queryctrl(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, type=%d, name=%s, min/max=%d/%d, " "step=%d, default=%d, flags=0x%08x\n", @@ -1261,9 +1271,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_control *p = arg; - if (vfd->vidioc_g_ctrl) - ret = vfd->vidioc_g_ctrl(file, fh, p); - else if (vfd->vidioc_g_ext_ctrls) { + if (ops->vidioc_g_ctrl) + ret = ops->vidioc_g_ctrl(file, fh, p); + else if (ops->vidioc_g_ext_ctrls) { struct v4l2_ext_controls ctrls; struct v4l2_ext_control ctrl; @@ -1273,7 +1283,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrl.id = p->id; ctrl.value = p->value; if (check_ext_ctrls(&ctrls, 1)) { - ret = vfd->vidioc_g_ext_ctrls(file, fh, &ctrls); + ret = ops->vidioc_g_ext_ctrls(file, fh, &ctrls); if (ret == 0) p->value = ctrl.value; } @@ -1291,16 +1301,16 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls ctrls; struct v4l2_ext_control ctrl; - if (!vfd->vidioc_s_ctrl && !vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ctrl && !ops->vidioc_s_ext_ctrls) break; dbgarg(cmd, "id=0x%x, value=%d\n", p->id, p->value); - if (vfd->vidioc_s_ctrl) { - ret = vfd->vidioc_s_ctrl(file, fh, p); + if (ops->vidioc_s_ctrl) { + ret = ops->vidioc_s_ctrl(file, fh, p); break; } - if (!vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ext_ctrls) break; ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(p->id); @@ -1309,7 +1319,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ctrl.id = p->id; ctrl.value = p->value; if (check_ext_ctrls(&ctrls, 1)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, &ctrls); + ret = ops->vidioc_s_ext_ctrls(file, fh, &ctrls); break; } case VIDIOC_G_EXT_CTRLS: @@ -1317,10 +1327,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_g_ext_ctrls) + if (!ops->vidioc_g_ext_ctrls) break; if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_g_ext_ctrls(file, fh, p); + ret = ops->vidioc_g_ext_ctrls(file, fh, p); v4l_print_ext_ctrls(cmd, vfd, p, !ret); break; } @@ -1329,11 +1339,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_s_ext_ctrls) + if (!ops->vidioc_s_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_s_ext_ctrls(file, fh, p); + ret = ops->vidioc_s_ext_ctrls(file, fh, p); break; } case VIDIOC_TRY_EXT_CTRLS: @@ -1341,20 +1351,20 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_ext_controls *p = arg; p->error_idx = p->count; - if (!vfd->vidioc_try_ext_ctrls) + if (!ops->vidioc_try_ext_ctrls) break; v4l_print_ext_ctrls(cmd, vfd, p, 1); if (check_ext_ctrls(p, 0)) - ret = vfd->vidioc_try_ext_ctrls(file, fh, p); + ret = ops->vidioc_try_ext_ctrls(file, fh, p); break; } case VIDIOC_QUERYMENU: { struct v4l2_querymenu *p = arg; - if (!vfd->vidioc_querymenu) + if (!ops->vidioc_querymenu) break; - ret = vfd->vidioc_querymenu(file, fh, p); + ret = ops->vidioc_querymenu(file, fh, p); if (!ret) dbgarg(cmd, "id=0x%x, index=%d, name=%s\n", p->id, p->index, p->name); @@ -1368,9 +1378,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audio *p = arg; - if (!vfd->vidioc_enumaudio) + if (!ops->vidioc_enumaudio) break; - ret = vfd->vidioc_enumaudio(file, fh, p); + ret = ops->vidioc_enumaudio(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, p->name, @@ -1384,12 +1394,12 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_audio *p = arg; __u32 index = p->index; - if (!vfd->vidioc_g_audio) + if (!ops->vidioc_g_audio) break; memset(p, 0, sizeof(*p)); p->index = index; - ret = vfd->vidioc_g_audio(file, fh, p); + ret = ops->vidioc_g_audio(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, @@ -1402,22 +1412,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audio *p = arg; - if (!vfd->vidioc_s_audio) + if (!ops->vidioc_s_audio) break; dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " "mode=0x%x\n", p->index, p->name, p->capability, p->mode); - ret = vfd->vidioc_s_audio(file, fh, p); + ret = ops->vidioc_s_audio(file, fh, p); break; } case VIDIOC_ENUMAUDOUT: { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_enumaudout) + if (!ops->vidioc_enumaudout) break; dbgarg(cmd, "Enum for index=%d\n", p->index); - ret = vfd->vidioc_enumaudout(file, fh, p); + ret = ops->vidioc_enumaudout(file, fh, p); if (!ret) dbgarg2("index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, @@ -1428,10 +1438,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_g_audout) + if (!ops->vidioc_g_audout) break; dbgarg(cmd, "Enum for index=%d\n", p->index); - ret = vfd->vidioc_g_audout(file, fh, p); + ret = ops->vidioc_g_audout(file, fh, p); if (!ret) dbgarg2("index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, @@ -1442,22 +1452,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_audioout *p = arg; - if (!vfd->vidioc_s_audout) + if (!ops->vidioc_s_audout) break; dbgarg(cmd, "index=%d, name=%s, capability=%d, " "mode=%d\n", p->index, p->name, p->capability, p->mode); - ret = vfd->vidioc_s_audout(file, fh, p); + ret = ops->vidioc_s_audout(file, fh, p); break; } case VIDIOC_G_MODULATOR: { struct v4l2_modulator *p = arg; - if (!vfd->vidioc_g_modulator) + if (!ops->vidioc_g_modulator) break; - ret = vfd->vidioc_g_modulator(file, fh, p); + ret = ops->vidioc_g_modulator(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, " "capability=%d, rangelow=%d," @@ -1471,23 +1481,23 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_modulator *p = arg; - if (!vfd->vidioc_s_modulator) + if (!ops->vidioc_s_modulator) break; dbgarg(cmd, "index=%d, name=%s, capability=%d, " "rangelow=%d, rangehigh=%d, txsubchans=%d\n", p->index, p->name, p->capability, p->rangelow, p->rangehigh, p->txsubchans); - ret = vfd->vidioc_s_modulator(file, fh, p); + ret = ops->vidioc_s_modulator(file, fh, p); break; } case VIDIOC_G_CROP: { struct v4l2_crop *p = arg; - if (!vfd->vidioc_g_crop) + if (!ops->vidioc_g_crop) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_g_crop(file, fh, p); + ret = ops->vidioc_g_crop(file, fh, p); if (!ret) dbgrect(vfd, "", &p->c); break; @@ -1496,11 +1506,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_crop *p = arg; - if (!vfd->vidioc_s_crop) + if (!ops->vidioc_s_crop) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); dbgrect(vfd, "", &p->c); - ret = vfd->vidioc_s_crop(file, fh, p); + ret = ops->vidioc_s_crop(file, fh, p); break; } case VIDIOC_CROPCAP: @@ -1508,10 +1518,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_cropcap *p = arg; /*FIXME: Should also show v4l2_fract pixelaspect */ - if (!vfd->vidioc_cropcap) + if (!ops->vidioc_cropcap) break; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_cropcap(file, fh, p); + ret = ops->vidioc_cropcap(file, fh, p); if (!ret) { dbgrect(vfd, "bounds ", &p->bounds); dbgrect(vfd, "defrect ", &p->defrect); @@ -1522,9 +1532,9 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_jpegcompression *p = arg; - if (!vfd->vidioc_g_jpegcomp) + if (!ops->vidioc_g_jpegcomp) break; - ret = vfd->vidioc_g_jpegcomp(file, fh, p); + ret = ops->vidioc_g_jpegcomp(file, fh, p); if (!ret) dbgarg(cmd, "quality=%d, APPn=%d, " "APP_len=%d, COM_len=%d, " @@ -1537,22 +1547,22 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_jpegcompression *p = arg; - if (!vfd->vidioc_g_jpegcomp) + if (!ops->vidioc_g_jpegcomp) break; dbgarg(cmd, "quality=%d, APPn=%d, APP_len=%d, " "COM_len=%d, jpeg_markers=%d\n", p->quality, p->APPn, p->APP_len, p->COM_len, p->jpeg_markers); - ret = vfd->vidioc_s_jpegcomp(file, fh, p); + ret = ops->vidioc_s_jpegcomp(file, fh, p); break; } case VIDIOC_G_ENC_INDEX: { struct v4l2_enc_idx *p = arg; - if (!vfd->vidioc_g_enc_index) + if (!ops->vidioc_g_enc_index) break; - ret = vfd->vidioc_g_enc_index(file, fh, p); + ret = ops->vidioc_g_enc_index(file, fh, p); if (!ret) dbgarg(cmd, "entries=%d, entries_cap=%d\n", p->entries, p->entries_cap); @@ -1562,10 +1572,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_encoder_cmd *p = arg; - if (!vfd->vidioc_encoder_cmd) + if (!ops->vidioc_encoder_cmd) break; memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_encoder_cmd(file, fh, p); + ret = ops->vidioc_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; @@ -1574,10 +1584,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_encoder_cmd *p = arg; - if (!vfd->vidioc_try_encoder_cmd) + if (!ops->vidioc_try_encoder_cmd) break; memset(&p->raw, 0, sizeof(p->raw)); - ret = vfd->vidioc_try_encoder_cmd(file, fh, p); + ret = ops->vidioc_try_encoder_cmd(file, fh, p); if (!ret) dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); break; @@ -1590,8 +1600,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, memset(p, 0, sizeof(*p)); p->type = type; - if (vfd->vidioc_g_parm) { - ret = vfd->vidioc_g_parm(file, fh, p); + if (ops->vidioc_g_parm) { + ret = ops->vidioc_g_parm(file, fh, p); } else { struct v4l2_standard s; @@ -1612,10 +1622,10 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_streamparm *p = arg; - if (!vfd->vidioc_s_parm) + if (!ops->vidioc_s_parm) break; dbgarg(cmd, "type=%d\n", p->type); - ret = vfd->vidioc_s_parm(file, fh, p); + ret = ops->vidioc_s_parm(file, fh, p); break; } case VIDIOC_G_TUNER: @@ -1623,13 +1633,13 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_tuner *p = arg; __u32 index = p->index; - if (!vfd->vidioc_g_tuner) + if (!ops->vidioc_g_tuner) break; memset(p, 0, sizeof(*p)); p->index = index; - ret = vfd->vidioc_g_tuner(file, fh, p); + ret = ops->vidioc_g_tuner(file, fh, p); if (!ret) dbgarg(cmd, "index=%d, name=%s, type=%d, " "capability=0x%x, rangelow=%d, " @@ -1645,7 +1655,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_tuner *p = arg; - if (!vfd->vidioc_s_tuner) + if (!ops->vidioc_s_tuner) break; dbgarg(cmd, "index=%d, name=%s, type=%d, " "capability=0x%x, rangelow=%d, " @@ -1655,19 +1665,19 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, p->capability, p->rangelow, p->rangehigh, p->signal, p->afc, p->rxsubchans, p->audmode); - ret = vfd->vidioc_s_tuner(file, fh, p); + ret = ops->vidioc_s_tuner(file, fh, p); break; } case VIDIOC_G_FREQUENCY: { struct v4l2_frequency *p = arg; - if (!vfd->vidioc_g_frequency) + if (!ops->vidioc_g_frequency) break; memset(p->reserved, 0, sizeof(p->reserved)); - ret = vfd->vidioc_g_frequency(file, fh, p); + ret = ops->vidioc_g_frequency(file, fh, p); if (!ret) dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", p->tuner, p->type, p->frequency); @@ -1677,11 +1687,11 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_frequency *p = arg; - if (!vfd->vidioc_s_frequency) + if (!ops->vidioc_s_frequency) break; dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", p->tuner, p->type, p->frequency); - ret = vfd->vidioc_s_frequency(file, fh, p); + ret = ops->vidioc_s_frequency(file, fh, p); break; } case VIDIOC_G_SLICED_VBI_CAP: @@ -1689,21 +1699,21 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_sliced_vbi_cap *p = arg; __u32 type = p->type; - if (!vfd->vidioc_g_sliced_vbi_cap) + if (!ops->vidioc_g_sliced_vbi_cap) break; memset(p, 0, sizeof(*p)); p->type = type; dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); - ret = vfd->vidioc_g_sliced_vbi_cap(file, fh, p); + ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); if (!ret) dbgarg2("service_set=%d\n", p->service_set); break; } case VIDIOC_LOG_STATUS: { - if (!vfd->vidioc_log_status) + if (!ops->vidioc_log_status) break; - ret = vfd->vidioc_log_status(file, fh); + ret = ops->vidioc_log_status(file, fh); break; } #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -1713,8 +1723,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; - else if (vfd->vidioc_g_register) - ret = vfd->vidioc_g_register(file, fh, p); + else if (ops->vidioc_g_register) + ret = ops->vidioc_g_register(file, fh, p); break; } case VIDIOC_DBG_S_REGISTER: @@ -1723,8 +1733,8 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) ret = -EPERM; - else if (vfd->vidioc_s_register) - ret = vfd->vidioc_s_register(file, fh, p); + else if (ops->vidioc_s_register) + ret = ops->vidioc_s_register(file, fh, p); break; } #endif @@ -1732,30 +1742,30 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, { struct v4l2_chip_ident *p = arg; - if (!vfd->vidioc_g_chip_ident) + if (!ops->vidioc_g_chip_ident) break; - ret = vfd->vidioc_g_chip_ident(file, fh, p); + ret = ops->vidioc_g_chip_ident(file, fh, p); if (!ret) dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); break; } - default: - { - if (!vfd->vidioc_default) - break; - ret = vfd->vidioc_default(file, fh, cmd, arg); - break; - } case VIDIOC_S_HW_FREQ_SEEK: { struct v4l2_hw_freq_seek *p = arg; - if (!vfd->vidioc_s_hw_freq_seek) + if (!ops->vidioc_s_hw_freq_seek) break; dbgarg(cmd, "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", p->tuner, p->type, p->seek_upward, p->wrap_around); - ret = vfd->vidioc_s_hw_freq_seek(file, fh, p); + ret = ops->vidioc_s_hw_freq_seek(file, fh, p); + break; + } + default: + { + if (!ops->vidioc_default) + break; + ret = ops->vidioc_default(file, fh, cmd, arg); break; } } /* switch */ diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index e4b3a006c71e..639210e52647 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1066,13 +1066,7 @@ static const struct file_operations vivi_fops = { .llseek = no_llseek, }; -static struct video_device vivi_template = { - .name = "vivi", - .type = VID_TYPE_CAPTURE, - .fops = &vivi_fops, - .minor = -1, - .release = video_device_release, - +static const struct v4l2_ioctl_ops vivi_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, @@ -1094,6 +1088,16 @@ static struct video_device vivi_template = { #ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif +}; + +static struct video_device vivi_template = { + .name = "vivi", + .type = VID_TYPE_CAPTURE, + .fops = &vivi_fops, + .ioctl_ops = &vivi_ioctl_ops, + .minor = -1, + .release = video_device_release, + .tvnorms = V4L2_STD_525_60, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index ea5265c22983..617ed2856b22 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -762,14 +762,7 @@ static const struct file_operations zr364xx_fops = { .llseek = no_llseek, }; -static struct video_device zr364xx_template = { - .owner = THIS_MODULE, - .name = DRIVER_DESC, - .type = VID_TYPE_CAPTURE, - .fops = &zr364xx_fops, - .release = video_device_release, - .minor = -1, - +static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { .vidioc_querycap = zr364xx_vidioc_querycap, .vidioc_enum_fmt_vid_cap = zr364xx_vidioc_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = zr364xx_vidioc_try_fmt_vid_cap, @@ -785,6 +778,16 @@ static struct video_device zr364xx_template = { .vidioc_s_ctrl = zr364xx_vidioc_s_ctrl, }; +static struct video_device zr364xx_template = { + .owner = THIS_MODULE, + .name = DRIVER_DESC, + .type = VID_TYPE_CAPTURE, + .fops = &zr364xx_fops, + .ioctl_ops = &zr364xx_ioctl_ops, + .release = video_device_release, + .minor = -1, +}; + /*******************/ diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index ad62d322e178..d9149cd25b31 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -39,6 +39,8 @@ #define VFL_TYPE_RADIO 2 #define VFL_TYPE_VTX 3 +struct v4l2_ioctl_callbacks; + /* * Newer version of video_device, handled by videodev2.c * This version moves redundant code from video device code to @@ -72,225 +74,7 @@ struct video_device void (*release)(struct video_device *vfd); /* ioctl callbacks */ - - /* VIDIOC_QUERYCAP handler */ - int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap); - - /* Priority handling */ - int (*vidioc_g_priority) (struct file *file, void *fh, - enum v4l2_priority *p); - int (*vidioc_s_priority) (struct file *file, void *fh, - enum v4l2_priority p); - - /* VIDIOC_ENUM_FMT handlers */ - int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); -#if 1 - /* deprecated, will be removed in 2.6.28 */ - int (*vidioc_enum_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); -#endif - int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, - struct v4l2_fmtdesc *f); - - /* VIDIOC_G_FMT handlers */ - int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, - struct v4l2_format *f); - - /* VIDIOC_S_FMT handlers */ - int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, - struct v4l2_format *f); - - /* VIDIOC_TRY_FMT handlers */ - int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, - struct v4l2_format *f); - - /* Buffer handlers */ - int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b); - int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - - - int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i); -#ifdef CONFIG_VIDEO_V4L1_COMPAT - /* buffer type is struct vidio_mbuf * */ - int (*vidiocgmbuf) (struct file *file, void *fh, struct video_mbuf *p); -#endif - int (*vidioc_g_fbuf) (struct file *file, void *fh, - struct v4l2_framebuffer *a); - int (*vidioc_s_fbuf) (struct file *file, void *fh, - struct v4l2_framebuffer *a); - - /* Stream on/off */ - int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i); - int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i); - - /* Standard handling - ENUMSTD is handled by videodev.c - */ - int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm); - int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm); - int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); - - /* Input handling */ - int (*vidioc_enum_input)(struct file *file, void *fh, - struct v4l2_input *inp); - int (*vidioc_g_input) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_input) (struct file *file, void *fh, unsigned int i); - - /* Output handling */ - int (*vidioc_enum_output) (struct file *file, void *fh, - struct v4l2_output *a); - int (*vidioc_g_output) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_output) (struct file *file, void *fh, unsigned int i); - - /* Control handling */ - int (*vidioc_queryctrl) (struct file *file, void *fh, - struct v4l2_queryctrl *a); - int (*vidioc_g_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_s_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_g_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_s_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_try_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_querymenu) (struct file *file, void *fh, - struct v4l2_querymenu *a); - - /* Audio ioctls */ - int (*vidioc_enumaudio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_g_audio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_s_audio) (struct file *file, void *fh, - struct v4l2_audio *a); - - /* Audio out ioctls */ - int (*vidioc_enumaudout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_g_audout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_s_audout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_g_modulator) (struct file *file, void *fh, - struct v4l2_modulator *a); - int (*vidioc_s_modulator) (struct file *file, void *fh, - struct v4l2_modulator *a); - /* Crop ioctls */ - int (*vidioc_cropcap) (struct file *file, void *fh, - struct v4l2_cropcap *a); - int (*vidioc_g_crop) (struct file *file, void *fh, - struct v4l2_crop *a); - int (*vidioc_s_crop) (struct file *file, void *fh, - struct v4l2_crop *a); - /* Compression ioctls */ - int (*vidioc_g_jpegcomp) (struct file *file, void *fh, - struct v4l2_jpegcompression *a); - int (*vidioc_s_jpegcomp) (struct file *file, void *fh, - struct v4l2_jpegcompression *a); - int (*vidioc_g_enc_index) (struct file *file, void *fh, - struct v4l2_enc_idx *a); - int (*vidioc_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - int (*vidioc_try_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - - /* Stream type-dependent parameter ioctls */ - int (*vidioc_g_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); - int (*vidioc_s_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); - - /* Tuner ioctls */ - int (*vidioc_g_tuner) (struct file *file, void *fh, - struct v4l2_tuner *a); - int (*vidioc_s_tuner) (struct file *file, void *fh, - struct v4l2_tuner *a); - int (*vidioc_g_frequency) (struct file *file, void *fh, - struct v4l2_frequency *a); - int (*vidioc_s_frequency) (struct file *file, void *fh, - struct v4l2_frequency *a); - - /* Sliced VBI cap */ - int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh, - struct v4l2_sliced_vbi_cap *a); - - /* Log status ioctl */ - int (*vidioc_log_status) (struct file *file, void *fh); - - int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh, - struct v4l2_hw_freq_seek *a); - - /* Debugging ioctls */ -#ifdef CONFIG_VIDEO_ADV_DEBUG - int (*vidioc_g_register) (struct file *file, void *fh, - struct v4l2_register *reg); - int (*vidioc_s_register) (struct file *file, void *fh, - struct v4l2_register *reg); -#endif - int (*vidioc_g_chip_ident) (struct file *file, void *fh, - struct v4l2_chip_ident *chip); - - /* For other private ioctls */ - int (*vidioc_default) (struct file *file, void *fh, - int cmd, void *arg); - + const struct v4l2_ioctl_ops *ioctl_ops; #ifdef OBSOLETE_OWNER /* to be removed soon */ /* obsolete -- fops->owner is used instead */ diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index e319d1fffb82..dc6404618555 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -20,6 +20,229 @@ #include #endif +struct v4l2_ioctl_ops { + /* ioctl callbacks */ + + /* VIDIOC_QUERYCAP handler */ + int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap); + + /* Priority handling */ + int (*vidioc_g_priority) (struct file *file, void *fh, + enum v4l2_priority *p); + int (*vidioc_s_priority) (struct file *file, void *fh, + enum v4l2_priority p); + + /* VIDIOC_ENUM_FMT handlers */ + int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, + struct v4l2_fmtdesc *f); +#if 1 + /* deprecated, will be removed in 2.6.28 */ + int (*vidioc_enum_fmt_vbi_cap) (struct file *file, void *fh, + struct v4l2_fmtdesc *f); +#endif + int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + + /* VIDIOC_G_FMT handlers */ + int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, + struct v4l2_format *f); + + /* VIDIOC_S_FMT handlers */ + int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, + struct v4l2_format *f); + + /* VIDIOC_TRY_FMT handlers */ + int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_cap) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_out) (struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, + struct v4l2_format *f); + + /* Buffer handlers */ + int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b); + int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b); + int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b); + int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b); + + + int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i); +#ifdef CONFIG_VIDEO_V4L1_COMPAT + /* buffer type is struct vidio_mbuf * */ + int (*vidiocgmbuf) (struct file *file, void *fh, struct video_mbuf *p); +#endif + int (*vidioc_g_fbuf) (struct file *file, void *fh, + struct v4l2_framebuffer *a); + int (*vidioc_s_fbuf) (struct file *file, void *fh, + struct v4l2_framebuffer *a); + + /* Stream on/off */ + int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i); + int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i); + + /* Standard handling + ENUMSTD is handled by videodev.c + */ + int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm); + int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id *norm); + int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); + + /* Input handling */ + int (*vidioc_enum_input)(struct file *file, void *fh, + struct v4l2_input *inp); + int (*vidioc_g_input) (struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_input) (struct file *file, void *fh, unsigned int i); + + /* Output handling */ + int (*vidioc_enum_output) (struct file *file, void *fh, + struct v4l2_output *a); + int (*vidioc_g_output) (struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_output) (struct file *file, void *fh, unsigned int i); + + /* Control handling */ + int (*vidioc_queryctrl) (struct file *file, void *fh, + struct v4l2_queryctrl *a); + int (*vidioc_g_ctrl) (struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_s_ctrl) (struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_g_ext_ctrls) (struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_s_ext_ctrls) (struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_try_ext_ctrls) (struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_querymenu) (struct file *file, void *fh, + struct v4l2_querymenu *a); + + /* Audio ioctls */ + int (*vidioc_enumaudio) (struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_g_audio) (struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_s_audio) (struct file *file, void *fh, + struct v4l2_audio *a); + + /* Audio out ioctls */ + int (*vidioc_enumaudout) (struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_g_audout) (struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_s_audout) (struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_g_modulator) (struct file *file, void *fh, + struct v4l2_modulator *a); + int (*vidioc_s_modulator) (struct file *file, void *fh, + struct v4l2_modulator *a); + /* Crop ioctls */ + int (*vidioc_cropcap) (struct file *file, void *fh, + struct v4l2_cropcap *a); + int (*vidioc_g_crop) (struct file *file, void *fh, + struct v4l2_crop *a); + int (*vidioc_s_crop) (struct file *file, void *fh, + struct v4l2_crop *a); + /* Compression ioctls */ + int (*vidioc_g_jpegcomp) (struct file *file, void *fh, + struct v4l2_jpegcompression *a); + int (*vidioc_s_jpegcomp) (struct file *file, void *fh, + struct v4l2_jpegcompression *a); + int (*vidioc_g_enc_index) (struct file *file, void *fh, + struct v4l2_enc_idx *a); + int (*vidioc_encoder_cmd) (struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_try_encoder_cmd) (struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + + /* Stream type-dependent parameter ioctls */ + int (*vidioc_g_parm) (struct file *file, void *fh, + struct v4l2_streamparm *a); + int (*vidioc_s_parm) (struct file *file, void *fh, + struct v4l2_streamparm *a); + + /* Tuner ioctls */ + int (*vidioc_g_tuner) (struct file *file, void *fh, + struct v4l2_tuner *a); + int (*vidioc_s_tuner) (struct file *file, void *fh, + struct v4l2_tuner *a); + int (*vidioc_g_frequency) (struct file *file, void *fh, + struct v4l2_frequency *a); + int (*vidioc_s_frequency) (struct file *file, void *fh, + struct v4l2_frequency *a); + + /* Sliced VBI cap */ + int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh, + struct v4l2_sliced_vbi_cap *a); + + /* Log status ioctl */ + int (*vidioc_log_status) (struct file *file, void *fh); + + int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh, + struct v4l2_hw_freq_seek *a); + + /* Debugging ioctls */ +#ifdef CONFIG_VIDEO_ADV_DEBUG + int (*vidioc_g_register) (struct file *file, void *fh, + struct v4l2_register *reg); + int (*vidioc_s_register) (struct file *file, void *fh, + struct v4l2_register *reg); +#endif + int (*vidioc_g_chip_ident) (struct file *file, void *fh, + struct v4l2_chip_ident *chip); + + /* For other private ioctls */ + int (*vidioc_default) (struct file *file, void *fh, + int cmd, void *arg); +}; + + /* v4l debugging and diagnostics */ /* Debug bitmask flags to be used on V4L2 */ -- cgit v1.2.3 From 9c39d7eafa366b807067697f7fc5b14d8b865179 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 21 Jul 2008 07:51:45 -0300 Subject: V4L/DVB (8483): Remove obsolete owner field from video_device struct. According to an old comment this should have been removed in 2.6.15. Better late than never... Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/dsbr100.c | 1 - drivers/media/radio/miropcm20-radio.c | 1 - drivers/media/radio/radio-aimslab.c | 1 - drivers/media/radio/radio-aztech.c | 1 - drivers/media/radio/radio-cadet.c | 1 - drivers/media/radio/radio-gemtek-pci.c | 1 - drivers/media/radio/radio-gemtek.c | 1 - drivers/media/radio/radio-maxiradio.c | 1 - drivers/media/radio/radio-rtrack2.c | 1 - drivers/media/radio/radio-sf16fmi.c | 1 - drivers/media/radio/radio-sf16fmr2.c | 1 - drivers/media/radio/radio-si470x.c | 1 - drivers/media/radio/radio-terratec.c | 1 - drivers/media/radio/radio-trust.c | 1 - drivers/media/radio/radio-typhoon.c | 1 - drivers/media/radio/radio-zoltrix.c | 1 - drivers/media/video/bw-qcam.c | 1 - drivers/media/video/c-qcam.c | 1 - drivers/media/video/cpia.c | 1 - drivers/media/video/cpia2/cpia2_v4l.c | 1 - drivers/media/video/et61x251/et61x251_core.c | 1 - drivers/media/video/meye.c | 1 - drivers/media/video/ov511.c | 1 - drivers/media/video/pms.c | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 - drivers/media/video/pwc/pwc-if.c | 2 -- drivers/media/video/saa5246a.c | 1 - drivers/media/video/saa5249.c | 1 - drivers/media/video/se401.c | 1 - drivers/media/video/sn9c102/sn9c102_core.c | 1 - drivers/media/video/stv680.c | 1 - drivers/media/video/usbvideo/usbvideo.c | 1 - drivers/media/video/usbvideo/vicam.c | 1 - drivers/media/video/usbvision/usbvision-video.c | 3 --- drivers/media/video/w9966.c | 1 - drivers/media/video/w9968cf.c | 1 - drivers/media/video/zc0301/zc0301_core.c | 1 - drivers/media/video/zr364xx.c | 1 - include/media/v4l2-dev.h | 20 +++++++------------- 39 files changed, 7 insertions(+), 54 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 08bf5e8031da..0edada6f4b31 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -462,7 +462,6 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { /* V4L2 interface */ static struct video_device dsbr100_videodev_template = { - .owner = THIS_MODULE, .name = "D-Link DSB-R 100", .type = VID_TYPE_TUNER, .fops = &usb_dsbr100_fops, diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index 4a332fe8b64b..594e246dfcff 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c @@ -229,7 +229,6 @@ static const struct file_operations pcm20_fops = { }; static struct video_device pcm20_radio = { - .owner = THIS_MODULE, .name = "Miro PCM 20 radio", .type = VID_TYPE_TUNER, .fops = &pcm20_fops, diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index be9bd7adaf61..2540df6dc2c8 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -405,7 +405,6 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { }; static struct video_device rtrack_radio = { - .owner = THIS_MODULE, .name = "RadioTrack radio", .type = VID_TYPE_TUNER, .fops = &rtrack_fops, diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 04c738b62d06..537f2f479506 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -369,7 +369,6 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { }; static struct video_device aztech_radio = { - .owner = THIS_MODULE, .name = "Aztech radio", .type = VID_TYPE_TUNER, .fops = &aztech_fops, diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 36b850fc14b4..362a279f0680 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -586,7 +586,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = { }; static struct video_device cadet_radio = { - .owner = THIS_MODULE, .name = "Cadet radio", .type = VID_TYPE_TUNER, .fops = &cadet_fops, diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c41b35f3b125..b8c515762b49 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -391,7 +391,6 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { }; static struct video_device vdev_template = { - .owner = THIS_MODULE, .name = "Gemtek PCI Radio", .type = VID_TYPE_TUNER, .fops = &gemtek_pci_fops, diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index f82b59f35e33..45b47c1643ee 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -569,7 +569,6 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { }; static struct video_device gemtek_radio = { - .owner = THIS_MODULE, .name = "GemTek Radio card", .type = VID_TYPE_TUNER, .fops = &gemtek_fops, diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 780516daebba..1b9099606494 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -390,7 +390,6 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { }; static struct video_device maxiradio_radio = { - .owner = THIS_MODULE, .name = "Maxi Radio FM2000 radio", .type = VID_TYPE_TUNER, .fops = &maxiradio_fops, diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index 045ae9d1067c..e065cb16dc5a 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -311,7 +311,6 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { }; static struct video_device rtrack2_radio = { - .owner = THIS_MODULE, .name = "RadioTrack II radio", .type = VID_TYPE_TUNER, .fops = &rtrack2_fops, diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 75b68a024541..975f8521848a 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -311,7 +311,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = { }; static struct video_device fmi_radio = { - .owner = THIS_MODULE, .name = "SF16FMx radio", .type = VID_TYPE_TUNER, .fops = &fmi_fops, diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 5ffddce80011..2786722b4946 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -427,7 +427,6 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { }; static struct video_device fmr2_radio = { - .owner = THIS_MODULE, .name = "SF16FMR2 radio", .type = VID_TYPE_TUNER, .fops = &fmr2_fops, diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index b829c67ecf0c..3cf78ccdc58f 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -1611,7 +1611,6 @@ static struct video_device si470x_viddev_template = { .name = DRIVER_NAME, .type = VID_TYPE_TUNER, .release = video_device_release, - .owner = THIS_MODULE, }; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 3a67471f999c..b3f669d0691f 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -383,7 +383,6 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = { }; static struct video_device terratec_radio = { - .owner = THIS_MODULE, .name = "TerraTec ActiveRadio", .type = VID_TYPE_TUNER, .fops = &terratec_fops, diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index e33400180915..74aefda868e6 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -363,7 +363,6 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = { }; static struct video_device trust_radio = { - .owner = THIS_MODULE, .name = "Trust FM Radio", .type = VID_TYPE_TUNER, .fops = &trust_fops, diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 48b5d2bc6276..6eb39b7ab75e 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -361,7 +361,6 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { }; static struct video_device typhoon_radio = { - .owner = THIS_MODULE, .name = "Typhoon Radio", .type = VID_TYPE_TUNER, .fops = &typhoon_fops, diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index c60344326cd6..4afcb09a4af3 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -424,7 +424,6 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { }; static struct video_device zoltrix_radio = { - .owner = THIS_MODULE, .name = "Zoltrix Radio Plus", .type = VID_TYPE_TUNER, .fops = &zoltrix_fops, diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index e367862313e1..ec870c781c02 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -907,7 +907,6 @@ static const struct file_operations qcam_fops = { }; static struct video_device qcam_template= { - .owner = THIS_MODULE, .name = "Connectix Quickcam", .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 8d690410c84f..62ed8949d461 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -702,7 +702,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { - .owner = THIS_MODULE, .name = "Colour QuickCam", .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 2a81376ef503..5d2ef48137c4 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3799,7 +3799,6 @@ static const struct file_operations cpia_fops = { }; static struct video_device cpia_template = { - .owner = THIS_MODULE, .name = "CPiA Camera", .type = VID_TYPE_CAPTURE, .fops = &cpia_fops, diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 8817c3841463..4e45de78df59 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -1936,7 +1936,6 @@ static const struct file_operations fops_template = { static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ - .owner= THIS_MODULE, .name= "CPiA2 Camera", .type= VID_TYPE_CAPTURE, .type2 = V4L2_CAP_VIDEO_CAPTURE | diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 8cd5f37425ea..3e71ea7bbe24 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -2585,7 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &et61x251_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index fd16ef0a5868..f9a6e1e8b4bd 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1720,7 +1720,6 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { }; static struct video_device meye_template = { - .owner = THIS_MODULE, .name = "meye", .type = VID_TYPE_CAPTURE, .fops = &meye_fops, diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index b72e5660bc19..f732b035570f 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -4666,7 +4666,6 @@ static const struct file_operations ov511_fops = { }; static struct video_device vdev_template = { - .owner = THIS_MODULE, .name = "OV511 USB Camera", .type = VID_TYPE_CAPTURE, .fops = &ov511_fops, diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 260c1d3f9692..8c72e4df85ab 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -895,7 +895,6 @@ static const struct file_operations pms_fops = { static struct video_device pms_template= { - .owner = THIS_MODULE, .name = "Mediavision PMS", .type = VID_TYPE_CAPTURE, .fops = &pms_fops, diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index bd6169fbdcca..ceb549ac752d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1161,7 +1161,6 @@ static const struct file_operations vdev_fops = { static struct video_device vdev_template = { - .owner = THIS_MODULE, .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index b4de82115e5b..4625b265bf98 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -165,7 +165,6 @@ static const struct file_operations pwc_fops = { .llseek = no_llseek, }; static struct video_device pwc_template = { - .owner = THIS_MODULE, .name = "Philips Webcam", /* Filled in later */ .type = VID_TYPE_CAPTURE, .release = video_device_release, @@ -1769,7 +1768,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); pdev->vdev->parent = &(udev->dev); strcpy(pdev->vdev->name, name); - pdev->vdev->owner = THIS_MODULE; video_set_drvdata(pdev->vdev, pdev); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index 8d69632a6658..e6a3fa482982 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -830,7 +830,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .owner = THIS_MODULE, .name = IF_NAME, .type = VID_TYPE_TELETEXT, .fops = &saa_fops, diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 812cfe3fd3f3..6f14619bda4a 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -711,7 +711,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { - .owner = THIS_MODULE, .name = IF_NAME, .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ .fops = &saa_fops, diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index 1cd629380f71..b4dd60b0f8f2 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c @@ -1230,7 +1230,6 @@ static const struct file_operations se401_fops = { .llseek = no_llseek, }; static struct video_device se401_template = { - .owner = THIS_MODULE, .name = "se401 USB camera", .type = VID_TYPE_CAPTURE, .fops = &se401_fops, diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 475b78191151..c68bf0921e9e 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -3309,7 +3309,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index da94d3fd8fac..fdcb58b0c121 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1401,7 +1401,6 @@ static const struct file_operations stv680_fops = { .llseek = no_llseek, }; static struct video_device stv680_template = { - .owner = THIS_MODULE, .name = "STV0680 USB camera", .type = VID_TYPE_CAPTURE, .fops = &stv680_fops, diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 7e6ab2910c13..357cee40fb38 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c @@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = { .llseek = no_llseek, }; static const struct video_device usbvideo_template = { - .owner = THIS_MODULE, .type = VID_TYPE_CAPTURE, .fops = &usbvideo_fops, }; diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index 40d053e0d5bf..e2dec6fb0da9 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -791,7 +791,6 @@ static const struct file_operations vicam_fops = { }; static struct video_device vicam_template = { - .owner = THIS_MODULE, .name = "ViCam-based USB Camera", .type = VID_TYPE_CAPTURE, .fops = &vicam_fops, diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 7eccdc1ea2d7..e97f955aad67 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1406,7 +1406,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { }; static struct video_device usbvision_video_template = { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, .fops = &usbvision_fops, .ioctl_ops = &usbvision_ioctl_ops, @@ -1445,7 +1444,6 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { }; static struct video_device usbvision_radio_template = { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER, .fops = &usbvision_radio_fops, .name = "usbvision-radio", @@ -1469,7 +1467,6 @@ static const struct file_operations usbvision_vbi_fops = { static struct video_device usbvision_vbi_template= { - .owner = THIS_MODULE, .type = VID_TYPE_TUNER, .fops = &usbvision_vbi_fops, .release = video_device_release, diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index a63e11f8399b..1641998c73e6 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -196,7 +196,6 @@ static const struct file_operations w9966_fops = { .llseek = no_llseek, }; static struct video_device w9966_template = { - .owner = THIS_MODULE, .name = W9966_DRIVERNAME, .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, .fops = &w9966_fops, diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 56bbeec542c5..8f665953c80c 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -3550,7 +3550,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &w9968cf_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index e5c4e9f5193f..0978a7e946b4 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -1985,7 +1985,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); - cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &zc0301_fops; cam->v4ldev->minor = video_nr[dev_nr]; diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 617ed2856b22..36ba36a5e2ea 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -779,7 +779,6 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { }; static struct video_device zr364xx_template = { - .owner = THIS_MODULE, .name = DRIVER_DESC, .type = VID_TYPE_CAPTURE, .fops = &zr364xx_fops, diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index d9149cd25b31..ae2b1e6bdf47 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -9,7 +9,6 @@ #ifndef _V4L2_DEV_H #define _V4L2_DEV_H -#define OBSOLETE_OWNER 1 /* to be removed soon */ #define OBSOLETE_DEVDATA 1 /* to be removed soon */ #include @@ -76,14 +75,12 @@ struct video_device /* ioctl callbacks */ const struct v4l2_ioctl_ops *ioctl_ops; -#ifdef OBSOLETE_OWNER /* to be removed soon */ -/* obsolete -- fops->owner is used instead */ -struct module *owner; -/* dev->driver_data will be used instead some day. - * Use the video_{get|set}_drvdata() helper functions, - * so the switch over will be transparent for you. - * Or use {pci|usb}_{get|set}_drvdata() directly. */ -void *priv; +#ifdef OBSOLETE_DEVDATA /* to be removed soon */ + /* dev->driver_data will be used instead some day. + * Use the video_{get|set}_drvdata() helper functions, + * so the switch over will be transparent for you. + * Or use {pci|usb}_{get|set}_drvdata() directly. */ + void *priv; #endif /* for videodev.c intenal usage -- please don't touch */ @@ -126,7 +123,7 @@ video_device_remove_file(struct video_device *vfd, #endif /* CONFIG_VIDEO_V4L1_COMPAT */ -#ifdef OBSOLETE_OWNER /* to be removed soon */ +#ifdef OBSOLETE_DEVDATA /* to be removed soon */ /* helper functions to access driver private data. */ static inline void *video_get_drvdata(struct video_device *dev) { @@ -138,9 +135,6 @@ static inline void video_set_drvdata(struct video_device *dev, void *data) dev->priv = data; } -#endif - -#ifdef OBSOLETE_DEVDATA /* to be removed soon */ /* Obsolete stuff - Still needed for radio devices and obsolete drivers */ extern struct video_device* video_devdata(struct file*); extern int video_exclusive_open(struct inode *inode, struct file *file); -- cgit v1.2.3 From 322e4095c9261d4cf0326f10d8e398d05e66521c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 22 Jul 2008 16:25:35 -0300 Subject: V4L/DVB (8484): videodev: missed two more usages of the removed 'owner' field. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/arv.c | 1 - sound/i2c/other/tea575x-tuner.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 8c7d1958856b..56ebfd5ef6fa 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c @@ -754,7 +754,6 @@ static const struct file_operations ar_fops = { }; static struct video_device ar_template = { - .owner = THIS_MODULE, .name = "Colour AR VGA", .type = VID_TYPE_CAPTURE, .fops = &ar_fops, diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 87e3aefeddc3..187c9527725f 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -189,7 +189,6 @@ void snd_tea575x_init(struct snd_tea575x *tea) } memset(&tea->vd, 0, sizeof(tea->vd)); - tea->vd.owner = tea->card->module; strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio"); tea->vd.type = VID_TYPE_TUNER; tea->vd.release = snd_tea575x_release; -- cgit v1.2.3 From 58cfdf9acffb0c61feb0e2bceacd557a2e0b0328 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 25 Jul 2008 04:26:31 -0300 Subject: V4L/DVB (8485): v4l-dvb: remove broken PlanB driver The PlanB driver has been broken since around May 2004. No one stepped in to maintain it, so it is now being removed. Signed-off-by: Adrian Bunk Acked-by: Michel Lanners Acked-by: Benjamin Herrenschmidt Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/Kconfig | 11 - drivers/media/video/Makefile | 1 - drivers/media/video/planb.c | 2309 ----------------------------------------- drivers/media/video/planb.h | 232 ----- drivers/media/video/saa7196.h | 117 --- 5 files changed, 2670 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 2a747db6dc3e..d4a6e56a7135 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -487,17 +487,6 @@ config VIDEO_PMS To compile this driver as a module, choose M here: the module will be called pms. -config VIDEO_PLANB - tristate "PlanB Video-In on PowerMac" - depends on PPC_PMAC && VIDEO_V4L1 && BROKEN - help - PlanB is the V4L driver for the PowerMac 7x00/8x00 series video - input hardware. If you want to experiment with this, say Y. - Otherwise, or if you don't understand a word, say N. See - for more info. - - Saying M will compile this driver as a module (planb). - config VIDEO_BWQCAM tristate "Quickcam BW Video For Linux" depends on PARPORT && VIDEO_V4L1 diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 9de1e4885246..bbc6f8b82297 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -57,7 +57,6 @@ obj-$(CONFIG_VIDEO_ZORAN_DC30) += zr36050.o zr36016.o obj-$(CONFIG_VIDEO_ZORAN_ZR36060) += zr36060.o obj-$(CONFIG_VIDEO_PMS) += pms.o -obj-$(CONFIG_VIDEO_PLANB) += planb.o obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o obj-$(CONFIG_VIDEO_STRADIS) += stradis.o obj-$(CONFIG_VIDEO_CPIA) += cpia.o diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c index 36047d4e70f6..e69de29bb2d1 100644 --- a/drivers/media/video/planb.c +++ b/drivers/media/video/planb.c @@ -1,2309 +0,0 @@ -/* - planb - PlanB frame grabber driver - - PlanB is used in the 7x00/8x00 series of PowerMacintosh - Computers as video input DMA controller. - - Copyright (C) 1998 Michel Lanners (mlan@cpu.lu) - - Based largely on the bttv driver by Ralph Metzler (rjkm@thp.uni-koeln.de) - - Additional debugging and coding by Takashi Oe (toe@unlserve.unl.edu) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* $Id: planb.c,v 1.18 1999/05/02 17:36:34 mlan Exp $ */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "planb.h" -#include "saa7196.h" - -/* Would you mind for some ugly debugging? */ -#if 0 -#define DEBUG(x...) printk(KERN_DEBUG ## x) /* Debug driver */ -#else -#define DEBUG(x...) /* Don't debug driver */ -#endif - -#if 0 -#define IDEBUG(x...) printk(KERN_DEBUG ## x) /* Debug interrupt part */ -#else -#define IDEBUG(x...) /* Don't debug interrupt part */ -#endif - -/* Ever seen a Mac with more than 1 of these? */ -#define PLANB_MAX 1 - -static int planb_num; -static struct planb planbs[PLANB_MAX]; -static volatile struct planb_registers *planb_regs; - -static int def_norm = PLANB_DEF_NORM; /* default norm */ -static int video_nr = -1; - -module_param(def_norm, int, 0); -MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)"); -module_param(video_nr, int, 0); -MODULE_LICENSE("GPL"); - - -/* ------------------ PlanB Exported Functions ------------------ */ -static long planb_write(struct video_device *, const char *, unsigned long, int); -static long planb_read(struct video_device *, char *, unsigned long, int); -static int planb_open(struct video_device *, int); -static void planb_close(struct video_device *); -static int planb_ioctl(struct video_device *, unsigned int, void *); -static int planb_init_done(struct video_device *); -static int planb_mmap(struct video_device *, const char *, unsigned long); -static void release_planb(void); -int init_planbs(struct video_init *); - -/* ------------------ PlanB Internal Functions ------------------ */ -static int planb_prepare_open(struct planb *); -static void planb_prepare_close(struct planb *); -static void saa_write_reg(unsigned char, unsigned char); -static unsigned char saa_status(int, struct planb *); -static void saa_set(unsigned char, unsigned char, struct planb *); -static void saa_init_regs(struct planb *); -static int grabbuf_alloc(struct planb *); -static int vgrab(struct planb *, struct video_mmap *); -static void add_clip(struct planb *, struct video_clip *); -static void fill_cmd_buff(struct planb *); -static void cmd_buff(struct planb *); -static volatile struct dbdma_cmd *setup_grab_cmd(int, struct planb *); -static void overlay_start(struct planb *); -static void overlay_stop(struct planb *); -static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *, unsigned short, - unsigned int); -static inline void tab_cmd_store(volatile struct dbdma_cmd *, unsigned int, - unsigned int); -static inline void tab_cmd_gen(volatile struct dbdma_cmd *, unsigned short, - unsigned short, unsigned int, unsigned int); -static int init_planb(struct planb *); -static int find_planb(void); -static void planb_pre_capture(int, int, struct planb *); -static volatile struct dbdma_cmd *cmd_geo_setup(volatile struct dbdma_cmd *, - int, int, int, int, int, struct planb *); -static inline void planb_dbdma_stop(volatile struct dbdma_regs *); -static unsigned int saa_geo_setup(int, int, int, int, struct planb *); -static inline int overlay_is_active(struct planb *); - -/*******************************/ -/* Memory management functions */ -/*******************************/ - -static int grabbuf_alloc(struct planb *pb) -{ - int i, npage; - - npage = MAX_GBUFFERS * ((PLANB_MAX_FBUF / PAGE_SIZE + 1) -#ifndef PLANB_GSCANLINE - + MAX_LNUM -#endif /* PLANB_GSCANLINE */ - ); - if ((pb->rawbuf = kmalloc(npage - * sizeof(unsigned long), GFP_KERNEL)) == 0) - return -ENOMEM; - for (i = 0; i < npage; i++) { - pb->rawbuf[i] = (unsigned char *)__get_free_pages(GFP_KERNEL - |GFP_DMA, 0); - if (!pb->rawbuf[i]) - break; - SetPageReserved(virt_to_page(pb->rawbuf[i])); - } - if (i-- < npage) { - printk(KERN_DEBUG "PlanB: init_grab: grab buffer not allocated\n"); - for (; i > 0; i--) { - ClearPageReserved(virt_to_page(pb->rawbuf[i])); - free_pages((unsigned long)pb->rawbuf[i], 0); - } - kfree(pb->rawbuf); - return -ENOBUFS; - } - pb->rawbuf_size = npage; - return 0; -} - -/*****************************/ -/* Hardware access functions */ -/*****************************/ - -static void saa_write_reg(unsigned char addr, unsigned char val) -{ - planb_regs->saa_addr = addr; eieio(); - planb_regs->saa_regval = val; eieio(); - return; -} - -/* return status byte 0 or 1: */ -static unsigned char saa_status(int byte, struct planb *pb) -{ - saa_regs[pb->win.norm][SAA7196_STDC] = - (saa_regs[pb->win.norm][SAA7196_STDC] & ~2) | ((byte & 1) << 1); - saa_write_reg (SAA7196_STDC, saa_regs[pb->win.norm][SAA7196_STDC]); - - /* Let's wait 30msec for this one */ - msleep_interruptible(30); - - return (unsigned char)in_8 (&planb_regs->saa_status); -} - -static void saa_set(unsigned char addr, unsigned char val, struct planb *pb) -{ - if(saa_regs[pb->win.norm][addr] != val) { - saa_regs[pb->win.norm][addr] = val; - saa_write_reg (addr, val); - } - return; -} - -static void saa_init_regs(struct planb *pb) -{ - int i; - - for (i = 0; i < SAA7196_NUMREGS; i++) - saa_write_reg (i, saa_regs[pb->win.norm][i]); -} - -static unsigned int saa_geo_setup(int width, int height, int interlace, int bpp, - struct planb *pb) -{ - int ht, norm = pb->win.norm; - - switch(bpp) { - case 2: - /* RGB555+a 1x16-bit + 16-bit transparent */ - saa_regs[norm][SAA7196_FMTS] &= ~0x3; - break; - case 1: - case 4: - /* RGB888 1x24-bit + 8-bit transparent */ - saa_regs[norm][SAA7196_FMTS] &= ~0x1; - saa_regs[norm][SAA7196_FMTS] |= 0x2; - break; - default: - return -EINVAL; - } - ht = (interlace ? height / 2 : height); - saa_regs[norm][SAA7196_OUTPIX] = (unsigned char) (width & 0x00ff); - saa_regs[norm][SAA7196_HFILT] = (saa_regs[norm][SAA7196_HFILT] & ~0x3) - | (width >> 8 & 0x3); - saa_regs[norm][SAA7196_OUTLINE] = (unsigned char) (ht & 0xff); - saa_regs[norm][SAA7196_VYP] = (saa_regs[norm][SAA7196_VYP] & ~0x3) - | (ht >> 8 & 0x3); - /* feed both fields if interlaced, or else feed only even fields */ - saa_regs[norm][SAA7196_FMTS] = (interlace) ? - (saa_regs[norm][SAA7196_FMTS] & ~0x60) - : (saa_regs[norm][SAA7196_FMTS] | 0x60); - /* transparent mode; extended format enabled */ - saa_regs[norm][SAA7196_DPATH] |= 0x3; - - return 0; -} - -/***************************/ -/* DBDMA support functions */ -/***************************/ - -static inline void planb_dbdma_restart(volatile struct dbdma_regs *ch) -{ - out_le32(&ch->control, PLANB_CLR(RUN)); - out_le32(&ch->control, PLANB_SET(RUN|WAKE) | PLANB_CLR(PAUSE)); -} - -static inline void planb_dbdma_stop(volatile struct dbdma_regs *ch) -{ - int i = 0; - - out_le32(&ch->control, PLANB_CLR(RUN) | PLANB_SET(FLUSH)); - while((in_le32(&ch->status) == (ACTIVE | FLUSH)) && (i < 999)) { - IDEBUG("PlanB: waiting for DMA to stop\n"); - i++; - } -} - -static inline void tab_cmd_dbdma(volatile struct dbdma_cmd *ch, - unsigned short command, unsigned int cmd_dep) -{ - st_le16(&ch->command, command); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static inline void tab_cmd_store(volatile struct dbdma_cmd *ch, - unsigned int phy_addr, unsigned int cmd_dep) -{ - st_le16(&ch->command, STORE_WORD | KEY_SYSTEM); - st_le16(&ch->req_count, 4); - st_le32(&ch->phy_addr, phy_addr); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static inline void tab_cmd_gen(volatile struct dbdma_cmd *ch, - unsigned short command, unsigned short req_count, - unsigned int phy_addr, unsigned int cmd_dep) -{ - st_le16(&ch->command, command); - st_le16(&ch->req_count, req_count); - st_le32(&ch->phy_addr, phy_addr); - st_le32(&ch->cmd_dep, cmd_dep); -} - -static volatile struct dbdma_cmd *cmd_geo_setup( - volatile struct dbdma_cmd *c1, int width, int height, int interlace, - int bpp, int clip, struct planb *pb) -{ - int norm = pb->win.norm; - - if((saa_geo_setup(width, height, interlace, bpp, pb)) != 0) - return (volatile struct dbdma_cmd *)NULL; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_FMTS); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_FMTS]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_DPATH); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_DPATH]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->even), - bpp | ((clip)? PLANB_CLIPMASK: 0)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->odd), - bpp | ((clip)? PLANB_CLIPMASK: 0)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_OUTPIX); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_OUTPIX]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_HFILT); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_HFILT]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_OUTLINE); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_OUTLINE]); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_addr), - SAA7196_VYP); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->saa_regval), - saa_regs[norm][SAA7196_VYP]); - return c1; -} - -/******************************/ -/* misc. supporting functions */ -/******************************/ - -static inline void planb_lock(struct planb *pb) -{ - mutex_lock(&pb->lock); -} - -static inline void planb_unlock(struct planb *pb) -{ - mutex_unlock(&pb->lock); -} - -/***************/ -/* Driver Core */ -/***************/ - -static int planb_prepare_open(struct planb *pb) -{ - int i, size; - - /* allocate memory for two plus alpha command buffers (size: max lines, - plus 40 commands handling, plus 1 alignment), plus dummy command buf, - plus clipmask buffer, plus frame grabbing status */ - size = (pb->tab_size*(2+MAX_GBUFFERS*TAB_FACTOR)+1+MAX_GBUFFERS - * PLANB_DUMMY)*sizeof(struct dbdma_cmd) - +(PLANB_MAXLINES*((PLANB_MAXPIXELS+7)& ~7))/8 - +MAX_GBUFFERS*sizeof(unsigned int); - if ((pb->priv_space = kzalloc (size, GFP_KERNEL)) == 0) - return -ENOMEM; - pb->overlay_last1 = pb->ch1_cmd = (volatile struct dbdma_cmd *) - DBDMA_ALIGN (pb->priv_space); - pb->overlay_last2 = pb->ch2_cmd = pb->ch1_cmd + pb->tab_size; - pb->ch1_cmd_phys = virt_to_bus(pb->ch1_cmd); - pb->cap_cmd[0] = pb->ch2_cmd + pb->tab_size; - pb->pre_cmd[0] = pb->cap_cmd[0] + pb->tab_size * TAB_FACTOR; - for (i = 1; i < MAX_GBUFFERS; i++) { - pb->cap_cmd[i] = pb->pre_cmd[i-1] + PLANB_DUMMY; - pb->pre_cmd[i] = pb->cap_cmd[i] + pb->tab_size * TAB_FACTOR; - } - pb->frame_stat=(volatile unsigned int *)(pb->pre_cmd[MAX_GBUFFERS-1] - + PLANB_DUMMY); - pb->mask = (unsigned char *)(pb->frame_stat+MAX_GBUFFERS); - - pb->rawbuf = NULL; - pb->rawbuf_size = 0; - pb->grabbing = 0; - for (i = 0; i < MAX_GBUFFERS; i++) { - pb->frame_stat[i] = GBUFFER_UNUSED; - pb->gwidth[i] = 0; - pb->gheight[i] = 0; - pb->gfmt[i] = 0; - pb->gnorm_switch[i] = 0; -#ifndef PLANB_GSCANLINE - pb->lsize[i] = 0; - pb->lnum[i] = 0; -#endif /* PLANB_GSCANLINE */ - } - pb->gcount = 0; - pb->suspend = 0; - pb->last_fr = -999; - pb->prev_last_fr = -999; - - /* Reset DMA controllers */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - return 0; -} - -static void planb_prepare_close(struct planb *pb) -{ - int i; - - /* make sure the dma's are idle */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - /* free kernel memory of command buffers */ - if(pb->priv_space != 0) { - kfree (pb->priv_space); - pb->priv_space = 0; - pb->cmd_buff_inited = 0; - } - if(pb->rawbuf) { - for (i = 0; i < pb->rawbuf_size; i++) { - ClearPageReserved(virt_to_page(pb->rawbuf[i])); - free_pages((unsigned long)pb->rawbuf[i], 0); - } - kfree(pb->rawbuf); - } - pb->rawbuf = NULL; -} - -/*****************************/ -/* overlay support functions */ -/*****************************/ - -static inline int overlay_is_active(struct planb *pb) -{ - unsigned int size = pb->tab_size * sizeof(struct dbdma_cmd); - unsigned int caddr = (unsigned)in_le32(&pb->planb_base->ch1.cmdptr); - - return (in_le32(&pb->overlay_last1->cmd_dep) == pb->ch1_cmd_phys) - && (caddr < (pb->ch1_cmd_phys + size)) - && (caddr >= (unsigned)pb->ch1_cmd_phys); -} - -static void overlay_start(struct planb *pb) -{ - - DEBUG("PlanB: overlay_start()\n"); - - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - - DEBUG("PlanB: presumably, grabbing is in progress...\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - out_le32 (&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->ch2_cmd)); - planb_dbdma_restart(&pb->planb_base->ch2); - st_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - eieio(); - pb->prev_last_fr = pb->last_fr; - pb->last_fr = -2; - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - IDEBUG("PlanB: became inactive " - "in the mean time... reactivating\n"); - planb_dbdma_stop(&pb->planb_base->ch1); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->ch1_cmd)); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } else { - - DEBUG("PlanB: currently idle, so can do whatever\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - st_le32 (&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->ch2_cmd)); - st_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->ch1_cmd)); - out_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - planb_dbdma_restart(&pb->planb_base->ch2); - planb_dbdma_restart(&pb->planb_base->ch1); - pb->last_fr = -1; - } - return; -} - -static void overlay_stop(struct planb *pb) -{ - DEBUG("PlanB: overlay_stop()\n"); - - if(pb->last_fr == -1) { - - DEBUG("PlanB: no grabbing, it seems...\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->last_fr = -999; - } else if(pb->last_fr == -2) { - unsigned int cmd_dep; - tab_cmd_dbdma(pb->cap_cmd[pb->prev_last_fr], DBDMA_STOP, 0); - eieio(); - cmd_dep = (unsigned int)in_le32(&pb->overlay_last1->cmd_dep); - if(overlay_is_active(pb)) { - - DEBUG("PlanB: overlay is currently active\n"); - - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - if(cmd_dep != pb->ch1_cmd_phys) { - out_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->overlay_last1)); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } - pb->last_fr = pb->prev_last_fr; - pb->prev_last_fr = -999; - } - return; -} - -static void suspend_overlay(struct planb *pb) -{ - int fr = -1; - struct dbdma_cmd last; - - DEBUG("PlanB: suspend_overlay: %d\n", pb->suspend); - - if(pb->suspend++) - return; - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - if(pb->last_fr == -2) { - fr = pb->prev_last_fr; - memcpy(&last, (void*)pb->last_cmd[fr], sizeof(last)); - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - } - if(overlay_is_active(pb)) { - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->suspended.overlay = 1; - pb->suspended.frame = fr; - memcpy(&pb->suspended.cmd, &last, sizeof(last)); - return; - } - } - pb->suspended.overlay = 0; - pb->suspended.frame = fr; - memcpy(&pb->suspended.cmd, &last, sizeof(last)); - return; -} - -static void resume_overlay(struct planb *pb) -{ - - DEBUG("PlanB: resume_overlay: %d\n", pb->suspend); - - if(pb->suspend > 1) - return; - if(pb->suspended.frame != -1) { - memcpy((void*)pb->last_cmd[pb->suspended.frame], - &pb->suspended.cmd, sizeof(pb->suspended.cmd)); - } - if(ACTIVE & in_le32(&pb->planb_base->ch1.status)) { - goto finish; - } - if(pb->suspended.overlay) { - - DEBUG("PlanB: overlay being resumed\n"); - - st_le16 (&pb->ch1_cmd->command, DBDMA_NOP); - st_le16 (&pb->ch2_cmd->command, DBDMA_NOP); - /* Set command buffer addresses */ - st_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->overlay_last1)); - out_le32(&pb->planb_base->ch2.cmdptr, - virt_to_bus(pb->overlay_last2)); - /* Start the DMA controller */ - out_le32 (&pb->planb_base->ch2.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - out_le32 (&pb->planb_base->ch1.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - } else if(pb->suspended.frame != -1) { - out_le32(&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->last_cmd[pb->suspended.frame])); - out_le32 (&pb->planb_base->ch1.control, - PLANB_CLR(PAUSE) | PLANB_SET(RUN|WAKE)); - } - -finish: - pb->suspend--; - wake_up_interruptible(&pb->suspendq); -} - -static void add_clip(struct planb *pb, struct video_clip *clip) -{ - volatile unsigned char *base; - int xc = clip->x, yc = clip->y; - int wc = clip->width, hc = clip->height; - int ww = pb->win.width, hw = pb->win.height; - int x, y, xtmp1, xtmp2; - - DEBUG("PlanB: clip %dx%d+%d+%d\n", wc, hc, xc, yc); - - if(xc < 0) { - wc += xc; - xc = 0; - } - if(yc < 0) { - hc += yc; - yc = 0; - } - if(xc + wc > ww) - wc = ww - xc; - if(wc <= 0) /* Nothing to do */ - return; - if(yc + hc > hw) - hc = hw - yc; - - for (y = yc; y < yc+hc; y++) { - xtmp1=xc>>3; - xtmp2=(xc+wc)>>3; - base = pb->mask + y*96; - if(xc != 0 || wc >= 8) - *(base + xtmp1) &= (unsigned char)(0x00ff & - (0xff00 >> (xc&7))); - for (x = xtmp1 + 1; x < xtmp2; x++) { - *(base + x) = 0; - } - if(xc < (ww & ~0x7)) - *(base + xtmp2) &= (unsigned char)(0x00ff >> - ((xc+wc) & 7)); - } - - return; -} - -static void fill_cmd_buff(struct planb *pb) -{ - int restore = 0; - volatile struct dbdma_cmd last; - - DEBUG("PlanB: fill_cmd_buff()\n"); - - if(pb->overlay_last1 != pb->ch1_cmd) { - restore = 1; - last = *(pb->overlay_last1); - } - memset ((void *) pb->ch1_cmd, 0, 2 * pb->tab_size - * sizeof(struct dbdma_cmd)); - cmd_buff (pb); - if(restore) - *(pb->overlay_last1) = last; - if(pb->suspended.overlay) { - unsigned long jump_addr = in_le32(&pb->overlay_last1->cmd_dep); - if(jump_addr != pb->ch1_cmd_phys) { - int i; - - DEBUG("PlanB: adjusting ch1's jump address\n"); - - for(i = 0; i < MAX_GBUFFERS; i++) { - if(pb->need_pre_capture[i]) { - if(jump_addr == virt_to_bus(pb->pre_cmd[i])) - goto found; - } else { - if(jump_addr == virt_to_bus(pb->cap_cmd[i])) - goto found; - } - } - - DEBUG("PlanB: not found...\n"); - - goto out; -found: - if(pb->need_pre_capture[i]) - out_le32(&pb->pre_cmd[i]->phy_addr, - virt_to_bus(pb->overlay_last1)); - else - out_le32(&pb->cap_cmd[i]->phy_addr, - virt_to_bus(pb->overlay_last1)); - } - } -out: - pb->cmd_buff_inited = 1; - - return; -} - -static void cmd_buff(struct planb *pb) -{ - int i, bpp, count, nlines, stepsize, interlace; - unsigned long base, jump, addr_com, addr_dep; - volatile struct dbdma_cmd *c1 = pb->ch1_cmd; - volatile struct dbdma_cmd *c2 = pb->ch2_cmd; - - interlace = pb->win.interlace; - bpp = pb->win.bpp; - count = (bpp * ((pb->win.x + pb->win.width > pb->win.swidth) ? - (pb->win.swidth - pb->win.x) : pb->win.width)); - nlines = ((pb->win.y + pb->win.height > pb->win.sheight) ? - (pb->win.sheight - pb->win.y) : pb->win.height); - - /* Do video in: */ - - /* Preamble commands: */ - addr_com = virt_to_bus(c1); - addr_dep = virt_to_bus(&c1->cmd_dep); - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - jump = virt_to_bus(c1+16); /* 14 by cmd_geo_setup() and 2 for padding */ - if((c1 = cmd_geo_setup(c1, pb->win.width, pb->win.height, interlace, - bpp, 1, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered serious problems\n"); - tab_cmd_dbdma(pb->ch1_cmd + 1, DBDMA_STOP, 0); - tab_cmd_dbdma(pb->ch2_cmd + 1, DBDMA_STOP, 0); - return; - } - tab_cmd_store(c1++, addr_com, (unsigned)(DBDMA_NOP | BR_ALWAYS) << 16); - tab_cmd_store(c1++, addr_dep, jump); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - /* (1) wait for field sync to be set */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - /* wait for field sync to be cleared */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - /* if not odd field, wait until field sync is set again */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - /* assert ch_sync to ch2 */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_SET(CH_SYNC)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - base = (pb->frame_buffer_phys + pb->offset + pb->win.y * (pb->win.bpl - + pb->win.pad) + pb->win.x * bpp); - - if (interlace) { - stepsize = 2; - jump = virt_to_bus(c1 + (nlines + 1) / 2); - } else { - stepsize = 1; - jump = virt_to_bus(c1 + nlines); - } - - /* even field data: */ - for (i=0; i < nlines; i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, - count, base + i * (pb->win.bpl + pb->win.pad), jump); - - /* For non-interlaced, we use even fields only */ - if (!interlace) - goto cmd_tab_data_end; - - /* Resync to odd field */ - /* (2) wait for field sync to be set */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - /* wait for field sync to be cleared */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - /* if not odd field, wait until field sync is set again */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - /* assert ch_sync to ch2 */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_SET(CH_SYNC)); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - /* odd field data: */ - jump = virt_to_bus(c1 + nlines / 2); - for (i=1; i < nlines; i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + i * (pb->win.bpl + pb->win.pad), jump); - - /* And jump back to the start */ -cmd_tab_data_end: - pb->overlay_last1 = c1; /* keep a pointer to the last command */ - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch1_cmd)); - - /* Clipmask command buffer */ - - /* Preamble commands: */ - tab_cmd_dbdma(c2++, DBDMA_NOP, 0); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel), - PLANB_SET(CH_SYNC)); - /* wait until ch1 asserts ch_sync */ - tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0); - /* clear ch_sync asserted by ch1 */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.control), - PLANB_CLR(CH_SYNC)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(ODD_FIELD)); - - /* jump to end of even field if appropriate */ - /* this points to (interlace)? pos. C: pos. B */ - jump = (interlace) ? virt_to_bus(c2 + (nlines + 1) / 2 + 2): - virt_to_bus(c2 + nlines + 2); - /* if odd field, skip over to odd field clipmasking */ - tab_cmd_dbdma(c2++, DBDMA_NOP | BR_IFSET, jump); - - /* even field mask: */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(DMA_ABORT)); - /* this points to pos. B */ - jump = (interlace) ? virt_to_bus(c2 + nlines + 1): - virt_to_bus(c2 + nlines); - base = virt_to_bus(pb->mask); - for (i=0; i < nlines; i += stepsize, c2++) - tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96, - base + i * 96, jump); - - /* For non-interlaced, we use only even fields */ - if(!interlace) - goto cmd_tab_mask_end; - - /* odd field mask: */ -/* C */ tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch2.br_sel), - PLANB_SET(DMA_ABORT)); - /* this points to pos. B */ - jump = virt_to_bus(c2 + nlines / 2); - base = virt_to_bus(pb->mask); - for (i=1; i < nlines; i += 2, c2++) /* abort if set */ - tab_cmd_gen(c2, OUTPUT_MORE | KEY_STREAM0 | BR_IFSET, 96, - base + i * 96, jump); - - /* Inform channel 1 and jump back to start */ -cmd_tab_mask_end: - /* ok, I just realized this is kind of flawed. */ - /* this part is reached only after odd field clipmasking. */ - /* wanna clean up? */ - /* wait for field sync to be set */ - /* corresponds to fsync (1) of ch1 */ -/* B */ tab_cmd_dbdma(c2++, DBDMA_NOP | WAIT_IFCLR, 0); - /* restart ch1, meant to clear any dead bit or something */ - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control), - PLANB_CLR(RUN)); - tab_cmd_store(c2++, (unsigned)(&pb->planb_base_phys->ch1.control), - PLANB_SET(RUN)); - pb->overlay_last2 = c2; /* keep a pointer to the last command */ - /* start over even field clipmasking */ - tab_cmd_dbdma(c2, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->ch2_cmd)); - - eieio(); - return; -} - -/*********************************/ -/* grabdisplay support functions */ -/*********************************/ - -static int palette2fmt[] = { - 0, - PLANB_GRAY, - 0, - 0, - 0, - PLANB_COLOUR32, - PLANB_COLOUR15, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -}; - -#define PLANB_PALETTE_MAX 15 - -static int vgrab(struct planb *pb, struct video_mmap *mp) -{ - unsigned int fr = mp->frame; - unsigned int format; - - if(pb->rawbuf==NULL) { - int err; - if((err=grabbuf_alloc(pb))) - return err; - } - - IDEBUG("PlanB: grab %d: %dx%d(%u)\n", pb->grabbing, - mp->width, mp->height, fr); - - if(pb->grabbing >= MAX_GBUFFERS) - return -ENOBUFS; - if(fr > (MAX_GBUFFERS - 1) || fr < 0) - return -EINVAL; - if(mp->height <= 0 || mp->width <= 0) - return -EINVAL; - if(mp->format < 0 || mp->format >= PLANB_PALETTE_MAX) - return -EINVAL; - if((format = palette2fmt[mp->format]) == 0) - return -EINVAL; - if (mp->height * mp->width * format > PLANB_MAX_FBUF) /* format = bpp */ - return -EINVAL; - - planb_lock(pb); - if(mp->width != pb->gwidth[fr] || mp->height != pb->gheight[fr] || - format != pb->gfmt[fr] || (pb->gnorm_switch[fr])) { - int i; -#ifndef PLANB_GSCANLINE - unsigned int osize = pb->gwidth[fr] * pb->gheight[fr] - * pb->gfmt[fr]; - unsigned int nsize = mp->width * mp->height * format; -#endif - - IDEBUG("PlanB: gwidth = %d, gheight = %d, mp->format = %u\n", - mp->width, mp->height, mp->format); - -#ifndef PLANB_GSCANLINE - if(pb->gnorm_switch[fr]) - nsize = 0; - if (nsize < osize) { - for(i = pb->gbuf_idx[fr]; osize > 0; i++) { - memset((void *)pb->rawbuf[i], 0, PAGE_SIZE); - osize -= PAGE_SIZE; - } - } - for(i = pb->l_fr_addr_idx[fr]; i < pb->l_fr_addr_idx[fr] - + pb->lnum[fr]; i++) - memset((void *)pb->rawbuf[i], 0, PAGE_SIZE); -#else -/* XXX TODO */ -/* - if(pb->gnorm_switch[fr]) - memset((void *)pb->gbuffer[fr], 0, - pb->gbytes_per_line * pb->gheight[fr]); - else { - if(mp-> - for(i = 0; i < pb->gheight[fr]; i++) { - memset((void *)(pb->gbuffer[fr] - + pb->gbytes_per_line * i - } - } -*/ -#endif - pb->gwidth[fr] = mp->width; - pb->gheight[fr] = mp->height; - pb->gfmt[fr] = format; - pb->last_cmd[fr] = setup_grab_cmd(fr, pb); - planb_pre_capture(fr, pb->gfmt[fr], pb); /* gfmt = bpp */ - pb->need_pre_capture[fr] = 1; - pb->gnorm_switch[fr] = 0; - } else - pb->need_pre_capture[fr] = 0; - pb->frame_stat[fr] = GBUFFER_GRABBING; - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - - IDEBUG("PlanB: ch1 inactive, initiating grabbing\n"); - - planb_dbdma_stop(&pb->planb_base->ch1); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->pre_cmd[fr])); - } else { - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - /* let's be on the safe side. here is not timing critical. */ - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), DBDMA_NOP, 0); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->cap_cmd[fr])); - } - planb_dbdma_restart(&pb->planb_base->ch1); - pb->last_fr = fr; - } else { - int i; - - IDEBUG("PlanB: ch1 active, grabbing being queued\n"); - - if((pb->last_fr == -1) || ((pb->last_fr == -2) && - overlay_is_active(pb))) { - - IDEBUG("PlanB: overlay is active, grabbing defered\n"); - - tab_cmd_dbdma(pb->last_cmd[fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_store(pb->pre_cmd[fr], - virt_to_bus(&pb->overlay_last1->cmd_dep), - virt_to_bus(pb->ch1_cmd)); - eieio(); - out_le32 (&pb->overlay_last1->cmd_dep, - virt_to_bus(pb->pre_cmd[fr])); - } else { - tab_cmd_store(pb->cap_cmd[fr], - virt_to_bus(&pb->overlay_last1->cmd_dep), - virt_to_bus(pb->ch1_cmd)); - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - eieio(); - out_le32 (&pb->overlay_last1->cmd_dep, - virt_to_bus(pb->cap_cmd[fr])); - } - for(i = 0; overlay_is_active(pb) && i < 999; i++) - IDEBUG("PlanB: waiting for overlay done\n"); - tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0); - pb->prev_last_fr = fr; - pb->last_fr = -2; - } else if(pb->last_fr == -2) { - - IDEBUG("PlanB: mixed mode detected, grabbing" - " will be done before activating overlay\n"); - - tab_cmd_dbdma(pb->ch1_cmd, DBDMA_NOP, 0); - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->pre_cmd[fr])); - eieio(); - } else { - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - if(pb->gwidth[pb->prev_last_fr] != - pb->gwidth[fr] - || pb->gheight[pb->prev_last_fr] != - pb->gheight[fr] - || pb->gfmt[pb->prev_last_fr] != - pb->gfmt[fr]) - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - else - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr] + 16)); - tab_cmd_dbdma(pb->last_cmd[pb->prev_last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr])); - eieio(); - } - tab_cmd_dbdma(pb->last_cmd[fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->ch1_cmd)); - eieio(); - pb->prev_last_fr = fr; - pb->last_fr = -2; - } else { - - IDEBUG("PlanB: active grabbing session detected\n"); - - if(pb->need_pre_capture[fr]) { - - IDEBUG("PlanB: padding pre-capture sequence\n"); - - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->pre_cmd[fr])); - eieio(); - } else { - tab_cmd_dbdma(pb->last_cmd[fr], DBDMA_STOP, 0); - tab_cmd_dbdma(pb->cap_cmd[fr], DBDMA_NOP, 0); - if(pb->gwidth[pb->last_fr] != pb->gwidth[fr] - || pb->gheight[pb->last_fr] != - pb->gheight[fr] - || pb->gfmt[pb->last_fr] != - pb->gfmt[fr]) - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP, 0); - else - tab_cmd_dbdma((pb->cap_cmd[fr] + 1), - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr] + 16)); - tab_cmd_dbdma(pb->last_cmd[pb->last_fr], - DBDMA_NOP | BR_ALWAYS, - virt_to_bus(pb->cap_cmd[fr])); - eieio(); - } - pb->last_fr = fr; - } - if(!(ACTIVE & in_le32(&pb->planb_base->ch1.status))) { - - IDEBUG("PlanB: became inactive in the mean time..." - "reactivating\n"); - - planb_dbdma_stop(&pb->planb_base->ch1); - out_le32 (&pb->planb_base->ch1.cmdptr, - virt_to_bus(pb->cap_cmd[fr])); - planb_dbdma_restart(&pb->planb_base->ch1); - } - } - pb->grabbing++; - planb_unlock(pb); - - return 0; -} - -static void planb_pre_capture(int fr, int bpp, struct planb *pb) -{ - volatile struct dbdma_cmd *c1 = pb->pre_cmd[fr]; - int interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0; - - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace, - bpp, 0, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered some problems\n"); - tab_cmd_dbdma(pb->pre_cmd[fr] + 1, DBDMA_STOP, 0); - return; - } - /* Sync to even field */ - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - /* For non-interlaced, we use even fields only */ - if (pb->gheight[fr] <= pb->maxlines/2) - goto cmd_tab_data_end; - /* Sync to odd field */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); -cmd_tab_data_end: - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(pb->cap_cmd[fr])); - - eieio(); -} - -static volatile struct dbdma_cmd *setup_grab_cmd(int fr, struct planb *pb) -{ - int i, bpp, count, nlines, stepsize, interlace; -#ifdef PLANB_GSCANLINE - int scanline; -#else - int nlpp, leftover1; - unsigned long base; -#endif - unsigned long jump; - int pagei; - volatile struct dbdma_cmd *c1; - volatile struct dbdma_cmd *jump_addr; - - c1 = pb->cap_cmd[fr]; - interlace = (pb->gheight[fr] > pb->maxlines/2)? 1: 0; - bpp = pb->gfmt[fr]; /* gfmt = bpp */ - count = bpp * pb->gwidth[fr]; - nlines = pb->gheight[fr]; -#ifdef PLANB_GSCANLINE - scanline = pb->gbytes_per_line; -#else - pb->lsize[fr] = count; - pb->lnum[fr] = 0; -#endif - - /* Do video in: */ - - /* Preamble commands: */ - tab_cmd_dbdma(c1++, DBDMA_NOP, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, virt_to_bus(c1 + 16)); c1++; - if((c1 = cmd_geo_setup(c1, pb->gwidth[fr], pb->gheight[fr], interlace, - bpp, 0, pb)) == NULL) { - printk(KERN_WARNING "PlanB: encountered serious problems\n"); - tab_cmd_dbdma(pb->cap_cmd[fr] + 1, DBDMA_STOP, 0); - return (pb->cap_cmd[fr] + 2); - } - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.wait_sel), - PLANB_SET(FIELD_SYNC)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFSET, virt_to_bus(c1-3)); c1++; - tab_cmd_dbdma(c1++, DBDMA_NOP | INTR_ALWAYS, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - if (interlace) { - stepsize = 2; - jump_addr = c1 + TAB_FACTOR * (nlines + 1) / 2; - } else { - stepsize = 1; - jump_addr = c1 + TAB_FACTOR * nlines; - } - jump = virt_to_bus(jump_addr); - - /* even field data: */ - - pagei = pb->gbuf_idx[fr]; -#ifdef PLANB_GSCANLINE - for (i = 0; i < nlines; i += stepsize) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pagei - + i * scanline / PAGE_SIZE]), jump); - } -#else - i = 0; - leftover1 = 0; - do { - int j; - - base = virt_to_bus(pb->rawbuf[pagei]); - nlpp = (PAGE_SIZE - leftover1) / count / stepsize; - for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, - count, base + count * j * stepsize + leftover1, jump); - if(i < nlines) { - int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1; - - if(lov0 == 0) - leftover1 = 0; - else { - if(lov0 >= count) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, base - + count * nlpp * stepsize + leftover1, jump); - } else { - pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei] - + count * nlpp * stepsize + leftover1; - pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1; - pb->l_to_next_size[fr][pb->lnum[fr]] = count - lov0; - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr] - + pb->lnum[fr]]), jump); - if(++pb->lnum[fr] > MAX_LNUM) - pb->lnum[fr]--; - } - leftover1 = count * stepsize - lov0; - i += stepsize; - } - } - pagei++; - } while(i < nlines); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump); - c1 = jump_addr; -#endif /* PLANB_GSCANLINE */ - - /* For non-interlaced, we use even fields only */ - if (!interlace) - goto cmd_tab_data_end; - - /* Sync to odd field */ - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFCLR, 0); - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(ODD_FIELD)); - tab_cmd_dbdma(c1++, DBDMA_NOP | WAIT_IFSET, 0); - tab_cmd_dbdma(c1, DBDMA_NOP | BR_IFCLR, virt_to_bus(c1-3)); c1++; - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->ch1.br_sel), - PLANB_SET(DMA_ABORT)); - - /* odd field data: */ - jump_addr = c1 + TAB_FACTOR * nlines / 2; - jump = virt_to_bus(jump_addr); -#ifdef PLANB_GSCANLINE - for (i = 1; i < nlines; i += stepsize) { - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pagei - + i * scanline / PAGE_SIZE]), jump); - } -#else - i = 1; - leftover1 = 0; - pagei = pb->gbuf_idx[fr]; - if(nlines <= 1) - goto skip; - do { - int j; - - base = virt_to_bus(pb->rawbuf[pagei]); - nlpp = (PAGE_SIZE - leftover1) / count / stepsize; - if(leftover1 >= count) { - tab_cmd_gen(c1++, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + leftover1 - count, jump); - i += stepsize; - } - for(j = 0; j < nlpp && i < nlines; j++, i += stepsize, c1++) - tab_cmd_gen(c1, INPUT_MORE | KEY_STREAM0 | BR_IFSET, count, - base + count * (j * stepsize + 1) + leftover1, jump); - if(i < nlines) { - int lov0 = PAGE_SIZE - count * nlpp * stepsize - leftover1; - - if(lov0 == 0) - leftover1 = 0; - else { - if(lov0 > count) { - pb->l_to_addr[fr][pb->lnum[fr]] = pb->rawbuf[pagei] - + count * (nlpp * stepsize + 1) + leftover1; - pb->l_to_next_idx[fr][pb->lnum[fr]] = pagei + 1; - pb->l_to_next_size[fr][pb->lnum[fr]] = count * stepsize - - lov0; - tab_cmd_gen(c1++, INPUT_MORE | BR_IFSET, count, - virt_to_bus(pb->rawbuf[pb->l_fr_addr_idx[fr] - + pb->lnum[fr]]), jump); - if(++pb->lnum[fr] > MAX_LNUM) - pb->lnum[fr]--; - i += stepsize; - } - leftover1 = count * stepsize - lov0; - } - } - pagei++; - } while(i < nlines); -skip: - tab_cmd_dbdma(c1, DBDMA_NOP | BR_ALWAYS, jump); - c1 = jump_addr; -#endif /* PLANB_GSCANLINE */ - -cmd_tab_data_end: - tab_cmd_store(c1++, (unsigned)(&pb->planb_base_phys->intr_stat), - (fr << 9) | PLANB_FRM_IRQ | PLANB_GEN_IRQ); - /* stop it */ - tab_cmd_dbdma(c1, DBDMA_STOP, 0); - - eieio(); - return c1; -} - -static irqreturn_t planb_irq(int irq, void *dev_id) -{ - unsigned int stat, astat; - struct planb *pb = (struct planb *)dev_id; - - IDEBUG("PlanB: planb_irq()\n"); - - /* get/clear interrupt status bits */ - eieio(); - stat = in_le32(&pb->planb_base->intr_stat); - astat = stat & pb->intr_mask; - out_le32(&pb->planb_base->intr_stat, PLANB_FRM_IRQ - & ~astat & stat & ~PLANB_GEN_IRQ); - IDEBUG("PlanB: stat = %X, astat = %X\n", stat, astat); - - if(astat & PLANB_FRM_IRQ) { - unsigned int fr = stat >> 9; -#ifndef PLANB_GSCANLINE - int i; -#endif - IDEBUG("PlanB: PLANB_FRM_IRQ\n"); - - pb->gcount++; - - IDEBUG("PlanB: grab %d: fr = %d, gcount = %d\n", - pb->grabbing, fr, pb->gcount); -#ifndef PLANB_GSCANLINE - IDEBUG("PlanB: %d * %d bytes are being copied over\n", - pb->lnum[fr], pb->lsize[fr]); - for(i = 0; i < pb->lnum[fr]; i++) { - int first = pb->lsize[fr] - pb->l_to_next_size[fr][i]; - - memcpy(pb->l_to_addr[fr][i], - pb->rawbuf[pb->l_fr_addr_idx[fr] + i], - first); - memcpy(pb->rawbuf[pb->l_to_next_idx[fr][i]], - pb->rawbuf[pb->l_fr_addr_idx[fr] + i] + first, - pb->l_to_next_size[fr][i]); - } -#endif - pb->frame_stat[fr] = GBUFFER_DONE; - pb->grabbing--; - wake_up_interruptible(&pb->capq); - return IRQ_HANDLED; - } - /* incorrect interrupts? */ - pb->intr_mask = PLANB_CLR_IRQ; - out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - printk(KERN_ERR "PlanB: IRQ lockup, cleared intrrupts" - " unconditionally\n"); - return IRQ_HANDLED; -} - -/******************************* - * Device Operations functions * - *******************************/ - -static int planb_open(struct video_device *dev, int mode) -{ - struct planb *pb = (struct planb *)dev; - - if (pb->user == 0) { - int err; - if((err = planb_prepare_open(pb)) != 0) - return err; - } - pb->user++; - - DEBUG("PlanB: device opened\n"); - return 0; -} - -static void planb_close(struct video_device *dev) -{ - struct planb *pb = (struct planb *)dev; - - if(pb->user < 1) /* ??? */ - return; - planb_lock(pb); - if (pb->user == 1) { - if (pb->overlay) { - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - pb->overlay = 0; - } - planb_prepare_close(pb); - } - pb->user--; - planb_unlock(pb); - - DEBUG("PlanB: device closed\n"); -} - -static long planb_read(struct video_device *v, char *buf, unsigned long count, - int nonblock) -{ - DEBUG("planb: read request\n"); - return -EINVAL; -} - -static long planb_write(struct video_device *v, const char *buf, - unsigned long count, int nonblock) -{ - DEBUG("planb: write request\n"); - return -EINVAL; -} - -static int planb_ioctl(struct video_device *dev, unsigned int cmd, void *arg) -{ - struct planb *pb=(struct planb *)dev; - - switch (cmd) - { - case VIDIOCGCAP: - { - struct video_capability b; - - DEBUG("PlanB: IOCTL VIDIOCGCAP\n"); - - strcpy (b.name, pb->video_dev.name); - b.type = VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | - VID_TYPE_FRAMERAM | VID_TYPE_SCALES | - VID_TYPE_CAPTURE; - b.channels = 2; /* composite & svhs */ - b.audios = 0; - b.maxwidth = PLANB_MAXPIXELS; - b.maxheight = PLANB_MAXLINES; - b.minwidth = 32; /* wild guess */ - b.minheight = 32; - if (copy_to_user(arg,&b,sizeof(b))) - return -EFAULT; - return 0; - } - case VIDIOCSFBUF: - { - struct video_buffer v; - unsigned short bpp; - unsigned int fmt; - - DEBUG("PlanB: IOCTL VIDIOCSFBUF\n"); - - if (!capable(CAP_SYS_ADMIN) - || !capable(CAP_SYS_RAWIO)) - return -EPERM; - if (copy_from_user(&v, arg,sizeof(v))) - return -EFAULT; - planb_lock(pb); - switch(v.depth) { - case 8: - bpp = 1; - fmt = PLANB_GRAY; - break; - case 15: - case 16: - bpp = 2; - fmt = PLANB_COLOUR15; - break; - case 24: - case 32: - bpp = 4; - fmt = PLANB_COLOUR32; - break; - default: - planb_unlock(pb); - return -EINVAL; - } - if (bpp * v.width > v.bytesperline) { - planb_unlock(pb); - return -EINVAL; - } - pb->win.bpp = bpp; - pb->win.color_fmt = fmt; - pb->frame_buffer_phys = (unsigned long) v.base; - pb->win.sheight = v.height; - pb->win.swidth = v.width; - pb->picture.depth = pb->win.depth = v.depth; - pb->win.bpl = pb->win.bpp * pb->win.swidth; - pb->win.pad = v.bytesperline - pb->win.bpl; - - DEBUG("PlanB: Display at %p is %d by %d, bytedepth %d," - " bpl %d (+ %d)\n", v.base, v.width,v.height, - pb->win.bpp, pb->win.bpl, pb->win.pad); - - pb->cmd_buff_inited = 0; - if(pb->overlay) { - suspend_overlay(pb); - fill_cmd_buff(pb); - resume_overlay(pb); - } - planb_unlock(pb); - return 0; - } - case VIDIOCGFBUF: - { - struct video_buffer v; - - DEBUG("PlanB: IOCTL VIDIOCGFBUF\n"); - - v.base = (void *)pb->frame_buffer_phys; - v.height = pb->win.sheight; - v.width = pb->win.swidth; - v.depth = pb->win.depth; - v.bytesperline = pb->win.bpl + pb->win.pad; - if (copy_to_user(arg, &v, sizeof(v))) - return -EFAULT; - return 0; - } - case VIDIOCCAPTURE: - { - int i; - - if(copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - if(i==0) { - DEBUG("PlanB: IOCTL VIDIOCCAPTURE Stop\n"); - - if (!(pb->overlay)) - return 0; - planb_lock(pb); - pb->overlay = 0; - overlay_stop(pb); - planb_unlock(pb); - } else { - DEBUG("PlanB: IOCTL VIDIOCCAPTURE Start\n"); - - if (pb->frame_buffer_phys == 0 || - pb->win.width == 0 || - pb->win.height == 0) - return -EINVAL; - if (pb->overlay) - return 0; - planb_lock(pb); - pb->overlay = 1; - if(!(pb->cmd_buff_inited)) - fill_cmd_buff(pb); - overlay_start(pb); - planb_unlock(pb); - } - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel v; - - DEBUG("PlanB: IOCTL VIDIOCGCHAN\n"); - - if(copy_from_user(&v, arg,sizeof(v))) - return -EFAULT; - v.flags = 0; - v.tuners = 0; - v.type = VIDEO_TYPE_CAMERA; - v.norm = pb->win.norm; - switch(v.channel) - { - case 0: - strcpy(v.name,"Composite"); - break; - case 1: - strcpy(v.name,"SVHS"); - break; - default: - return -EINVAL; - break; - } - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel v; - - DEBUG("PlanB: IOCTL VIDIOCSCHAN\n"); - - if(copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - if (v.norm != pb->win.norm) { - int i, maxlines; - - switch (v.norm) - { - case VIDEO_MODE_PAL: - case VIDEO_MODE_SECAM: - maxlines = PLANB_MAXLINES; - break; - case VIDEO_MODE_NTSC: - maxlines = PLANB_NTSC_MAXLINES; - break; - default: - return -EINVAL; - break; - } - planb_lock(pb); - /* empty the grabbing queue */ - wait_event(pb->capq, !pb->grabbing); - pb->maxlines = maxlines; - pb->win.norm = v.norm; - /* Stop overlay if running */ - suspend_overlay(pb); - for(i = 0; i < MAX_GBUFFERS; i++) - pb->gnorm_switch[i] = 1; - /* I know it's an overkill, but.... */ - fill_cmd_buff(pb); - /* ok, now init it accordingly */ - saa_init_regs (pb); - /* restart overlay if it was running */ - resume_overlay(pb); - planb_unlock(pb); - } - - switch(v.channel) - { - case 0: /* Composite */ - saa_set (SAA7196_IOCC, - ((saa_regs[pb->win.norm][SAA7196_IOCC] & - ~7) | 3), pb); - break; - case 1: /* SVHS */ - saa_set (SAA7196_IOCC, - ((saa_regs[pb->win.norm][SAA7196_IOCC] & - ~7) | 4), pb); - break; - default: - return -EINVAL; - break; - } - - return 0; - } - case VIDIOCGPICT: - { - struct video_picture vp = pb->picture; - - DEBUG("PlanB: IOCTL VIDIOCGPICT\n"); - - switch(pb->win.color_fmt) { - case PLANB_GRAY: - vp.palette = VIDEO_PALETTE_GREY; - case PLANB_COLOUR15: - vp.palette = VIDEO_PALETTE_RGB555; - break; - case PLANB_COLOUR32: - vp.palette = VIDEO_PALETTE_RGB32; - break; - default: - vp.palette = 0; - break; - } - - if(copy_to_user(arg,&vp,sizeof(vp))) - return -EFAULT; - return 0; - } - case VIDIOCSPICT: - { - struct video_picture vp; - - DEBUG("PlanB: IOCTL VIDIOCSPICT\n"); - - if(copy_from_user(&vp,arg,sizeof(vp))) - return -EFAULT; - pb->picture = vp; - /* Should we do sanity checks here? */ - saa_set (SAA7196_BRIG, (unsigned char) - ((pb->picture.brightness) >> 8), pb); - saa_set (SAA7196_HUEC, (unsigned char) - ((pb->picture.hue) >> 8) ^ 0x80, pb); - saa_set (SAA7196_CSAT, (unsigned char) - ((pb->picture.colour) >> 9), pb); - saa_set (SAA7196_CONT, (unsigned char) - ((pb->picture.contrast) >> 9), pb); - - return 0; - } - case VIDIOCSWIN: - { - struct video_window vw; - struct video_clip clip; - int i; - - DEBUG("PlanB: IOCTL VIDIOCSWIN\n"); - - if(copy_from_user(&vw,arg,sizeof(vw))) - return -EFAULT; - - planb_lock(pb); - /* Stop overlay if running */ - suspend_overlay(pb); - pb->win.interlace = (vw.height > pb->maxlines/2)? 1: 0; - if (pb->win.x != vw.x || - pb->win.y != vw.y || - pb->win.width != vw.width || - pb->win.height != vw.height || - !pb->cmd_buff_inited) { - pb->win.x = vw.x; - pb->win.y = vw.y; - pb->win.width = vw.width; - pb->win.height = vw.height; - fill_cmd_buff(pb); - } - /* Reset clip mask */ - memset ((void *) pb->mask, 0xff, (pb->maxlines - * ((PLANB_MAXPIXELS + 7) & ~7)) / 8); - /* Add any clip rects */ - for (i = 0; i < vw.clipcount; i++) { - if (copy_from_user(&clip, vw.clips + i, - sizeof(struct video_clip))) - return -EFAULT; - add_clip(pb, &clip); - } - /* restart overlay if it was running */ - resume_overlay(pb); - planb_unlock(pb); - return 0; - } - case VIDIOCGWIN: - { - struct video_window vw; - - DEBUG("PlanB: IOCTL VIDIOCGWIN\n"); - - vw.x=pb->win.x; - vw.y=pb->win.y; - vw.width=pb->win.width; - vw.height=pb->win.height; - vw.chromakey=0; - vw.flags=0; - if(pb->win.interlace) - vw.flags|=VIDEO_WINDOW_INTERLACE; - if(copy_to_user(arg,&vw,sizeof(vw))) - return -EFAULT; - return 0; - } - case VIDIOCSYNC: { - int i; - - IDEBUG("PlanB: IOCTL VIDIOCSYNC\n"); - - if(copy_from_user((void *)&i,arg,sizeof(int))) - return -EFAULT; - - IDEBUG("PlanB: sync to frame %d\n", i); - - if(i > (MAX_GBUFFERS - 1) || i < 0) - return -EINVAL; -chk_grab: - switch (pb->frame_stat[i]) { - case GBUFFER_UNUSED: - return -EINVAL; - case GBUFFER_GRABBING: - IDEBUG("PlanB: waiting for grab" - " done (%d)\n", i); - interruptible_sleep_on(&pb->capq); - if(signal_pending(current)) - return -EINTR; - goto chk_grab; - case GBUFFER_DONE: - pb->frame_stat[i] = GBUFFER_UNUSED; - break; - } - return 0; - } - - case VIDIOCMCAPTURE: - { - struct video_mmap vm; - volatile unsigned int status; - - IDEBUG("PlanB: IOCTL VIDIOCMCAPTURE\n"); - - if(copy_from_user((void *) &vm,(void *)arg,sizeof(vm))) - return -EFAULT; - status = pb->frame_stat[vm.frame]; - if (status != GBUFFER_UNUSED) - return -EBUSY; - - return vgrab(pb, &vm); - } - - case VIDIOCGMBUF: - { - int i; - struct video_mbuf vm; - - DEBUG("PlanB: IOCTL VIDIOCGMBUF\n"); - - memset(&vm, 0 , sizeof(vm)); - vm.size = PLANB_MAX_FBUF * MAX_GBUFFERS; - vm.frames = MAX_GBUFFERS; - for(i = 0; i= SAA7196_NUMREGS) - return -EINVAL; - preg.val = saa_regs[pb->win.norm][preg.addr]; - if(copy_to_user((void *)arg, (void *)&preg, - sizeof(preg))) - return -EFAULT; - return 0; - } - - case PLANBIOCSSAAREGS: - { - struct planb_saa_regs preg; - - DEBUG("PlanB: IOCTL PLANBIOCSSAAREGS\n"); - - if(copy_from_user(&preg, arg, sizeof(preg))) - return -EFAULT; - if(preg.addr >= SAA7196_NUMREGS) - return -EINVAL; - saa_set (preg.addr, preg.val, pb); - return 0; - } - - case PLANBIOCGSTAT: - { - struct planb_stat_regs pstat; - - DEBUG("PlanB: IOCTL PLANBIOCGSTAT\n"); - - pstat.ch1_stat = in_le32(&pb->planb_base->ch1.status); - pstat.ch2_stat = in_le32(&pb->planb_base->ch2.status); - pstat.saa_stat0 = saa_status(0, pb); - pstat.saa_stat1 = saa_status(1, pb); - - if(copy_to_user((void *)arg, (void *)&pstat, - sizeof(pstat))) - return -EFAULT; - return 0; - } - - case PLANBIOCSMODE: { - int v; - - DEBUG("PlanB: IOCTL PLANBIOCSMODE\n"); - - if(copy_from_user(&v, arg, sizeof(v))) - return -EFAULT; - - switch(v) - { - case PLANB_TV_MODE: - saa_set (SAA7196_STDC, - (saa_regs[pb->win.norm][SAA7196_STDC] & - 0x7f), pb); - break; - case PLANB_VTR_MODE: - saa_set (SAA7196_STDC, - (saa_regs[pb->win.norm][SAA7196_STDC] | - 0x80), pb); - break; - default: - return -EINVAL; - break; - } - pb->win.mode = v; - return 0; - } - case PLANBIOCGMODE: { - int v=pb->win.mode; - - DEBUG("PlanB: IOCTL PLANBIOCGMODE\n"); - - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - return 0; - } -#ifdef PLANB_GSCANLINE - case PLANBG_GRAB_BPL: { - int v=pb->gbytes_per_line; - - DEBUG("PlanB: IOCTL PLANBG_GRAB_BPL\n"); - - if(copy_to_user(arg,&v,sizeof(v))) - return -EFAULT; - return 0; - } -#endif /* PLANB_GSCANLINE */ - case PLANB_INTR_DEBUG: { - int i; - - DEBUG("PlanB: IOCTL PLANB_INTR_DEBUG\n"); - - if(copy_from_user(&i, arg, sizeof(i))) - return -EFAULT; - - /* avoid hang ups all together */ - for (i = 0; i < MAX_GBUFFERS; i++) { - if(pb->frame_stat[i] == GBUFFER_GRABBING) { - pb->frame_stat[i] = GBUFFER_DONE; - } - } - if(pb->grabbing) - pb->grabbing--; - wake_up_interruptible(&pb->capq); - return 0; - } - case PLANB_INV_REGS: { - int i; - struct planb_any_regs any; - - DEBUG("PlanB: IOCTL PLANB_INV_REGS\n"); - - if(copy_from_user(&any, arg, sizeof(any))) - return -EFAULT; - if(any.offset < 0 || any.offset + any.bytes > 0x400) - return -EINVAL; - if(any.bytes > 128) - return -EINVAL; - for (i = 0; i < any.bytes; i++) { - any.data[i] = - in_8((unsigned char *)pb->planb_base - + any.offset + i); - } - if(copy_to_user(arg,&any,sizeof(any))) - return -EFAULT; - return 0; - } - default: - { - DEBUG("PlanB: Unimplemented IOCTL\n"); - return -ENOIOCTLCMD; - } - /* Some IOCTLs are currently unsupported on PlanB */ - case VIDIOCGTUNER: { - DEBUG("PlanB: IOCTL VIDIOCGTUNER\n"); - goto unimplemented; } - case VIDIOCSTUNER: { - DEBUG("PlanB: IOCTL VIDIOCSTUNER\n"); - goto unimplemented; } - case VIDIOCSFREQ: { - DEBUG("PlanB: IOCTL VIDIOCSFREQ\n"); - goto unimplemented; } - case VIDIOCGFREQ: { - DEBUG("PlanB: IOCTL VIDIOCGFREQ\n"); - goto unimplemented; } - case VIDIOCKEY: { - DEBUG("PlanB: IOCTL VIDIOCKEY\n"); - goto unimplemented; } - case VIDIOCSAUDIO: { - DEBUG("PlanB: IOCTL VIDIOCSAUDIO\n"); - goto unimplemented; } - case VIDIOCGAUDIO: { - DEBUG("PlanB: IOCTL VIDIOCGAUDIO\n"); - goto unimplemented; } -unimplemented: - DEBUG(" Unimplemented\n"); - return -ENOIOCTLCMD; - } - return 0; -} - -static int planb_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size) -{ - int i; - struct planb *pb = (struct planb *)dev; - unsigned long start = (unsigned long)adr; - - if (size > MAX_GBUFFERS * PLANB_MAX_FBUF) - return -EINVAL; - if (!pb->rawbuf) { - int err; - if((err=grabbuf_alloc(pb))) - return err; - } - for (i = 0; i < pb->rawbuf_size; i++) { - unsigned long pfn; - - pfn = virt_to_phys((void *)pb->rawbuf[i]) >> PAGE_SHIFT; - if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - start += PAGE_SIZE; - if (size <= PAGE_SIZE) - break; - size -= PAGE_SIZE; - } - return 0; -} - -static struct video_device planb_template= -{ - .owner = THIS_MODULE, - .name = PLANB_DEVICE_NAME, - .type = VID_TYPE_OVERLAY, - .open = planb_open, - .close = planb_close, - .read = planb_read, - .write = planb_write, - .ioctl = planb_ioctl, - .mmap = planb_mmap, /* mmap? */ -}; - -static int init_planb(struct planb *pb) -{ - unsigned char saa_rev; - int i, result; - - memset ((void *) &pb->win, 0, sizeof (struct planb_window)); - /* Simple sanity check */ - if(def_norm >= NUM_SUPPORTED_NORM || def_norm < 0) { - printk(KERN_ERR "PlanB: Option(s) invalid\n"); - return -2; - } - pb->win.norm = def_norm; - pb->win.mode = PLANB_TV_MODE; /* TV mode */ - pb->win.interlace=1; - pb->win.x=0; - pb->win.y=0; - pb->win.width=768; /* 640 */ - pb->win.height=576; /* 480 */ - pb->maxlines=576; -#if 0 - btv->win.cropwidth=768; /* 640 */ - btv->win.cropheight=576; /* 480 */ - btv->win.cropx=0; - btv->win.cropy=0; -#endif - pb->win.pad=0; - pb->win.bpp=4; - pb->win.depth=32; - pb->win.color_fmt=PLANB_COLOUR32; - pb->win.bpl=1024*pb->win.bpp; - pb->win.swidth=1024; - pb->win.sheight=768; -#ifdef PLANB_GSCANLINE - if((pb->gbytes_per_line = PLANB_MAXPIXELS * 4) > PAGE_SIZE - || (pb->gbytes_per_line <= 0)) - return -3; - else { - /* page align pb->gbytes_per_line for DMA purpose */ - for(i = PAGE_SIZE; pb->gbytes_per_line < (i>>1);) - i>>=1; - pb->gbytes_per_line = i; - } -#endif - pb->tab_size = PLANB_MAXLINES + 40; - pb->suspend = 0; - mutex_init(&pb->lock); - pb->ch1_cmd = 0; - pb->ch2_cmd = 0; - pb->mask = 0; - pb->priv_space = 0; - pb->offset = 0; - pb->user = 0; - pb->overlay = 0; - init_waitqueue_head(&pb->suspendq); - pb->cmd_buff_inited = 0; - pb->frame_buffer_phys = 0; - - /* Reset DMA controllers */ - planb_dbdma_stop(&pb->planb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - saa_rev = (saa_status(0, pb) & 0xf0) >> 4; - printk(KERN_INFO "PlanB: SAA7196 video processor rev. %d\n", saa_rev); - /* Initialize the SAA registers in memory and on chip */ - saa_init_regs (pb); - - /* clear interrupt mask */ - pb->intr_mask = PLANB_CLR_IRQ; - - result = request_irq(pb->irq, planb_irq, 0, "PlanB", pb); - if (result < 0) { - if (result==-EINVAL) - printk(KERN_ERR "PlanB: Bad irq number (%d) " - "or handler\n", (int)pb->irq); - else if (result==-EBUSY) - printk(KERN_ERR "PlanB: I don't know why, " - "but IRQ %d is busy\n", (int)pb->irq); - return result; - } - disable_irq(pb->irq); - - /* Now add the template and register the device unit. */ - memcpy(&pb->video_dev,&planb_template,sizeof(planb_template)); - - pb->picture.brightness=0x90<<8; - pb->picture.contrast = 0x70 << 8; - pb->picture.colour = 0x70<<8; - pb->picture.hue = 0x8000; - pb->picture.whiteness = 0; - pb->picture.depth = pb->win.depth; - - pb->frame_stat=NULL; - init_waitqueue_head(&pb->capq); - for(i=0; igbuf_idx[i] = PLANB_MAX_FBUF * i / PAGE_SIZE; - pb->gwidth[i]=0; - pb->gheight[i]=0; - pb->gfmt[i]=0; - pb->cap_cmd[i]=NULL; -#ifndef PLANB_GSCANLINE - pb->l_fr_addr_idx[i] = MAX_GBUFFERS * (PLANB_MAX_FBUF - / PAGE_SIZE + 1) + MAX_LNUM * i; - pb->lsize[i] = 0; - pb->lnum[i] = 0; -#endif - } - pb->rawbuf=NULL; - pb->grabbing=0; - - /* enable interrupts */ - out_le32(&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - pb->intr_mask = PLANB_FRM_IRQ; - enable_irq(pb->irq); - - if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0) - return -1; - - return 0; -} - -/* - * Scan for a PlanB controller, request the irq and map the io memory - */ - -static int find_planb(void) -{ - struct planb *pb; - struct device_node *planb_devices; - unsigned char dev_fn, confreg, bus; - unsigned int old_base, new_base; - unsigned int irq; - struct pci_dev *pdev; - int rc; - - if (!machine_is(powermac)) - return 0; - - planb_devices = of_find_node_by_name(NULL, "planb"); - if (planb_devices == 0) { - planb_num=0; - printk(KERN_WARNING "PlanB: no device found!\n"); - return planb_num; - } - - if (planb_devices->next != NULL) - printk(KERN_ERR "Warning: only using first PlanB device!\n"); - pb = &planbs[0]; - planb_num = 1; - - if (planb_devices->n_addrs != 1) { - printk (KERN_WARNING "PlanB: expecting 1 address for planb " - "(got %d)", planb_devices->n_addrs); - of_node_put(planb_devices); - return 0; - } - - if (planb_devices->n_intrs == 0) { - printk(KERN_WARNING "PlanB: no intrs for device %s\n", - planb_devices->full_name); - of_node_put(planb_devices); - return 0; - } else { - irq = planb_devices->intrs[0].line; - } - - /* Initialize PlanB's PCI registers */ - - /* There is a bug with the way OF assigns addresses - to the devices behind the chaos bridge. - control needs only 0x1000 of space, but decodes only - the upper 16 bits. It therefore occupies a full 64K. - OF assigns the planb controller memory within this space; - so we need to change that here in order to access planb. */ - - /* We remap to 0xf1000000 in hope that nobody uses it ! */ - - bus = (planb_devices->addrs[0].space >> 16) & 0xff; - dev_fn = (planb_devices->addrs[0].space >> 8) & 0xff; - confreg = planb_devices->addrs[0].space & 0xff; - old_base = planb_devices->addrs[0].address; - new_base = 0xf1000000; - of_node_put(planb_devices); - - DEBUG("PlanB: Found on bus %d, dev %d, func %d, " - "membase 0x%x (base reg. 0x%x)\n", - bus, PCI_SLOT(dev_fn), PCI_FUNC(dev_fn), old_base, confreg); - - pdev = pci_get_bus_and_slot(bus, dev_fn); - if (!pdev) { - printk(KERN_ERR "planb: cannot find slot\n"); - goto err_out; - } - - /* Enable response in memory space, bus mastering, - use memory write and invalidate */ - rc = pci_enable_device(pdev); - if (rc) { - printk(KERN_ERR "planb: cannot enable PCI device %s\n", - pci_name(pdev)); - goto err_out; - } - rc = pci_set_mwi(pdev); - if (rc) { - printk(KERN_ERR "planb: cannot enable MWI on PCI device %s\n", - pci_name(pdev)); - goto err_out_disable; - } - pci_set_master(pdev); - - /* Set the new base address */ - pci_write_config_dword (pdev, confreg, new_base); - - planb_regs = (volatile struct planb_registers *) - ioremap (new_base, 0x400); - pb->planb_base = planb_regs; - pb->planb_base_phys = (struct planb_registers *)new_base; - pb->irq = irq; - pb->dev = pdev; - - return planb_num; - -err_out_disable: - pci_disable_device(pdev); -err_out: - /* FIXME handle error */ /* comment moved from pci_find_slot, above */ - pci_dev_put(pdev); - return 0; -} - -static void release_planb(void) -{ - int i; - struct planb *pb; - - for (i=0;iplanb_base->ch2); - planb_dbdma_stop(&pb->planb_base->ch1); - - /* clear and free interrupts */ - pb->intr_mask = PLANB_CLR_IRQ; - out_le32 (&pb->planb_base->intr_stat, PLANB_CLR_IRQ); - free_irq(pb->irq, pb); - - /* make sure all allocated memory are freed */ - planb_prepare_close(pb); - - printk(KERN_INFO "PlanB: unregistering with v4l\n"); - video_unregister_device(&pb->video_dev); - - pci_dev_put(pb->dev); - - /* note that iounmap() does nothing on the PPC right now */ - iounmap ((void *)pb->planb_base); - } -} - -static int __init init_planbs(void) -{ - int i; - - if (find_planb()<=0) - return -EIO; - - for (i=0; i -#include "saa7196.h" -#endif /* __KERNEL__ */ - -#define PLANB_DEVICE_NAME "Apple PlanB Video-In" -#define PLANB_REV "1.0" - -#ifdef __KERNEL__ -//#define PLANB_GSCANLINE /* use this if apps have the notion of */ - /* grab buffer scanline */ -/* This should be safe for both PAL and NTSC */ -#define PLANB_MAXPIXELS 768 -#define PLANB_MAXLINES 576 -#define PLANB_NTSC_MAXLINES 480 - -/* Uncomment your preferred norm ;-) */ -#define PLANB_DEF_NORM VIDEO_MODE_PAL -//#define PLANB_DEF_NORM VIDEO_MODE_NTSC -//#define PLANB_DEF_NORM VIDEO_MODE_SECAM - -/* fields settings */ -#define PLANB_GRAY 0x1 /* 8-bit mono? */ -#define PLANB_COLOUR15 0x2 /* 16-bit mode */ -#define PLANB_COLOUR32 0x4 /* 32-bit mode */ -#define PLANB_CLIPMASK 0x8 /* hardware clipmasking */ - -/* misc. flags for PlanB DMA operation */ -#define CH_SYNC 0x1 /* synchronize channels (set by ch1; - cleared by ch2) */ -#define FIELD_SYNC 0x2 /* used for the start of each field - (0 -> 1 -> 0 for ch1; 0 -> 1 for ch2) */ -#define EVEN_FIELD 0x0 /* even field is detected if unset */ -#define DMA_ABORT 0x2 /* error or just out of sync if set */ -#define ODD_FIELD 0x4 /* odd field is detected if set */ - -/* for capture operations */ -#define MAX_GBUFFERS 2 -/* note PLANB_MAX_FBUF must be divisible by PAGE_SIZE */ -#ifdef PLANB_GSCANLINE -#define PLANB_MAX_FBUF 0x240000 /* 576 * 1024 * 4 */ -#define TAB_FACTOR (1) -#else -#define PLANB_MAX_FBUF 0x1b0000 /* 576 * 768 * 4 */ -#define TAB_FACTOR (2) -#endif -#endif /* __KERNEL__ */ - -struct planb_saa_regs { - unsigned char addr; - unsigned char val; -}; - -struct planb_stat_regs { - unsigned int ch1_stat; - unsigned int ch2_stat; - unsigned char saa_stat0; - unsigned char saa_stat1; -}; - -struct planb_any_regs { - unsigned int offset; - unsigned int bytes; - unsigned char data[128]; -}; - -/* planb private ioctls */ -#define PLANBIOCGSAAREGS _IOWR('v', BASE_VIDIOCPRIVATE, struct planb_saa_regs) /* Read a saa7196 reg value */ -#define PLANBIOCSSAAREGS _IOW('v', BASE_VIDIOCPRIVATE + 1, struct planb_saa_regs) /* Set a saa7196 reg value */ -#define PLANBIOCGSTAT _IOR('v', BASE_VIDIOCPRIVATE + 2, struct planb_stat_regs) /* Read planb status */ -#define PLANB_TV_MODE 1 -#define PLANB_VTR_MODE 2 -#define PLANBIOCGMODE _IOR('v', BASE_VIDIOCPRIVATE + 3, int) /* Get TV/VTR mode */ -#define PLANBIOCSMODE _IOW('v', BASE_VIDIOCPRIVATE + 4, int) /* Set TV/VTR mode */ - -#ifdef PLANB_GSCANLINE -#define PLANBG_GRAB_BPL _IOR('v', BASE_VIDIOCPRIVATE + 5, int) /* # of bytes per scanline in grab buffer */ -#endif - -/* call wake_up_interruptible() with appropriate actions */ -#define PLANB_INTR_DEBUG _IOW('v', BASE_VIDIOCPRIVATE + 20, int) -/* investigate which reg does what */ -#define PLANB_INV_REGS _IOWR('v', BASE_VIDIOCPRIVATE + 21, struct planb_any_regs) - -#ifdef __KERNEL__ - -/* Potentially useful macros */ -#define PLANB_SET(x) ((x) << 16 | (x)) -#define PLANB_CLR(x) ((x) << 16) - -/* This represents the physical register layout */ -struct planb_registers { - volatile struct dbdma_regs ch1; /* 0x00: video in */ - volatile unsigned int even; /* 0x40: even field setting */ - volatile unsigned int odd; /* 0x44; odd field setting */ - unsigned int pad1[14]; /* empty? */ - volatile struct dbdma_regs ch2; /* 0x80: clipmask out */ - unsigned int pad2[16]; /* 0xc0: empty? */ - volatile unsigned int reg3; /* 0x100: ???? */ - volatile unsigned int intr_stat; /* 0x104: irq status */ -#define PLANB_CLR_IRQ 0x00 /* clear Plan B interrupt */ -#define PLANB_GEN_IRQ 0x01 /* assert Plan B interrupt */ -#define PLANB_FRM_IRQ 0x0100 /* end of frame */ - unsigned int pad3[1]; /* empty? */ - volatile unsigned int reg5; /* 0x10c: ??? */ - unsigned int pad4[60]; /* empty? */ - volatile unsigned char saa_addr; /* 0x200: SAA subadr */ - char pad5[3]; - volatile unsigned char saa_regval; /* SAA7196 write reg. val */ - char pad6[3]; - volatile unsigned char saa_status; /* SAA7196 status byte */ - /* There is more unused stuff here */ -}; - -struct planb_window { - int x, y; - ushort width, height; - ushort bpp, bpl, depth, pad; - ushort swidth, sheight; - int norm; - int interlace; - u32 color_fmt; - int chromakey; - int mode; /* used to switch between TV/VTR modes */ -}; - -struct planb_suspend { - int overlay; - int frame; - struct dbdma_cmd cmd; -}; - -struct planb { - struct video_device video_dev; - struct video_picture picture; /* Current picture params */ - struct video_audio audio_dev; /* Current audio params */ - - volatile struct planb_registers *planb_base; /* virt base of planb */ - struct planb_registers *planb_base_phys; /* phys base of planb */ - void *priv_space; /* Org. alloc. mem for kfree */ - int user; - unsigned int tab_size; - int maxlines; - struct mutex lock; - unsigned int irq; /* interrupt number */ - volatile unsigned int intr_mask; - struct pci_dev *dev; /* Our PCI device */ - - int overlay; /* overlay running? */ - struct planb_window win; - unsigned long frame_buffer_phys; /* We need phys for DMA */ - int offset; /* offset of pixel 1 */ - volatile struct dbdma_cmd *ch1_cmd; /* Video In DMA cmd buffer */ - volatile struct dbdma_cmd *ch2_cmd; /* Clip Out DMA cmd buffer */ - volatile struct dbdma_cmd *overlay_last1; - volatile struct dbdma_cmd *overlay_last2; - unsigned long ch1_cmd_phys; - volatile unsigned char *mask; /* Clipmask buffer */ - int suspend; - wait_queue_head_t suspendq; - struct planb_suspend suspended; - int cmd_buff_inited; /* cmd buffer inited? */ - - int grabbing; - unsigned int gcount; - wait_queue_head_t capq; - int last_fr; - int prev_last_fr; - unsigned char **rawbuf; - int rawbuf_size; - int gbuf_idx[MAX_GBUFFERS]; - volatile struct dbdma_cmd *cap_cmd[MAX_GBUFFERS]; - volatile struct dbdma_cmd *last_cmd[MAX_GBUFFERS]; - volatile struct dbdma_cmd *pre_cmd[MAX_GBUFFERS]; - int need_pre_capture[MAX_GBUFFERS]; -#define PLANB_DUMMY 40 /* # of command buf's allocated for pre-capture seq. */ - int gwidth[MAX_GBUFFERS], gheight[MAX_GBUFFERS]; - unsigned int gfmt[MAX_GBUFFERS]; - int gnorm_switch[MAX_GBUFFERS]; - volatile unsigned int *frame_stat; -#define GBUFFER_UNUSED 0x00U -#define GBUFFER_GRABBING 0x01U -#define GBUFFER_DONE 0x02U -#ifdef PLANB_GSCANLINE - int gbytes_per_line; -#else -#define MAX_LNUM 431 /* change this if PLANB_MAXLINES or */ - /* PLANB_MAXPIXELS changes */ - int l_fr_addr_idx[MAX_GBUFFERS]; - unsigned char *l_to_addr[MAX_GBUFFERS][MAX_LNUM]; - int l_to_next_idx[MAX_GBUFFERS][MAX_LNUM]; - int l_to_next_size[MAX_GBUFFERS][MAX_LNUM]; - int lsize[MAX_GBUFFERS], lnum[MAX_GBUFFERS]; -#endif -}; - -#endif /* __KERNEL__ */ - -#endif /* _PLANB_H_ */ diff --git a/drivers/media/video/saa7196.h b/drivers/media/video/saa7196.h index cd4b6354a7b3..e69de29bb2d1 100644 --- a/drivers/media/video/saa7196.h +++ b/drivers/media/video/saa7196.h @@ -1,117 +0,0 @@ -/* - Definitions for the Philips SAA7196 digital video decoder, - scaler, and clock generator circuit (DESCpro), as used in - the PlanB video input of the Powermac 7x00/8x00 series. - - Copyright (C) 1998 Michel Lanners (mlan@cpu.lu) - - The register defines are shamelessly copied from the meteor - driver out of NetBSD (with permission), - and are copyrighted (c) 1995 Mark Tinguely and Jim Lowe - (Thanks !) - - Additional debugging and coding by Takashi Oe (toe@unlinfo.unl.edu) - - The default values used for PlanB are my mistakes. -*/ - -/* $Id: saa7196.h,v 1.5 1999/03/26 23:28:47 mlan Exp $ */ - -#ifndef _SAA7196_H_ -#define _SAA7196_H_ - -#define SAA7196_NUMREGS 0x31 /* Number of registers (used)*/ -#define NUM_SUPPORTED_NORM 3 /* Number of supported norms by PlanB */ - -/* Decoder part: */ -#define SAA7196_IDEL 0x00 /* Increment delay */ -#define SAA7196_HSB5 0x01 /* H-sync begin; 50 hz */ -#define SAA7196_HSS5 0x02 /* H-sync stop; 50 hz */ -#define SAA7196_HCB5 0x03 /* H-clamp begin; 50 hz */ -#define SAA7196_HCS5 0x04 /* H-clamp stop; 50 hz */ -#define SAA7196_HSP5 0x05 /* H-sync after PHI1; 50 hz */ -#define SAA7196_LUMC 0x06 /* Luminance control */ -#define SAA7196_HUEC 0x07 /* Hue control */ -#define SAA7196_CKTQ 0x08 /* Colour Killer Threshold QAM (PAL, NTSC) */ -#define SAA7196_CKTS 0x09 /* Colour Killer Threshold SECAM */ -#define SAA7196_PALS 0x0a /* PAL switch sensitivity */ -#define SAA7196_SECAMS 0x0b /* SECAM switch sensitivity */ -#define SAA7196_CGAINC 0x0c /* Chroma gain control */ -#define SAA7196_STDC 0x0d /* Standard/Mode control */ -#define SAA7196_IOCC 0x0e /* I/O and Clock Control */ -#define SAA7196_CTRL1 0x0f /* Control #1 */ -#define SAA7196_CTRL2 0x10 /* Control #2 */ -#define SAA7196_CGAINR 0x11 /* Chroma Gain Reference */ -#define SAA7196_CSAT 0x12 /* Chroma Saturation */ -#define SAA7196_CONT 0x13 /* Luminance Contrast */ -#define SAA7196_HSB6 0x14 /* H-sync begin; 60 hz */ -#define SAA7196_HSS6 0x15 /* H-sync stop; 60 hz */ -#define SAA7196_HCB6 0x16 /* H-clamp begin; 60 hz */ -#define SAA7196_HCS6 0x17 /* H-clamp stop; 60 hz */ -#define SAA7196_HSP6 0x18 /* H-sync after PHI1; 60 hz */ -#define SAA7196_BRIG 0x19 /* Luminance Brightness */ - -/* Scaler part: */ -#define SAA7196_FMTS 0x20 /* Formats and sequence */ -#define SAA7196_OUTPIX 0x21 /* Output data pixel/line */ -#define SAA7196_INPIX 0x22 /* Input data pixel/line */ -#define SAA7196_HWS 0x23 /* Horiz. window start */ -#define SAA7196_HFILT 0x24 /* Horiz. filter */ -#define SAA7196_OUTLINE 0x25 /* Output data lines/field */ -#define SAA7196_INLINE 0x26 /* Input data lines/field */ -#define SAA7196_VWS 0x27 /* Vertical window start */ -#define SAA7196_VYP 0x28 /* AFS/vertical Y processing */ -#define SAA7196_VBS 0x29 /* Vertical Bypass start */ -#define SAA7196_VBCNT 0x2a /* Vertical Bypass count */ -#define SAA7196_VBP 0x2b /* veritcal Bypass Polarity */ -#define SAA7196_VLOW 0x2c /* Colour-keying lower V limit */ -#define SAA7196_VHIGH 0x2d /* Colour-keying upper V limit */ -#define SAA7196_ULOW 0x2e /* Colour-keying lower U limit */ -#define SAA7196_UHIGH 0x2f /* Colour-keying upper U limit */ -#define SAA7196_DPATH 0x30 /* Data path setting */ - -/* Initialization default values: */ - -unsigned char saa_regs[NUM_SUPPORTED_NORM][SAA7196_NUMREGS] = { - -/* PAL, 768x576 (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff, - 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x06, 0x3b, 0x98, - 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0xa2, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12, - 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 }, - -/* NTSC, 640x480? (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x50, 0x00, - 0xf8, 0xf0, 0xfe, 0xe0, 0x00, 0x06, 0x3b, 0x98, - 0x00, 0x2c, 0x3d, 0x40, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0x98, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x80, 0x03, 0x89, 0xf0, 0xf0, 0x0d, - 0xa0, 0x0d, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 }, - -/* SECAM, 768x576 (no scaling), composite video-in */ -/* Decoder: */ - { 0x50, 0x30, 0x00, 0xe8, 0xb6, 0xe5, 0x63, 0xff, - 0xfe, 0xf0, 0xfe, 0xe0, 0x20, 0x07, 0x3b, 0x98, - 0x00, 0x59, 0x41, 0x45, 0x34, 0x0a, 0xf4, 0xd2, - 0xe9, 0xa2, -/* Padding */ - 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -/* Scaler: */ - 0x72, 0x80, 0x00, 0x03, 0x8d, 0x20, 0x20, 0x12, - 0xa5, 0x12, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x87 } - }; - -#endif /* _SAA7196_H_ */ -- cgit v1.2.3 From 33b687cf1df62bd83167616516922b4e472be662 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 05:32:50 -0300 Subject: V4L/DVB (8487): videodev: replace videodev.h includes by videodev2.h where possible Several V4L2 drivers still included videodev.h. Fix this. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cs53l32a.c | 2 +- drivers/media/video/m52790.c | 2 +- drivers/media/video/msp3400-driver.c | 1 - drivers/media/video/msp3400-kthreads.c | 1 - drivers/media/video/saa717x.c | 1 - drivers/media/video/tda7432.c | 2 +- drivers/media/video/tda9875.c | 2 +- drivers/media/video/tlv320aic23b.c | 2 +- drivers/media/video/tveeprom.c | 2 +- drivers/media/video/tvp5150.c | 2 +- drivers/media/video/v4l2-common.c | 2 +- drivers/media/video/vino.c | 2 +- drivers/media/video/vp27smpx.c | 2 +- drivers/media/video/vpx3220.c | 2 +- drivers/media/video/w9966.c | 2 +- drivers/media/video/w9968cf.h | 2 +- drivers/media/video/wm8739.c | 2 +- drivers/media/video/wm8775.c | 2 +- 18 files changed, 15 insertions(+), 18 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c index 645b339152d3..e30a589c0e18 100644 --- a/drivers/media/video/cs53l32a.c +++ b/drivers/media/video/cs53l32a.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 39bf6b114d50..89a781c6929d 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index 780531b587a4..3da74dcee902 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/msp3400-kthreads.c b/drivers/media/video/msp3400-kthreads.c index 1622f70e4dd0..846a14a61fd1 100644 --- a/drivers/media/video/msp3400-kthreads.c +++ b/drivers/media/video/msp3400-kthreads.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c index 2220f9569941..af60ede5310d 100644 --- a/drivers/media/video/saa717x.c +++ b/drivers/media/video/saa717x.c @@ -35,7 +35,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c index 2fda40c0f255..4963d4264880 100644 --- a/drivers/media/video/tda7432.c +++ b/drivers/media/video/tda7432.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c index 7a8ce8fb46dc..792f0b079909 100644 --- a/drivers/media/video/tda9875.c +++ b/drivers/media/video/tda9875.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c index 9220378a5637..281065b9dd2d 100644 --- a/drivers/media/video/tlv320aic23b.c +++ b/drivers/media/video/tlv320aic23b.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index fbfac1b3bd02..bcc32fa92a81 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index 6a3af1005f03..28af5ce5560d 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index e9dd996fd5df..88ca13104417 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -64,7 +64,7 @@ #include #endif -#include +#include MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr"); MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers"); diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 01ea99c9bc1a..f0fcb008b723 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -38,7 +38,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c index cbecb3cbbbaa..577956c5410b 100644 --- a/drivers/media/video/vp27smpx.c +++ b/drivers/media/video/vp27smpx.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 35293029da02..3b83d4e2b2c3 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -33,7 +33,7 @@ #define I2C_NAME(x) (x)->name -#include +#include #include #include diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 1641998c73e6..925b4e7b557d 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h index 3c95316bc030..30032e15e23c 100644 --- a/drivers/media/video/w9968cf.h +++ b/drivers/media/video/w9968cf.h @@ -21,7 +21,7 @@ #ifndef _W9968CF_H_ #define _W9968CF_H_ -#include +#include #include #include #include diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c index 7be47a255853..95c79ad80487 100644 --- a/drivers/media/video/wm8739.c +++ b/drivers/media/video/wm8739.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index c2ab70a04a74..48df661d4fc3 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From f894dfd735237548d282d6fd55b6ebb4b2fd9ef2 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 25 Jul 2008 07:39:54 -0300 Subject: V4L/DVB (8488): videodev: remove some CONFIG_VIDEO_V4L1_COMPAT code from v4l2-dev.h The video_device_create_file and video_device_remove_file functions can be removed from v4l2-dev.h, removing the dependency on videodev.h in v4l2-dev.h. Also removed a few more videodev.h includes that should have been videodev2.h. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/tda9887.c | 2 +- drivers/media/common/tuners/tuner-simple.c | 2 +- drivers/media/video/cpia2/cpia2_core.c | 1 + drivers/media/video/ov511.c | 34 +++++++++--------- drivers/media/video/pwc/pwc-if.c | 11 +++--- drivers/media/video/stk-webcam.c | 14 ++++---- drivers/media/video/stv680.c | 47 +++++++++++++------------ drivers/media/video/usbvideo/vicam.c | 1 + drivers/media/video/usbvision/usbvision-core.c | 1 - drivers/media/video/usbvision/usbvision-video.c | 1 - drivers/media/video/vpx3220.c | 2 +- include/media/v4l2-dev.h | 25 ------------- 12 files changed, 60 insertions(+), 81 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c index a0545ba957b0..72abf0b73486 100644 --- a/drivers/media/common/tuners/tda9887.c +++ b/drivers/media/common/tuners/tda9887.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include "tuner-i2c.h" diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c index 266c255cf0d8..597e47f5d69c 100644 --- a/drivers/media/common/tuners/tuner-simple.c +++ b/drivers/media/common/tuners/tuner-simple.c @@ -6,7 +6,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c index f2e8b1c82c66..af8b9ec8e358 100644 --- a/drivers/media/video/cpia2/cpia2_core.c +++ b/drivers/media/video/cpia2/cpia2_core.c @@ -32,6 +32,7 @@ #include "cpia2.h" #include +#include #include #include diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index f732b035570f..2374ebc084d4 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -5660,43 +5660,43 @@ static int ov_create_sysfs(struct video_device *vdev) { int rc; - rc = video_device_create_file(vdev, &dev_attr_custom_id); + rc = device_create_file(&vdev->dev, &dev_attr_custom_id); if (rc) goto err; - rc = video_device_create_file(vdev, &dev_attr_model); + rc = device_create_file(&vdev->dev, &dev_attr_model); if (rc) goto err_id; - rc = video_device_create_file(vdev, &dev_attr_bridge); + rc = device_create_file(&vdev->dev, &dev_attr_bridge); if (rc) goto err_model; - rc = video_device_create_file(vdev, &dev_attr_sensor); + rc = device_create_file(&vdev->dev, &dev_attr_sensor); if (rc) goto err_bridge; - rc = video_device_create_file(vdev, &dev_attr_brightness); + rc = device_create_file(&vdev->dev, &dev_attr_brightness); if (rc) goto err_sensor; - rc = video_device_create_file(vdev, &dev_attr_saturation); + rc = device_create_file(&vdev->dev, &dev_attr_saturation); if (rc) goto err_bright; - rc = video_device_create_file(vdev, &dev_attr_contrast); + rc = device_create_file(&vdev->dev, &dev_attr_contrast); if (rc) goto err_sat; - rc = video_device_create_file(vdev, &dev_attr_hue); + rc = device_create_file(&vdev->dev, &dev_attr_hue); if (rc) goto err_contrast; - rc = video_device_create_file(vdev, &dev_attr_exposure); + rc = device_create_file(&vdev->dev, &dev_attr_exposure); if (rc) goto err_hue; return 0; err_hue: - video_device_remove_file(vdev, &dev_attr_hue); + device_remove_file(&vdev->dev, &dev_attr_hue); err_contrast: - video_device_remove_file(vdev, &dev_attr_contrast); + device_remove_file(&vdev->dev, &dev_attr_contrast); err_sat: - video_device_remove_file(vdev, &dev_attr_saturation); + device_remove_file(&vdev->dev, &dev_attr_saturation); err_bright: - video_device_remove_file(vdev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_brightness); err_sensor: - video_device_remove_file(vdev, &dev_attr_sensor); + device_remove_file(&vdev->dev, &dev_attr_sensor); err_bridge: - video_device_remove_file(vdev, &dev_attr_bridge); + device_remove_file(&vdev->dev, &dev_attr_bridge); err_model: - video_device_remove_file(vdev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_model); err_id: - video_device_remove_file(vdev, &dev_attr_custom_id); + device_remove_file(&vdev->dev, &dev_attr_custom_id); err: return rc; } diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 4625b265bf98..436a47caf52d 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1047,19 +1047,20 @@ static int pwc_create_sysfs_files(struct video_device *vdev) struct pwc_device *pdev = video_get_drvdata(vdev); int rc; - rc = video_device_create_file(vdev, &dev_attr_button); + rc = device_create_file(&vdev->dev, &dev_attr_button); if (rc) goto err; if (pdev->features & FEATURE_MOTOR_PANTILT) { - rc = video_device_create_file(vdev, &dev_attr_pan_tilt); + rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt); if (rc) goto err_button; } return 0; err_button: - video_device_remove_file(vdev, &dev_attr_button); + device_remove_file(&vdev->dev, &dev_attr_button); err: + PWC_ERROR("Could not create sysfs files.\n"); return rc; } @@ -1067,8 +1068,8 @@ static void pwc_remove_sysfs_files(struct video_device *vdev) { struct pwc_device *pdev = video_get_drvdata(vdev); if (pdev->features & FEATURE_MOTOR_PANTILT) - video_device_remove_file(vdev, &dev_attr_pan_tilt); - video_device_remove_file(vdev, &dev_attr_button); + device_remove_file(&vdev->dev, &dev_attr_pan_tilt); + device_remove_file(&vdev->dev, &dev_attr_button); } #ifdef CONFIG_USB_PWC_DEBUG diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 8d5fa95ad95a..8aa56fe02546 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -341,17 +341,19 @@ static int stk_create_sysfs_files(struct video_device *vdev) { int ret; - ret = video_device_create_file(vdev, &dev_attr_brightness); - ret += video_device_create_file(vdev, &dev_attr_hflip); - ret += video_device_create_file(vdev, &dev_attr_vflip); + ret = device_create_file(&vdev->dev, &dev_attr_brightness); + ret += device_create_file(&vdev->dev, &dev_attr_hflip); + ret += device_create_file(&vdev->dev, &dev_attr_vflip); + if (ret) + STK_WARNING("Could not create sysfs files\n"); return ret; } static void stk_remove_sysfs_files(struct video_device *vdev) { - video_device_remove_file(vdev, &dev_attr_brightness); - video_device_remove_file(vdev, &dev_attr_hflip); - video_device_remove_file(vdev, &dev_attr_vflip); + device_remove_file(&vdev->dev, &dev_attr_brightness); + device_remove_file(&vdev->dev, &dev_attr_hflip); + device_remove_file(&vdev->dev, &dev_attr_vflip); } #else diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index fdcb58b0c121..9053d5a0b1c3 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -525,53 +525,54 @@ static int stv680_create_sysfs_files(struct video_device *vdev) { int rc; - rc = video_device_create_file(vdev, &dev_attr_model); + rc = device_create_file(&vdev->dev, &dev_attr_model); if (rc) goto err; - rc = video_device_create_file(vdev, &dev_attr_in_use); + rc = device_create_file(&vdev->dev, &dev_attr_in_use); if (rc) goto err_model; - rc = video_device_create_file(vdev, &dev_attr_streaming); + rc = device_create_file(&vdev->dev, &dev_attr_streaming); if (rc) goto err_inuse; - rc = video_device_create_file(vdev, &dev_attr_palette); + rc = device_create_file(&vdev->dev, &dev_attr_palette); if (rc) goto err_stream; - rc = video_device_create_file(vdev, &dev_attr_frames_total); + rc = device_create_file(&vdev->dev, &dev_attr_frames_total); if (rc) goto err_pal; - rc = video_device_create_file(vdev, &dev_attr_frames_read); + rc = device_create_file(&vdev->dev, &dev_attr_frames_read); if (rc) goto err_framtot; - rc = video_device_create_file(vdev, &dev_attr_packets_dropped); + rc = device_create_file(&vdev->dev, &dev_attr_packets_dropped); if (rc) goto err_framread; - rc = video_device_create_file(vdev, &dev_attr_decoding_errors); + rc = device_create_file(&vdev->dev, &dev_attr_decoding_errors); if (rc) goto err_dropped; return 0; err_dropped: - video_device_remove_file(vdev, &dev_attr_packets_dropped); + device_remove_file(&vdev->dev, &dev_attr_packets_dropped); err_framread: - video_device_remove_file(vdev, &dev_attr_frames_read); + device_remove_file(&vdev->dev, &dev_attr_frames_read); err_framtot: - video_device_remove_file(vdev, &dev_attr_frames_total); + device_remove_file(&vdev->dev, &dev_attr_frames_total); err_pal: - video_device_remove_file(vdev, &dev_attr_palette); + device_remove_file(&vdev->dev, &dev_attr_palette); err_stream: - video_device_remove_file(vdev, &dev_attr_streaming); + device_remove_file(&vdev->dev, &dev_attr_streaming); err_inuse: - video_device_remove_file(vdev, &dev_attr_in_use); + device_remove_file(&vdev->dev, &dev_attr_in_use); err_model: - video_device_remove_file(vdev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_model); err: + PDEBUG(0, "STV(e): Could not create sysfs files"); return rc; } static void stv680_remove_sysfs_files(struct video_device *vdev) { - video_device_remove_file(vdev, &dev_attr_model); - video_device_remove_file(vdev, &dev_attr_in_use); - video_device_remove_file(vdev, &dev_attr_streaming); - video_device_remove_file(vdev, &dev_attr_palette); - video_device_remove_file(vdev, &dev_attr_frames_total); - video_device_remove_file(vdev, &dev_attr_frames_read); - video_device_remove_file(vdev, &dev_attr_packets_dropped); - video_device_remove_file(vdev, &dev_attr_decoding_errors); + device_remove_file(&vdev->dev, &dev_attr_model); + device_remove_file(&vdev->dev, &dev_attr_in_use); + device_remove_file(&vdev->dev, &dev_attr_streaming); + device_remove_file(&vdev->dev, &dev_attr_palette); + device_remove_file(&vdev->dev, &dev_attr_frames_total); + device_remove_file(&vdev->dev, &dev_attr_frames_read); + device_remove_file(&vdev->dev, &dev_attr_packets_dropped); + device_remove_file(&vdev->dev, &dev_attr_decoding_errors); } /******************************************************************** diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index e2dec6fb0da9..b8e8fceee525 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c index 7d53de531c44..c317ed7a8482 100644 --- a/drivers/media/video/usbvision/usbvision-core.c +++ b/drivers/media/video/usbvision/usbvision-core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index e97f955aad67..a65e5db0a325 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c index 3b83d4e2b2c3..35293029da02 100644 --- a/drivers/media/video/vpx3220.c +++ b/drivers/media/video/vpx3220.c @@ -33,7 +33,7 @@ #define I2C_NAME(x) (x)->name -#include +#include #include #include diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index ae2b1e6bdf47..2fe38858516b 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -16,11 +16,7 @@ #include #include #include /* need __user */ -#ifdef CONFIG_VIDEO_V4L1_COMPAT -#include -#else #include -#endif #define VIDEO_MAJOR 81 /* Minor device allocation */ @@ -102,27 +98,6 @@ void video_unregister_device(struct video_device *); struct video_device *video_device_alloc(void); void video_device_release(struct video_device *vfd); -#ifdef CONFIG_VIDEO_V4L1_COMPAT -#include - -static inline int __must_check -video_device_create_file(struct video_device *vfd, - struct device_attribute *attr) -{ - int ret = device_create_file(&vfd->dev, attr); - if (ret < 0) - printk(KERN_WARNING "%s error: %d\n", __func__, ret); - return ret; -} -static inline void -video_device_remove_file(struct video_device *vfd, - struct device_attribute *attr) -{ - device_remove_file(&vfd->dev, attr); -} - -#endif /* CONFIG_VIDEO_V4L1_COMPAT */ - #ifdef OBSOLETE_DEVDATA /* to be removed soon */ /* helper functions to access driver private data. */ static inline void *video_get_drvdata(struct video_device *dev) -- cgit v1.2.3 From 655b8408557d586212d0797d423babdc464c587f Mon Sep 17 00:00:00 2001 From: reinhard schwab Date: Sat, 26 Jul 2008 10:47:00 -0300 Subject: V4L/DVB (8489): add dvb-t support for terratec cinergy hybrid T usb xs This patch adds dvbt support for the terratec cinergy hybrid T usb xsstick. Thanks to Devin Heitmueller and Mauro Chehab for guiding me. Signed-off-by: Reinhard Schwab Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 4 ++++ drivers/media/video/em28xx/em28xx-dvb.c | 9 +++++++++ 2 files changed, 13 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 6e0eb950ab81..edf6f77862cc 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -246,6 +246,7 @@ struct em28xx_board em28xx_boards[] = { .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, + .has_dvb = 1, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -639,6 +640,9 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: ctl->demod = XC3028_FE_ZARLINK456; break; + case EM2880_BOARD_TERRATEC_HYBRID_XS: + ctl->demod = XC3028_FE_ZARLINK456; + break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: /* djh - Not sure which demod we need here */ ctl->demod = XC3028_FE_DEFAULT; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index cc61cfb23a4a..9727653b76ff 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -441,6 +441,15 @@ static int dvb_init(struct em28xx *dev) } break; #endif + case EM2880_BOARD_TERRATEC_HYBRID_XS: + dvb->frontend = dvb_attach(zl10353_attach, + &em28xx_zl10353_with_xc3028, + &dev->i2c_adap); + if (attach_xc3028(0x61, dev) < 0) { + result = -EINVAL; + goto out_free; + } + break; default: printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" " isn't supported yet\n", -- cgit v1.2.3 From f78d92c9ffcda7451b5943ab491c087f1ec7e08d Mon Sep 17 00:00:00 2001 From: Dean Anderson Date: Tue, 22 Jul 2008 14:43:27 -0300 Subject: V4L/DVB (8490): s2255drv Sensoray 2255 driver fixes This patch fixes timer issues in driver disconnect. It also removes the restriction of one user per channel at a time. Thanks to Oliver Neukum and Mauro Chehab for finding these issues. Locking of video stream partly based on saa7134 driver. Signed-off-by: Dean Anderson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s2255drv.c | 111 ++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 46 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 2428d441fe15..9ff5403483e5 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -185,6 +185,7 @@ struct s2255_dmaqueue { #define S2255_FW_LOADED_DSPWAIT 1 #define S2255_FW_SUCCESS 2 #define S2255_FW_FAILED 3 +#define S2255_FW_DISCONNECTING 4 struct s2255_fw { int fw_loaded; @@ -264,7 +265,6 @@ struct s2255_buffer { struct s2255_fh { struct s2255_dev *dev; - unsigned int resources; const struct s2255_fmt *fmt; unsigned int width; unsigned int height; @@ -274,14 +274,9 @@ struct s2255_fh { /* mode below is the desired mode. mode in s2255_dev is the current mode that was last set */ struct s2255_mode mode; + int resources[MAX_CHANNELS]; }; -/* - * TODO: fixme S2255_MAX_USERS. Do not limit open driver handles. - * Limit V4L to one stream at a time. - */ -#define S2255_MAX_USERS 1 - #define CUR_USB_FWVER 774 /* current cypress EEPROM firmware version */ #define S2255_MAJOR_VERSION 1 #define S2255_MINOR_VERSION 13 @@ -477,10 +472,9 @@ static void s2255_timer(unsigned long user_data) dprintk(100, "s2255 timer\n"); if (usb_submit_urb(data->fw_urb, GFP_ATOMIC) < 0) { printk(KERN_ERR "s2255: can't submit urb\n"); - if (data->fw) { - release_firmware(data->fw); - data->fw = NULL; - } + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } } @@ -510,13 +504,18 @@ static void s2255_fwchunk_complete(struct urb *urb) struct usb_device *udev = urb->dev; int len; dprintk(100, "udev %p urb %p", udev, urb); - /* TODO: fixme. reflect change in status */ if (urb->status) { dev_err(&udev->dev, "URB failed with status %d", urb->status); + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } if (data->fw_urb == NULL) { - dev_err(&udev->dev, "early disconncect\n"); + dev_err(&udev->dev, "s2255 disconnected\n"); + atomic_set(&data->fw_state, S2255_FW_FAILED); + /* wake up anything waiting for the firmware */ + wake_up(&data->wait_fw); return; } #define CHUNK_SIZE 512 @@ -790,7 +789,8 @@ static int res_get(struct s2255_dev *dev, struct s2255_fh *fh) } /* it's free, grab it */ dev->resources[fh->channel] = 1; - dprintk(1, "res: get\n"); + fh->resources[fh->channel] = 1; + dprintk(1, "s2255: res: get\n"); mutex_unlock(&dev->lock); return 1; } @@ -800,9 +800,18 @@ static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh) return dev->resources[fh->channel]; } +static int res_check(struct s2255_fh *fh) +{ + return fh->resources[fh->channel]; +} + + static void res_free(struct s2255_dev *dev, struct s2255_fh *fh) { + mutex_lock(&dev->lock); dev->resources[fh->channel] = 0; + fh->resources[fh->channel] = 0; + mutex_unlock(&dev->lock); dprintk(1, "res: put\n"); } @@ -1233,7 +1242,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) } if (!res_get(dev, fh)) { - dev_err(&dev->udev->dev, "res get busy\n"); + dev_err(&dev->udev->dev, "s2255: stream busy\n"); return -EBUSY; } @@ -1289,8 +1298,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) } s2255_stop_acquire(dev, fh->channel); res = videobuf_streamoff(&fh->vb_vidq); + if (res < 0) + return res; res_free(dev, fh); - return res; + return 0; } static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) @@ -1463,12 +1474,7 @@ static int s2255_open(struct inode *inode, struct file *file) mutex_lock(&dev->open_lock); dev->users[cur_channel]++; - if (dev->users[cur_channel] > S2255_MAX_USERS) { - dev->users[cur_channel]--; - mutex_unlock(&dev->open_lock); - printk(KERN_INFO "s2255drv: too many open handles!\n"); - return -EBUSY; - } + dprintk(4, "s2255: open_handles %d\n", dev->users[cur_channel]); if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_FAILED) { err("2255 firmware load failed. retrying.\n"); @@ -1479,7 +1485,8 @@ static int s2255_open(struct inode *inode, struct file *file) msecs_to_jiffies(S2255_LOAD_TIMEOUT)); if (atomic_read(&dev->fw_data->fw_state) != S2255_FW_SUCCESS) { - printk(KERN_INFO "2255 FW load failed after 2 tries\n"); + printk(KERN_INFO "2255 FW load failed.\n"); + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -EFAULT; } @@ -1495,6 +1502,7 @@ static int s2255_open(struct inode *inode, struct file *file) != S2255_FW_SUCCESS) { printk(KERN_INFO "2255 firmware not loaded" "try again\n"); + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -EBUSY; } @@ -1503,6 +1511,7 @@ static int s2255_open(struct inode *inode, struct file *file) /* allocate + initialize per filehandle data */ fh = kzalloc(sizeof(*fh), GFP_KERNEL); if (NULL == fh) { + dev->users[cur_channel]--; mutex_unlock(&dev->open_lock); return -ENOMEM; } @@ -1562,44 +1571,48 @@ static void s2255_destroy(struct kref *kref) printk(KERN_ERR "s2255drv: kref problem\n"); return; } + + /* + * Wake up any firmware load waiting (only done in .open, + * which holds the open_lock mutex) + */ + atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING); + wake_up(&dev->fw_data->wait_fw); + /* prevent s2255_disconnect from racing s2255_open */ mutex_lock(&dev->open_lock); s2255_exit_v4l(dev); - /* device unregistered so no longer possible to open. open_mutex - can be unlocked */ + /* + * device unregistered so no longer possible to open. open_mutex + * can be unlocked and timers deleted afterwards. + */ mutex_unlock(&dev->open_lock); /* board shutdown stops the read pipe if it is running */ s2255_board_shutdown(dev); /* make sure firmware still not trying to load */ + del_timer(&dev->timer); /* only started in .probe and .open */ + if (dev->fw_data->fw_urb) { dprintk(2, "kill fw_urb\n"); usb_kill_urb(dev->fw_data->fw_urb); usb_free_urb(dev->fw_data->fw_urb); dev->fw_data->fw_urb = NULL; } + /* - * TODO: fixme(above, below): potentially leaving timers alive. - * do not ignore timeout below if - * it occurs. + * delete the dsp_wait timer, which sets the firmware + * state on completion. This is done before fw_data + * is freed below. */ - /* make sure we aren't waiting for the DSP */ - if (atomic_read(&dev->fw_data->fw_state) == S2255_FW_LOADED_DSPWAIT) { - /* if we are, wait for the wakeup for fw_success or timeout */ - wait_event_timeout(dev->fw_data->wait_fw, - (atomic_read(&dev->fw_data->fw_state) - == S2255_FW_SUCCESS), - msecs_to_jiffies(S2255_LOAD_TIMEOUT)); - } + del_timer(&dev->fw_data->dsp_wait); /* only started in .open */ - if (dev->fw_data) { - if (dev->fw_data->fw) - release_firmware(dev->fw_data->fw); - kfree(dev->fw_data->pfw_data); - kfree(dev->fw_data); - } + if (dev->fw_data->fw) + release_firmware(dev->fw_data->fw); + kfree(dev->fw_data->pfw_data); + kfree(dev->fw_data); usb_put_dev(dev->udev); dprintk(1, "%s", __func__); @@ -1616,17 +1629,23 @@ static int s2255_close(struct inode *inode, struct file *file) mutex_lock(&dev->open_lock); - if (dev->b_acquire[fh->channel]) - s2255_stop_acquire(dev, fh->channel); - res_free(dev, fh); + /* turn off stream */ + if (res_check(fh)) { + if (dev->b_acquire[fh->channel]) + s2255_stop_acquire(dev, fh->channel); + videobuf_streamoff(&fh->vb_vidq); + res_free(dev, fh); + } + videobuf_mmap_free(&fh->vb_vidq); - kfree(fh); dev->users[fh->channel]--; + mutex_unlock(&dev->open_lock); kref_put(&dev->kref, s2255_destroy); dprintk(1, "s2255: close called (minor=%d, users=%d)\n", minor, dev->users[fh->channel]); + kfree(fh); return 0; } -- cgit v1.2.3 From b18559076a31ab0be2d980ce2beff8e32504e080 Mon Sep 17 00:00:00 2001 From: Jaime Velasco Juan Date: Tue, 22 Jul 2008 12:28:36 -0300 Subject: V4L/DVB (8491): stkwebcam: Always reuse last queued buffer This change keeps the video stream going on when the application is slow queuing buffers, instead of spamming dmesg and hanging. Fixes a problem with aMSN reported by Samed Beyribey Signed-off-by: Jaime Velasco Juan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/stk-webcam.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index 8aa56fe02546..a8a72768ca91 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -445,18 +445,19 @@ static void stk_isoc_handler(struct urb *urb) fb->v4lbuf.bytesused = 0; fill = fb->buffer; } else if (fb->v4lbuf.bytesused == dev->frame_size) { - list_move_tail(dev->sio_avail.next, - &dev->sio_full); - wake_up(&dev->wait_frame); - if (list_empty(&dev->sio_avail)) { - (void) (printk_ratelimit() && - STK_ERROR("No buffer available\n")); - goto resubmit; + if (list_is_singular(&dev->sio_avail)) { + /* Always reuse the last buffer */ + fb->v4lbuf.bytesused = 0; + fill = fb->buffer; + } else { + list_move_tail(dev->sio_avail.next, + &dev->sio_full); + wake_up(&dev->wait_frame); + fb = list_first_entry(&dev->sio_avail, + struct stk_sio_buffer, list); + fb->v4lbuf.bytesused = 0; + fill = fb->buffer; } - fb = list_first_entry(&dev->sio_avail, - struct stk_sio_buffer, list); - fb->v4lbuf.bytesused = 0; - fill = fb->buffer; } } else { framelen -= 4; -- cgit v1.2.3 From e14b3658a7651ffd9b1f407eaf07f4dde17ef1e7 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sat, 26 Jul 2008 11:04:33 -0300 Subject: V4L/DVB (8492): Add support for the ATI TV Wonder HD 600 em28xx-cards.c em28xx-dvb.c em28xx.h - Add support for the ATI TV Wonder HD 600, based on a 94 email exchange and USB traces provided by Ronnie Bailey Thanks to Ronnie Bailey for testing the changes Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 50 +++++++++++++++++++++++++++++++ drivers/media/video/em28xx/em28xx-dvb.c | 2 ++ drivers/media/video/em28xx/em28xx.h | 1 + 4 files changed, 54 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 10591467ef16..ef0c3ddacae6 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -18,3 +18,4 @@ 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 19 -> PointNix Intra-Oral Camera (em2860) + 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index edf6f77862cc..81f9ff55588d 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -240,6 +240,52 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, @@ -493,6 +539,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, { USB_DEVICE(0x0ccd, 0x0047), .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, + { USB_DEVICE(0x0438, 0xb002), + .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -608,6 +656,7 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); msleep(50); @@ -649,6 +698,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: /* FIXME: Better to specify the needed IF */ ctl->demod = XC3028_FE_DEFAULT; break; diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 9727653b76ff..31475a245716 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -6,6 +6,7 @@ (c) 2008 Devin Heitmueller - Fixes for the driver to properly work with HVR-950 - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick + - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 (c) 2008 Aidan Thornton @@ -411,6 +412,7 @@ static int dvb_init(struct em28xx *dev) switch (dev->model) { case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, &em2880_lgdt3303_dev, &dev->i2c_adap); diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 89842c5d64a1..9da877375cfb 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -58,6 +58,7 @@ #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 +#define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 1ffdddd6fa3d18982133f6d149d456312d8bfcac Mon Sep 17 00:00:00 2001 From: roel kluin Date: Mon, 21 Jul 2008 21:29:46 -0300 Subject: V4L/DVB (8493): mt20xx: test below 0 on unsigned lo1a and lo2a lo1a and lo2a are unsigned ints so these tests won't work. Signed-off-by: Roel Kluin Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mt20xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c index fbcb28233737..35b763a16d53 100644 --- a/drivers/media/common/tuners/mt20xx.c +++ b/drivers/media/common/tuners/mt20xx.c @@ -148,7 +148,8 @@ static int mt2032_compute_freq(struct dvb_frontend *fe, tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n", rfin,lo2,lo2n,lo2a,lo2num,lo2freq); - if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) { + if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 || + lo2n > 30) { tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n", lo1a, lo1n, lo2a,lo2n); return(-1); -- cgit v1.2.3 From fe0d3dff464bdd0cfe56829d86e358438647046c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Jul 2008 16:33:48 -0300 Subject: V4L/DVB (8494): make cx25840_debug static cx25840_debug can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx25840/cx25840-core.c | 2 +- drivers/media/video/cx25840/cx25840-core.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index e7bf4f4c1319..209d3bcb5dbb 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -50,7 +50,7 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -int cx25840_debug; +static int cx25840_debug; module_param_named(debug,cx25840_debug, int, 0644); diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index 72916ba975a8..b87337e590b4 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h @@ -24,8 +24,6 @@ #include #include -extern int cx25840_debug; - /* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is present in Hauppauge PVR-150 (and possibly PVR-500) cards that have certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The -- cgit v1.2.3 From 53faa1b1b9a262a634d7761ab5c62bbb017666bd Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 21 Jul 2008 16:33:42 -0300 Subject: V4L/DVB (8495): usb/anysee.c: make struct anysee_usb_mutex static This patch makes the needlessly global struct anysee_usb_mutex static. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/anysee.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index adfd4fc82efd..2f408d2e1ef3 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -43,7 +43,7 @@ module_param_named(debug, dvb_usb_anysee_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); -struct mutex anysee_usb_mutex; +static struct mutex anysee_usb_mutex; static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) -- cgit v1.2.3 From d53687d1d22c3204394658a31654de2f1efb0e8f Mon Sep 17 00:00:00 2001 From: Simon Arlott Date: Sat, 26 Jul 2008 11:30:03 -0300 Subject: V4L/DVB (8496): saa7134: Copy tuner data earlier in init to avoid overwriting manual tuner type When saa7134_board_init2 runs, it immediately overwrites the current value (set earlier from module parameter) of tuner_type with the static values, and then does autodetection. This patch moves the tuner_addr copy to earlier in saa7134_initdev and removes the tuner_type copy from saa7134_board_init2. Autodetection could still potentially change to the wrong tuner type, but it is now possible to override the default type for the card again. My card's tuner is configured with autodetection from eeprom, so I don't need to manually set the tuner. I've checked that the autodetection still works for my card. Signed-off-by: Simon Arlott Reviewed-by: Hermann Pitton Cc: Brian Marete Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-cards.c | 3 --- drivers/media/video/saa7134/saa7134-core.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 6893f998d292..98364d171def 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -5853,9 +5853,6 @@ int saa7134_board_init2(struct saa7134_dev *dev) unsigned char buf; int board; - dev->tuner_type = saa7134_boards[dev->board].tuner_type; - dev->tuner_addr = saa7134_boards[dev->board].tuner_addr; - switch (dev->board) { case SAA7134_BOARD_BMK_MPEX_NOTUNER: case SAA7134_BOARD_BMK_MPEX_TUNER: diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index f3e7a598e4b5..a404368308aa 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -945,11 +945,12 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->board = SAA7134_BOARD_UNKNOWN; } dev->autodetected = card[dev->nr] != dev->board; - dev->tuner_type = saa7134_boards[dev->board].tuner_type; + dev->tuner_type = saa7134_boards[dev->board].tuner_type; + dev->tuner_addr = saa7134_boards[dev->board].tuner_addr; dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; if (UNSET != tuner[dev->nr]) dev->tuner_type = tuner[dev->nr]; - printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", dev->name,pci_dev->subsystem_vendor, pci_dev->subsystem_device,saa7134_boards[dev->board].name, dev->board, dev->autodetected ? -- cgit v1.2.3 From 90ac5ea37f91e38d798c5e355232ce7f9c2a24d4 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 26 Jul 2008 11:42:29 -0300 Subject: V4L/DVB (8497): uvcvideo: Make the auto-exposure menu control V4L2 compliant V4L2 and UVC enumerate the auto-exposure settings in a different order. This patch fixes the auto-exposure menu declaration to match the V4L2 spec. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 3ae95512666f..f54d06a8af92 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -195,8 +195,8 @@ static struct uvc_menu_info power_line_frequency_controls[] = { }; static struct uvc_menu_info exposure_auto_controls[] = { - { 1, "Manual Mode" }, { 2, "Auto Mode" }, + { 1, "Manual Mode" }, { 4, "Shutter Priority Mode" }, { 8, "Aperture Priority Mode" }, }; -- cgit v1.2.3 From 54812c77bc830e2dbcb62b4c6d8a9c7f97cfdd1b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 17 Jul 2008 07:37:37 -0300 Subject: V4L/DVB (8498): uvcvideo: Return sensible min and max values when querying a boolean control. Although the V4L2 spec states that the minimum and maximum fields may not be valid for control types other than V4L2_CTRL_TYPE_INTEGER, it makes sense to set the bounds to 0 and 1 for boolean controls instead of returning uninitialized values. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/uvc/uvc_ctrl.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f54d06a8af92..626f4ad7e876 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c @@ -592,6 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, if (ctrl == NULL) return -EINVAL; + memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl); v4l2_ctrl->id = mapping->id; v4l2_ctrl->type = mapping->v4l2_type; strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); @@ -608,7 +609,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, v4l2_ctrl->default_value = uvc_get_le_value(data, mapping); } - if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { + switch (mapping->v4l2_type) { + case V4L2_CTRL_TYPE_MENU: v4l2_ctrl->minimum = 0; v4l2_ctrl->maximum = mapping->menu_count - 1; v4l2_ctrl->step = 1; @@ -622,6 +624,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, } return 0; + + case V4L2_CTRL_TYPE_BOOLEAN: + v4l2_ctrl->minimum = 0; + v4l2_ctrl->maximum = 1; + v4l2_ctrl->step = 1; + return 0; + + default: + break; } if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { -- cgit v1.2.3 From 85b9b8a444413ea5706096df13012520ed6c5103 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Jul 2008 09:51:03 -0300 Subject: V4L/DVB (8499): zr36067: Rework device memory allocation Allocate zoran devices dynamically. Currently, the zr36067 driver stores the device structures in a global array, with room for 4 devices. This makes the bss section very large (90 kB!), and given that most users, I suspect, have only one zoran device, this is a waste of kernel memory. Allocating the memory dynamically lets us use only the amount of memory we need. Before: text data bss dec hex filename 64754 9230 90224 164208 28170 drivers/media/video/zr36067.o After: text data bss dec hex filename 64866 9230 112 74208 121e0 drivers/media/video/zr36067.o Signed-off-by: Jean Delvare Acked-by: Ronald Bultje Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_card.c | 36 +++++++++++++++++++++++------------- drivers/media/video/zoran_card.h | 2 +- drivers/media/video/zoran_driver.c | 4 ++-- 3 files changed, 26 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 0929edb2d4f1..38d7ed858812 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -161,7 +161,7 @@ static struct pci_device_id zr36067_pci_tbl[] = { MODULE_DEVICE_TABLE(pci, zr36067_pci_tbl); int zoran_num; /* number of Buzs in use */ -struct zoran zoran[BUZ_MAX]; +struct zoran *zoran[BUZ_MAX]; /* videocodec bus functions ZR36060 */ static u32 @@ -1164,7 +1164,7 @@ static void zoran_release (struct zoran *zr) { if (!zr->initialized) - return; + goto exit_free; /* unregister videocodec bus */ if (zr->codec) { struct videocodec_master *master = zr->codec->master_data; @@ -1192,6 +1192,8 @@ zoran_release (struct zoran *zr) iounmap(zr->zr36057_mem); pci_disable_device(zr->pci_dev); video_unregister_device(zr->video_dev); +exit_free: + kfree(zr); } void @@ -1269,8 +1271,14 @@ find_zr36057 (void) while (zoran_num < BUZ_MAX && (dev = pci_get_device(PCI_VENDOR_ID_ZORAN, PCI_DEVICE_ID_ZORAN_36057, dev)) != NULL) { card_num = card[zoran_num]; - zr = &zoran[zoran_num]; - memset(zr, 0, sizeof(struct zoran)); // Just in case if previous cycle failed + zr = kzalloc(sizeof(struct zoran), GFP_KERNEL); + if (!zr) { + dprintk(1, + KERN_ERR + "%s: find_zr36057() - kzalloc failed\n", + ZORAN_NAME); + continue; + } zr->pci_dev = dev; //zr->zr36057_mem = NULL; zr->id = zoran_num; @@ -1278,7 +1286,7 @@ find_zr36057 (void) spin_lock_init(&zr->spinlock); mutex_init(&zr->resource_lock); if (pci_enable_device(dev)) - continue; + goto zr_free_mem; zr->zr36057_adr = pci_resource_start(zr->pci_dev, 0); pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision); @@ -1294,7 +1302,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - no card specified, please use the card=X insmod option\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } } else { int i; @@ -1333,7 +1341,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - unknown card\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } } } @@ -1343,7 +1351,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - invalid cardnum %d\n", ZR_DEVNAME(zr), card_num); - continue; + goto zr_free_mem; } /* even though we make this a non pointer and thus @@ -1361,7 +1369,7 @@ find_zr36057 (void) KERN_ERR "%s: find_zr36057() - ioremap failed\n", ZR_DEVNAME(zr)); - continue; + goto zr_free_mem; } result = request_irq(zr->pci_dev->irq, @@ -1530,7 +1538,7 @@ find_zr36057 (void) } /* Success so keep the pci_dev referenced */ pci_dev_get(zr->pci_dev); - zoran_num++; + zoran[zoran_num++] = zr; continue; // Init errors @@ -1549,6 +1557,8 @@ find_zr36057 (void) free_irq(zr->pci_dev->irq, zr); zr_unmap: iounmap(zr->zr36057_mem); + zr_free_mem: + kfree(zr); continue; } if (dev) /* Clean up ref count on early exit */ @@ -1620,7 +1630,7 @@ init_dc10_cards (void) /* take care of Natoma chipset and a revision 1 zr36057 */ for (i = 0; i < zoran_num; i++) { - struct zoran *zr = &zoran[i]; + struct zoran *zr = zoran[i]; if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) { zr->jpg_buffers.need_contiguous = 1; @@ -1632,7 +1642,7 @@ init_dc10_cards (void) if (zr36057_init(zr) < 0) { for (i = 0; i < zoran_num; i++) - zoran_release(&zoran[i]); + zoran_release(zoran[i]); return -EIO; } zoran_proc_init(zr); @@ -1647,7 +1657,7 @@ unload_dc10_cards (void) int i; for (i = 0; i < zoran_num; i++) - zoran_release(&zoran[i]); + zoran_release(zoran[i]); } module_init(init_dc10_cards); diff --git a/drivers/media/video/zoran_card.h b/drivers/media/video/zoran_card.h index 1b5c4171cf9c..e4dc9d29b404 100644 --- a/drivers/media/video/zoran_card.h +++ b/drivers/media/video/zoran_card.h @@ -41,7 +41,7 @@ extern int zr36067_debug; /* Anybody who uses more than four? */ #define BUZ_MAX 4 extern int zoran_num; -extern struct zoran zoran[BUZ_MAX]; +extern struct zoran *zoran[BUZ_MAX]; extern struct video_device zoran_template; diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index e1e1b19a0aed..3ca58221d5a9 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -1213,8 +1213,8 @@ zoran_open (struct inode *inode, /* find the device */ for (i = 0; i < zoran_num; i++) { - if (zoran[i].video_dev->minor == minor) { - zr = &zoran[i]; + if (zoran[i]->video_dev->minor == minor) { + zr = zoran[i]; break; } } -- cgit v1.2.3 From ed1aedb136ca42dfd70f5bef202d23994c1a3bae Mon Sep 17 00:00:00 2001 From: Martin Samuelsson Date: Mon, 14 Jul 2008 09:28:59 -0300 Subject: V4L/DVB (8500): zr36067: Load the avs6eyes chip drivers automatically This enables the avs6eyes to load the bt866 and ks0127 drivers automatically. Signed-off-by: Martin Samuelsson Acked-by: Ronald Bultje Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran_card.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/media') diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c index 38d7ed858812..d842a7cb99d2 100644 --- a/drivers/media/video/zoran_card.c +++ b/drivers/media/video/zoran_card.c @@ -355,9 +355,15 @@ i2cid_to_modulename (u16 i2c_id) case I2C_DRIVERID_BT856: name = "bt856"; break; + case I2C_DRIVERID_BT866: + name = "bt866"; + break; case I2C_DRIVERID_VPX3220: name = "vpx3220"; break; + case I2C_DRIVERID_KS0127: + name = "ks0127"; + break; } return name; -- cgit v1.2.3 From 8d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 25 Jul 2008 19:44:49 -0700 Subject: dma-mapping: add the device argument to dma_mapping_error() Add per-device dma_mapping_ops support for CONFIG_X86_64 as POWER architecture does: This enables us to cleanly fix the Calgary IOMMU issue that some devices are not behind the IOMMU (http://lkml.org/lkml/2008/5/8/423). I think that per-device dma_mapping_ops support would be also helpful for KVM people to support PCI passthrough but Andi thinks that this makes it difficult to support the PCI passthrough (see the above thread). So I CC'ed this to KVM camp. Comments are appreciated. A pointer to dma_mapping_ops to struct dev_archdata is added. If the pointer is non NULL, DMA operations in asm/dma-mapping.h use it. If it's NULL, the system-wide dma_ops pointer is used as before. If it's useful for KVM people, I plan to implement a mechanism to register a hook called when a new pci (or dma capable) device is created (it works with hot plugging). It enables IOMMUs to set up an appropriate dma_mapping_ops per device. The major obstacle is that dma_mapping_error doesn't take a pointer to the device unlike other DMA operations. So x86 can't have dma_mapping_ops per device. Note all the POWER IOMMUs use the same dma_mapping_error function so this is not a problem for POWER but x86 IOMMUs use different dma_mapping_error functions. The first patch adds the device argument to dma_mapping_error. The patch is trivial but large since it touches lots of drivers and dma-mapping.h in all the architecture. This patch: dma_mapping_error() doesn't take a pointer to the device unlike other DMA operations. So we can't have dma_mapping_ops per device. Note that POWER already has dma_mapping_ops per device but all the POWER IOMMUs use the same dma_mapping_error function. x86 IOMMUs use device argument. [akpm@linux-foundation.org: fix sge] [akpm@linux-foundation.org: fix svc_rdma] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix bnx2x] [akpm@linux-foundation.org: fix s2io] [akpm@linux-foundation.org: fix pasemi_mac] [akpm@linux-foundation.org: fix sdhci] [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: fix sparc] [akpm@linux-foundation.org: fix ibmvscsi] Signed-off-by: FUJITA Tomonori Cc: Muli Ben-Yehuda Cc: Andi Kleen Cc: Thomas Gleixner Cc: Ingo Molnar Cc: Avi Kivity Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 4 +- arch/arm/common/dmabounce.c | 2 +- arch/ia64/hp/common/hwsw_iommu.c | 5 +- arch/ia64/hp/common/sba_iommu.c | 2 +- arch/ia64/sn/pci/pci_dma.c | 2 +- arch/mips/mm/dma-default.c | 2 +- arch/powerpc/platforms/cell/celleb_scc_pciex.c | 2 +- arch/powerpc/platforms/cell/spider-pci.c | 2 +- arch/powerpc/platforms/iseries/mf.c | 2 +- arch/x86/kernel/pci-calgary_64.c | 2 +- arch/x86/kernel/pci-dma.c | 27 ++++--- arch/x86/kernel/pci-gart_64.c | 3 +- arch/x86/kernel/pci-nommu.c | 14 +--- arch/x86/kernel/pci-swiotlb_64.c | 2 +- drivers/firewire/fw-iso.c | 2 +- drivers/firewire/fw-ohci.c | 2 +- drivers/firewire/fw-sbp2.c | 8 +-- drivers/infiniband/hw/ipath/ipath_sdma.c | 2 +- drivers/infiniband/hw/ipath/ipath_user_sdma.c | 6 +- drivers/infiniband/hw/mthca/mthca_eq.c | 2 +- drivers/media/dvb/pluto2/pluto2.c | 2 +- drivers/mmc/host/sdhci.c | 4 +- drivers/net/arm/ep93xx_eth.c | 4 +- drivers/net/bnx2x_main.c | 4 +- drivers/net/cxgb3/sge.c | 2 +- drivers/net/e100.c | 2 +- drivers/net/e1000e/ethtool.c | 4 +- drivers/net/e1000e/netdev.c | 11 +-- drivers/net/ibmveth.c | 38 +++++----- drivers/net/iseries_veth.c | 4 +- drivers/net/mlx4/eq.c | 2 +- drivers/net/pasemi_mac.c | 6 +- drivers/net/qla3xxx.c | 12 ++-- drivers/net/s2io.c | 48 +++++++------ drivers/net/sfc/rx.c | 4 +- drivers/net/sfc/tx.c | 7 +- drivers/net/spider_net.c | 4 +- drivers/net/tc35815.c | 4 +- drivers/net/wireless/ath5k/base.c | 4 +- drivers/scsi/ibmvscsi/ibmvfc.c | 4 +- drivers/scsi/ibmvscsi/ibmvscsi.c | 4 +- drivers/scsi/ibmvscsi/ibmvstgt.c | 2 +- drivers/scsi/ibmvscsi/rpa_vscsi.c | 2 +- drivers/spi/atmel_spi.c | 4 +- drivers/spi/au1550_spi.c | 6 +- drivers/spi/omap2_mcspi.c | 4 +- drivers/spi/pxa2xx_spi.c | 4 +- drivers/spi/spi_imx.c | 6 +- include/asm-alpha/dma-mapping.h | 6 +- include/asm-alpha/pci.h | 2 +- include/asm-arm/dma-mapping.h | 2 +- include/asm-avr32/dma-mapping.h | 2 +- include/asm-cris/dma-mapping.h | 2 +- include/asm-frv/dma-mapping.h | 2 +- include/asm-generic/dma-mapping-broken.h | 2 +- include/asm-generic/dma-mapping.h | 4 +- include/asm-generic/pci-dma-compat.h | 4 +- include/asm-ia64/machvec.h | 2 +- include/asm-m68k/dma-mapping.h | 2 +- include/asm-mips/dma-mapping.h | 2 +- include/asm-mn10300/dma-mapping.h | 2 +- include/asm-parisc/dma-mapping.h | 2 +- include/asm-powerpc/dma-mapping.h | 2 +- include/asm-sh/dma-mapping.h | 2 +- include/asm-sparc/dma-mapping_64.h | 2 +- include/asm-sparc/pci_32.h | 3 +- include/asm-sparc/pci_64.h | 5 +- include/asm-x86/device.h | 3 + include/asm-x86/dma-mapping.h | 99 ++++++++++++++++++-------- include/asm-x86/swiotlb.h | 2 +- include/asm-xtensa/dma-mapping.h | 2 +- include/linux/i2o.h | 2 +- include/linux/ssb/ssb.h | 4 +- include/rdma/ib_verbs.h | 2 +- lib/swiotlb.c | 4 +- net/sunrpc/xprtrdma/svc_rdma_sendto.c | 3 +- 76 files changed, 256 insertions(+), 210 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 80d150458c80..d8b63d164e41 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -298,10 +298,10 @@ recommended that you never use these unless you really know what the cache width is. int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *hwdev, dma_addr_t dma_addr) In some circumstances dma_map_single and dma_map_page will fail to create a mapping. A driver can check for these errors by testing the returned diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index dd2947342604..69130f365904 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -280,7 +280,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, /* * Trying to unmap an invalid mapping */ - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "Trying to unmap invalid mapping\n"); return; } diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c index 1c44ec2a1d58..88b6e6f3fd88 100644 --- a/arch/ia64/hp/common/hwsw_iommu.c +++ b/arch/ia64/hp/common/hwsw_iommu.c @@ -186,9 +186,10 @@ hwsw_dma_supported (struct device *dev, u64 mask) } int -hwsw_dma_mapping_error (dma_addr_t dma_addr) +hwsw_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return hwiommu_dma_mapping_error (dma_addr) || swiotlb_dma_mapping_error(dma_addr); + return hwiommu_dma_mapping_error(dev, dma_addr) || + swiotlb_dma_mapping_error(dev, dma_addr); } EXPORT_SYMBOL(hwsw_dma_mapping_error); diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 34421aed1e2a..4956be40d7b5 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2147,7 +2147,7 @@ sba_dma_supported (struct device *dev, u64 mask) } int -sba_dma_mapping_error (dma_addr_t dma_addr) +sba_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c index 52175af299a0..53ebb6484495 100644 --- a/arch/ia64/sn/pci/pci_dma.c +++ b/arch/ia64/sn/pci/pci_dma.c @@ -350,7 +350,7 @@ void sn_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } EXPORT_SYMBOL(sn_dma_sync_sg_for_device); -int sn_dma_mapping_error(dma_addr_t dma_addr) +int sn_dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index ae39dd88b9aa..891312f8e5a6 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -348,7 +348,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele EXPORT_SYMBOL(dma_sync_sg_for_device); -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 0e04f8fb152a..3e7e0f1568ef 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -281,7 +281,7 @@ static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data) dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(bus->phb->parent, dummy_page_da)) { pr_err("PCIEX:Map dummy page failed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/cell/spider-pci.c b/arch/powerpc/platforms/cell/spider-pci.c index 418b605ac35a..5122ec145271 100644 --- a/arch/powerpc/platforms/cell/spider-pci.c +++ b/arch/powerpc/platforms/cell/spider-pci.c @@ -111,7 +111,7 @@ static int __init spiderpci_pci_setup_chip(struct pci_controller *phb, dummy_page_da = dma_map_single(phb->parent, dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(dummy_page_da)) { + if (dma_mapping_error(phb->parent, dummy_page_da)) { pr_err("SPIDER-IOWA:Map dummy page filed.\n"); kfree(dummy_page_va); return -1; diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 1dc7295746da..731d7b157749 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -871,7 +871,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, count = 256 - off; dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error(NULL, dma_addr)) return -ENOMEM; memset(page, 0, off + count); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 19e7fc7c2c4f..1eb86be93d7a 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -544,7 +544,7 @@ error: return ret; } -static const struct dma_mapping_ops calgary_dma_ops = { +static struct dma_mapping_ops calgary_dma_ops = { .alloc_coherent = calgary_alloc_coherent, .map_single = calgary_map_single, .unmap_single = calgary_unmap_single, diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index cbecb05551bb..37544123896d 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -11,7 +11,7 @@ static int forbid_dac __read_mostly; -const struct dma_mapping_ops *dma_ops; +struct dma_mapping_ops *dma_ops; EXPORT_SYMBOL(dma_ops); static int iommu_sac_force __read_mostly; @@ -312,6 +312,8 @@ static int dma_release_coherent(struct device *dev, int order, void *vaddr) int dma_supported(struct device *dev, u64 mask) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + #ifdef CONFIG_PCI if (mask > 0xffffffff && forbid_dac > 0) { dev_info(dev, "PCI: Disallowing DAC for device\n"); @@ -319,8 +321,8 @@ int dma_supported(struct device *dev, u64 mask) } #endif - if (dma_ops->dma_supported) - return dma_ops->dma_supported(dev, mask); + if (ops->dma_supported) + return ops->dma_supported(dev, mask); /* Copied from i386. Doesn't make much sense, because it will only work for pci_alloc_coherent. @@ -367,6 +369,7 @@ void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp) { + struct dma_mapping_ops *ops = get_dma_ops(dev); void *memory = NULL; struct page *page; unsigned long dma_mask = 0; @@ -435,8 +438,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, /* Let low level make its own zone decisions */ gfp &= ~(GFP_DMA32|GFP_DMA); - if (dma_ops->alloc_coherent) - return dma_ops->alloc_coherent(dev, size, + if (ops->alloc_coherent) + return ops->alloc_coherent(dev, size, dma_handle, gfp); return NULL; } @@ -448,14 +451,14 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, } } - if (dma_ops->alloc_coherent) { + if (ops->alloc_coherent) { free_pages((unsigned long)memory, get_order(size)); gfp &= ~(GFP_DMA|GFP_DMA32); - return dma_ops->alloc_coherent(dev, size, dma_handle, gfp); + return ops->alloc_coherent(dev, size, dma_handle, gfp); } - if (dma_ops->map_simple) { - *dma_handle = dma_ops->map_simple(dev, virt_to_phys(memory), + if (ops->map_simple) { + *dma_handle = ops->map_simple(dev, virt_to_phys(memory), size, PCI_DMA_BIDIRECTIONAL); if (*dma_handle != bad_dma_address) @@ -477,12 +480,14 @@ EXPORT_SYMBOL(dma_alloc_coherent); void dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t bus) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + int order = get_order(size); WARN_ON(irqs_disabled()); /* for portability */ if (dma_release_coherent(dev, order, vaddr)) return; - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, bus, size, 0); + if (ops->unmap_single) + ops->unmap_single(dev, bus, size, 0); free_pages((unsigned long)vaddr, order); } EXPORT_SYMBOL(dma_free_coherent); diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index df5f142657d2..744126e64950 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c @@ -692,8 +692,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) extern int agp_amd64_init(void); -static const struct dma_mapping_ops gart_dma_ops = { - .mapping_error = NULL, +static struct dma_mapping_ops gart_dma_ops = { .map_single = gart_map_single, .map_simple = gart_map_simple, .unmap_single = gart_unmap_single, diff --git a/arch/x86/kernel/pci-nommu.c b/arch/x86/kernel/pci-nommu.c index 792b9179eff3..3f91f71cdc3e 100644 --- a/arch/x86/kernel/pci-nommu.c +++ b/arch/x86/kernel/pci-nommu.c @@ -72,21 +72,9 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, return nents; } -/* Make sure we keep the same behaviour */ -static int nommu_mapping_error(dma_addr_t dma_addr) -{ -#ifdef CONFIG_X86_32 - return 0; -#else - return (dma_addr == bad_dma_address); -#endif -} - - -const struct dma_mapping_ops nommu_dma_ops = { +struct dma_mapping_ops nommu_dma_ops = { .map_single = nommu_map_single, .map_sg = nommu_map_sg, - .mapping_error = nommu_mapping_error, .is_phys = 1, }; diff --git a/arch/x86/kernel/pci-swiotlb_64.c b/arch/x86/kernel/pci-swiotlb_64.c index 20df839b9c20..c4ce0332759e 100644 --- a/arch/x86/kernel/pci-swiotlb_64.c +++ b/arch/x86/kernel/pci-swiotlb_64.c @@ -18,7 +18,7 @@ swiotlb_map_single_phys(struct device *hwdev, phys_addr_t paddr, size_t size, return swiotlb_map_single(hwdev, phys_to_virt(paddr), size, direction); } -const struct dma_mapping_ops swiotlb_dma_ops = { +struct dma_mapping_ops swiotlb_dma_ops = { .mapping_error = swiotlb_dma_mapping_error, .alloc_coherent = swiotlb_alloc_coherent, .free_coherent = swiotlb_free_coherent, diff --git a/drivers/firewire/fw-iso.c b/drivers/firewire/fw-iso.c index bcbe794a3ea5..e14c03dc0065 100644 --- a/drivers/firewire/fw-iso.c +++ b/drivers/firewire/fw-iso.c @@ -50,7 +50,7 @@ fw_iso_buffer_init(struct fw_iso_buffer *buffer, struct fw_card *card, address = dma_map_page(card->device, buffer->pages[i], 0, PAGE_SIZE, direction); - if (dma_mapping_error(address)) { + if (dma_mapping_error(card->device, address)) { __free_page(buffer->pages[i]); goto out_pages; } diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 333b12544dd1..566672e0bcff 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -953,7 +953,7 @@ at_context_queue_packet(struct context *ctx, struct fw_packet *packet) payload_bus = dma_map_single(ohci->card.device, packet->payload, packet->payload_length, DMA_TO_DEVICE); - if (dma_mapping_error(payload_bus)) { + if (dma_mapping_error(ohci->card.device, payload_bus)) { packet->ack = RCODE_SEND_ERROR; return -1; } diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 53fc5a641e6d..aaff50ebba1d 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -543,7 +543,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); - if (dma_mapping_error(orb->response_bus)) + if (dma_mapping_error(device->card->device, orb->response_bus)) goto fail_mapping_response; orb->request.response.high = 0; @@ -577,7 +577,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto fail_mapping_request; sbp2_send_orb(&orb->base, lu, node_id, generation, @@ -1424,7 +1424,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, orb->page_table_bus = dma_map_single(device->card->device, orb->page_table, sizeof(orb->page_table), DMA_TO_DEVICE); - if (dma_mapping_error(orb->page_table_bus)) + if (dma_mapping_error(device->card->device, orb->page_table_bus)) goto fail_page_table; /* @@ -1509,7 +1509,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) orb->base.request_bus = dma_map_single(device->card->device, &orb->request, sizeof(orb->request), DMA_TO_DEVICE); - if (dma_mapping_error(orb->base.request_bus)) + if (dma_mapping_error(device->card->device, orb->base.request_bus)) goto out; sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation, diff --git a/drivers/infiniband/hw/ipath/ipath_sdma.c b/drivers/infiniband/hw/ipath/ipath_sdma.c index eaba03273e4f..284c9bca517e 100644 --- a/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -698,7 +698,7 @@ retry: addr = dma_map_single(&dd->pcidev->dev, tx->txreq.map_addr, tx->map_len, DMA_TO_DEVICE); - if (dma_mapping_error(addr)) { + if (dma_mapping_error(&dd->pcidev->dev, addr)) { ret = -EIO; goto unlock; } diff --git a/drivers/infiniband/hw/ipath/ipath_user_sdma.c b/drivers/infiniband/hw/ipath/ipath_user_sdma.c index 86e016916cd1..82d9a0b5ca2f 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_sdma.c +++ b/drivers/infiniband/hw/ipath/ipath_user_sdma.c @@ -206,7 +206,7 @@ static int ipath_user_sdma_coalesce(const struct ipath_devdata *dd, dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_unmap; } @@ -301,7 +301,7 @@ static int ipath_user_sdma_pin_pages(const struct ipath_devdata *dd, pages[j], 0, flen, DMA_TO_DEVICE); unsigned long fofs = addr & ~PAGE_MASK; - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto done; } @@ -508,7 +508,7 @@ static int ipath_user_sdma_queue_pkts(const struct ipath_devdata *dd, if (page) { dma_addr = dma_map_page(&dd->pcidev->dev, page, 0, len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_addr)) { + if (dma_mapping_error(&dd->pcidev->dev, dma_addr)) { ret = -ENOMEM; goto free_pbc; } diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 4e36aa7cb3d2..cc6858f0b65b 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -780,7 +780,7 @@ int mthca_map_eq_icm(struct mthca_dev *dev, u64 icm_virt) return -ENOMEM; dev->eq_table.icm_dma = pci_map_page(dev->pdev, dev->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(dev->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, dev->eq_table.icm_dma)) { __free_page(dev->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 1360403b88b6..a9653c63f4db 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -242,7 +242,7 @@ static int __devinit pluto_dma_map(struct pluto *pluto) pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - return pci_dma_mapping_error(pluto->dma_addr); + return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); } static void pluto_dma_unmap(struct pluto *pluto) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index c3a5db72ddd7..5f95e10229b5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -337,7 +337,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->align_addr = dma_map_single(mmc_dev(host->mmc), host->align_buffer, 128 * 4, direction); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto fail; BUG_ON(host->align_addr & 0x3); @@ -439,7 +439,7 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); - if (dma_mapping_error(host->align_addr)) + if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto unmap_entries; BUG_ON(host->adma_addr & 0x3); diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 7a14980f3472..18d3eeb7eab2 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -482,7 +482,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } @@ -505,7 +505,7 @@ static int ep93xx_alloc_buffers(struct ep93xx_priv *ep) goto err; d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE); - if (dma_mapping_error(d)) { + if (dma_mapping_error(NULL, d)) { free_page((unsigned long)page); goto err; } diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 0263bef9cc6d..c7cc760a1777 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -1020,7 +1020,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, mapping = pci_map_page(bp->pdev, page, 0, BCM_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { __free_pages(page, PAGES_PER_SGE_SHIFT); return -ENOMEM; } @@ -1048,7 +1048,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(mapping))) { + if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) { dev_kfree_skb(skb); return -ENOMEM; } diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index a96331c875e6..1b0861d73ab7 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -386,7 +386,7 @@ static inline int add_one_rx_buf(void *va, unsigned int len, dma_addr_t mapping; mapping = pci_map_single(pdev, va, len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(mapping))) + if (unlikely(pci_dma_mapping_error(pdev, mapping))) return -ENOMEM; pci_unmap_addr_set(sd, dma_addr, mapping); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1037b1332312..19d32a227be1 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1790,7 +1790,7 @@ static int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(rx->dma_addr)) { + if (pci_dma_mapping_error(nic->pdev, rx->dma_addr)) { dev_kfree_skb_any(rx->skb); rx->skb = NULL; rx->dma_addr = 0; diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index a14561f40db0..9350564065e7 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -1090,7 +1090,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) tx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { ret_val = 4; goto err_nomem; } @@ -1153,7 +1153,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->buffer_info[i].dma = pci_map_single(pdev, skb->data, 2048, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) { + if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { ret_val = 8; goto err_nomem; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 9c0f56b3c518..d13677899767 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -195,7 +195,7 @@ map_skb: buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; break; @@ -265,7 +265,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ps_page->page, 0, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(ps_page->dma)) { + if (pci_dma_mapping_error(pdev, ps_page->dma)) { dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); adapter->rx_dma_failed++; @@ -300,7 +300,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_ps_bsize0, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(pdev, buffer_info->dma)) { dev_err(&pdev->dev, "RX DMA map failed\n"); adapter->rx_dma_failed++; /* cleanup skb */ @@ -3344,7 +3344,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, skb->data + offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); adapter->tx_dma_failed++; return -1; @@ -3382,7 +3382,8 @@ static int e1000_tx_map(struct e1000_adapter *adapter, offset, size, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buffer_info->dma)) { + if (pci_dma_mapping_error(adapter->pdev, + buffer_info->dma)) { dev_err(&adapter->pdev->dev, "TX DMA page map failed\n"); adapter->tx_dma_failed++; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index e5a6e2e84540..91ec9fdc7184 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -260,7 +260,7 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_addr)) + if (dma_mapping_error((&adapter->vdev->dev, dma_addr)) goto failure; pool->free_map[free_index] = IBM_VETH_INVALID_MAP; @@ -294,7 +294,7 @@ failure: pool->consumer_index = pool->size - 1; else pool->consumer_index--; - if (!dma_mapping_error(dma_addr)) + if (!dma_mapping_error((&adapter->vdev->dev, dma_addr)) dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[index], pool->buff_size, DMA_FROM_DEVICE); @@ -448,11 +448,11 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) static void ibmveth_cleanup(struct ibmveth_adapter *adapter) { int i; + struct device *dev = &adapter->vdev->dev; if(adapter->buffer_list_addr != NULL) { - if(!dma_mapping_error(adapter->buffer_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->buffer_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { + dma_unmap_single(dev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->buffer_list_dma = DMA_ERROR_CODE; } @@ -461,9 +461,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->filter_list_addr != NULL) { - if(!dma_mapping_error(adapter->filter_list_dma)) { - dma_unmap_single(&adapter->vdev->dev, - adapter->filter_list_dma, 4096, + if (!dma_mapping_error(dev, adapter->filter_list_dma)) { + dma_unmap_single(dev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); adapter->filter_list_dma = DMA_ERROR_CODE; } @@ -472,8 +471,8 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) } if(adapter->rx_queue.queue_addr != NULL) { - if(!dma_mapping_error(adapter->rx_queue.queue_dma)) { - dma_unmap_single(&adapter->vdev->dev, + if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { + dma_unmap_single(dev, adapter->rx_queue.queue_dma, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); @@ -535,6 +534,7 @@ static int ibmveth_open(struct net_device *netdev) int rc; union ibmveth_buf_desc rxq_desc; int i; + struct device *dev; ibmveth_debug_printk("open starting\n"); @@ -563,17 +563,19 @@ static int ibmveth_open(struct net_device *netdev) return -ENOMEM; } - adapter->buffer_list_dma = dma_map_single(&adapter->vdev->dev, + dev = &adapter->vdev->dev; + + adapter->buffer_list_dma = dma_map_single(dev, adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->filter_list_dma = dma_map_single(&adapter->vdev->dev, + adapter->filter_list_dma = dma_map_single(dev, adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); - adapter->rx_queue.queue_dma = dma_map_single(&adapter->vdev->dev, + adapter->rx_queue.queue_dma = dma_map_single(dev, adapter->rx_queue.queue_addr, adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); - if((dma_mapping_error(adapter->buffer_list_dma) ) || - (dma_mapping_error(adapter->filter_list_dma)) || - (dma_mapping_error(adapter->rx_queue.queue_dma))) { + if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || + (dma_mapping_error(dev, adapter->filter_list_dma)) || + (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { ibmveth_error_printk("unable to map filter or buffer list pages\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -645,7 +647,7 @@ static int ibmveth_open(struct net_device *netdev) adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); - if (dma_mapping_error(adapter->bounce_buffer_dma)) { + if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { ibmveth_error_printk("unable to map bounce buffer\n"); ibmveth_cleanup(adapter); napi_disable(&adapter->napi); @@ -922,7 +924,7 @@ static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *netdev) buf[1] = 0; } - if (dma_mapping_error(data_dma_addr)) { + if (dma_mapping_error((&adapter->vdev->dev, data_dma_addr)) { if (!firmware_has_feature(FW_FEATURE_CMO)) ibmveth_error_printk("tx: unable to map xmit buffer\n"); skb_copy_from_linear_data(skb, adapter->bounce_buffer, diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index b8d0639c1cdf..c46864d626b2 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1128,7 +1128,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, msg->data.addr[0] = dma_map_single(port->dev, skb->data, skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(msg->data.addr[0])) + if (dma_mapping_error(port->dev, msg->data.addr[0])) goto recycle_and_drop; msg->dev = port->dev; @@ -1226,7 +1226,7 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx, dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; - if (!dma_mapping_error(dma_address)) + if (!dma_mapping_error(msg->dev, dma_address)) dma_unmap_single(msg->dev, dma_address, dma_length, DMA_TO_DEVICE); diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index ea3a09aaa844..7df928d3a3d8 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -526,7 +526,7 @@ int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt) return -ENOMEM; priv->eq_table.icm_dma = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(priv->eq_table.icm_dma)) { + if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) { __free_page(priv->eq_table.icm_page); return -ENOMEM; } diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 993d87c9296f..edc0fd588985 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -650,7 +650,7 @@ static void pasemi_mac_replenish_rx_ring(const struct net_device *dev, mac->bufsz - LOCAL_SKB_ALIGN, PCI_DMA_FROMDEVICE); - if (unlikely(dma_mapping_error(dma))) { + if (unlikely(pci_dma_mapping_error(mac->dma_pdev, dma))) { dev_kfree_skb_irq(info->skb); break; } @@ -1519,7 +1519,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE); map_size[0] = skb_headlen(skb); - if (dma_mapping_error(map[0])) + if (pci_dma_mapping_error(mac->dma_pdev, map[0])) goto out_err_nolock; for (i = 0; i < nfrags; i++) { @@ -1529,7 +1529,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev) frag->page_offset, frag->size, PCI_DMA_TODEVICE); map_size[i+1] = frag->size; - if (dma_mapping_error(map[i+1])) { + if (pci_dma_mapping_error(mac->dma_pdev, map[i+1])) { nfrags = i; goto out_err_nolock; } diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index e7d48a352beb..e82b37bbd6c3 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -328,7 +328,7 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, qdev->lrg_buffer_len - QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -1919,7 +1919,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2454,7 +2454,7 @@ static int ql_send_map(struct ql3_adapter *qdev, */ map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -2487,7 +2487,7 @@ static int ql_send_map(struct ql3_adapter *qdev, sizeof(struct oal), PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", @@ -2514,7 +2514,7 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", qdev->ndev->name, err); @@ -2916,7 +2916,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 9dae40ccf048..86d77d05190a 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -2512,8 +2512,8 @@ static void stop_nic(struct s2io_nic *nic) * Return Value: * SUCCESS on success or an appropriate -ve value on failure. */ - -static int fill_rx_buffers(struct ring_info *ring, int from_card_up) +static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring, + int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2602,7 +2602,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp1->Buffer0_ptr)) goto pci_map_failed; rxdp->Control_2 = @@ -2636,7 +2637,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer0_ptr)) goto pci_map_failed; } else pci_dma_sync_single_for_device(ring->pdev, @@ -2655,7 +2657,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer2_ptr)) goto pci_map_failed; if (from_card_up) { @@ -2664,8 +2667,8 @@ static int fill_rx_buffers(struct ring_info *ring, int from_card_up) ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error - (rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(nic->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (ring->pdev, (dma_addr_t)(unsigned long) @@ -2806,9 +2809,9 @@ static void free_rx_buffers(struct s2io_nic *sp) } } -static int s2io_chk_rx_buffers(struct ring_info *ring) +static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring) { - if (fill_rx_buffers(ring, 0) == -ENOMEM) { + if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); } @@ -2848,7 +2851,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) return 0; pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); @@ -2882,7 +2885,7 @@ static int s2io_poll_inta(struct napi_struct *napi, int budget) for (i = 0; i < config->rx_ring_num; i++) { ring = &mac_control->rings[i]; ring_pkts_processed = rx_intr_handler(ring, budget); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(nic, ring); pkts_processed += ring_pkts_processed; budget -= ring_pkts_processed; if (budget <= 0) @@ -2939,7 +2942,8 @@ static void s2io_netpoll(struct net_device *dev) rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { + if (fill_rx_buffers(nic, &mac_control->rings[i], 0) == + -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -4235,14 +4239,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(txdp->Buffer_Pointer)) + if (pci_dma_mapping_error(sp->pdev, txdp->Buffer_Pointer)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -4345,7 +4349,7 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) netif_rx_schedule(dev, &ring->napi); } else { rx_intr_handler(ring, 0); - s2io_chk_rx_buffers(ring); + s2io_chk_rx_buffers(sp, ring); } return IRQ_HANDLED; @@ -4826,7 +4830,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) */ if (!config->napi) { for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(&mac_control->rings[i]); + s2io_chk_rx_buffers(sp, &mac_control->rings[i]); } writeq(sp->general_int_mask, &bar0->general_int_mask); readl(&bar0->general_int_status); @@ -6859,7 +6863,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp1->Buffer0_ptr)) goto memalloc_failed; rxdp->Host_Control = (unsigned long) (*skb); } @@ -6886,12 +6890,13 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) + if (pci_dma_mapping_error(sp->pdev, rxdp3->Buffer2_ptr)) goto memalloc_failed; rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer0_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6903,7 +6908,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { + if (pci_dma_mapping_error(sp->pdev, + rxdp3->Buffer1_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -7187,7 +7193,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(&mac_control->rings[i], 1); + ret = fill_rx_buffers(sp, &mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 601b001437c0..0d27dd39bc09 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -233,7 +233,7 @@ static inline int efx_init_rx_buffer_skb(struct efx_rx_queue *rx_queue, rx_buf->data, rx_buf->len, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(rx_buf->dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, rx_buf->dma_addr))) { dev_kfree_skb_any(rx_buf->skb); rx_buf->skb = NULL; return -EIO; @@ -275,7 +275,7 @@ static inline int efx_init_rx_buffer_page(struct efx_rx_queue *rx_queue, 0, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(dma_addr))) { + if (unlikely(pci_dma_mapping_error(efx->pci_dev, dma_addr))) { __free_pages(rx_buf->page, efx->rx_buffer_order); rx_buf->page = NULL; return -EIO; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index 5cdd082ab8f6..5e8374ab28ee 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -172,7 +172,7 @@ static inline int efx_enqueue_skb(struct efx_tx_queue *tx_queue, /* Process all fragments */ while (1) { - if (unlikely(pci_dma_mapping_error(dma_addr))) + if (unlikely(pci_dma_mapping_error(pci_dev, dma_addr))) goto pci_err; /* Store fields for marking in the per-fragment final @@ -661,7 +661,8 @@ efx_tsoh_heap_alloc(struct efx_tx_queue *tx_queue, size_t header_len) tsoh->dma_addr = pci_map_single(tx_queue->efx->pci_dev, TSOH_BUFFER(tsoh), header_len, PCI_DMA_TODEVICE); - if (unlikely(pci_dma_mapping_error(tsoh->dma_addr))) { + if (unlikely(pci_dma_mapping_error(tx_queue->efx->pci_dev, + tsoh->dma_addr))) { kfree(tsoh); return NULL; } @@ -863,7 +864,7 @@ static inline int tso_get_fragment(struct tso_state *st, struct efx_nic *efx, st->ifc.unmap_addr = pci_map_page(efx->pci_dev, page, page_off, len, PCI_DMA_TODEVICE); - if (likely(!pci_dma_mapping_error(st->ifc.unmap_addr))) { + if (likely(!pci_dma_mapping_error(efx->pci_dev, st->ifc.unmap_addr))) { st->ifc.unmap_len = len; st->ifc.len = len; st->ifc.dma_addr = st->ifc.unmap_addr; diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 00aa0b108cb9..b6435d0d71f9 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -452,7 +452,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, /* iommu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { dev_kfree_skb_any(descr->skb); descr->skb = NULL; if (netif_msg_rx_err(card) && net_ratelimit()) @@ -691,7 +691,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, unsigned long flags; buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(buf)) { + if (pci_dma_mapping_error(card->pdev, buf)) { if (netif_msg_tx_err(card) && net_ratelimit()) dev_err(&card->netdev->dev, "could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index a645e5028c14..8487ace9d2e3 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -506,7 +506,7 @@ static void *alloc_rxbuf_page(struct pci_dev *hwdev, dma_addr_t *dma_handle) return NULL; *dma_handle = pci_map_single(hwdev, buf, PAGE_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { free_page((unsigned long)buf); return NULL; } @@ -536,7 +536,7 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, return NULL; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(*dma_handle)) { + if (pci_dma_mapping_error(hwdev, *dma_handle)) { dev_kfree_skb_any(skb); return NULL; } diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 217d506527a9..d9769c527346 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1166,7 +1166,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) bf->skb = skb; bf->skbaddr = pci_map_single(sc->pdev, skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE); - if (unlikely(pci_dma_mapping_error(bf->skbaddr))) { + if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) { ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__); dev_kfree_skb(skb); bf->skb = NULL; @@ -1918,7 +1918,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] " "skbaddr %llx\n", skb, skb->data, skb->len, (unsigned long long)bf->skbaddr); - if (pci_dma_mapping_error(bf->skbaddr)) { + if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) { ATH5K_ERR(sc, "beacon DMA mapping failed\n"); return -EIO; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index c4a7c06793c5..61f8fdea2d96 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3525,7 +3525,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost) crq->msg_token = dma_map_single(dev, crq->msgs, PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(crq->msg_token)) + if (dma_mapping_error(dev, crq->msg_token)) goto map_failed; retrc = rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, @@ -3618,7 +3618,7 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) async_q->size * sizeof(*async_q->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(async_q->msg_token)) { + if (dma_mapping_error(dev, async_q->msg_token)) { dev_err(dev, "Failed to map async queue\n"); goto free_async_crq; } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 20000ec79b04..6b24b9cdb04c 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -859,7 +859,7 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) sizeof(hostdata->madapter_info), DMA_BIDIRECTIONAL); - if (dma_mapping_error(req->buffer)) { + if (dma_mapping_error(hostdata->dev, req->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "Unable to map request_buffer for " @@ -1407,7 +1407,7 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata, length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(host_config->buffer)) { + if (dma_mapping_error(hostdata->dev, host_config->buffer)) { if (!firmware_has_feature(FW_FEATURE_CMO)) dev_err(hostdata->dev, "dma_mapping error getting host config\n"); diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 3b9514c8f1f1..2e13ec00172a 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -564,7 +564,7 @@ static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(target->dev, queue->msg_token)) goto map_failed; err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 182146100dc1..462a8574dad9 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -253,7 +253,7 @@ static int rpavscsi_init_crq_queue(struct crq_queue *queue, queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); - if (dma_mapping_error(queue->msg_token)) + if (dma_mapping_error(hostdata->dev, queue->msg_token)) goto map_failed; gather_partition_info(); diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index e81d59d78910..0c7165660853 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -313,14 +313,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) xfer->tx_dma = dma_map_single(dev, (void *) xfer->tx_buf, xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(xfer->tx_dma)) + if (dma_mapping_error(dev, xfer->tx_dma)) return -ENOMEM; } if (xfer->rx_buf) { xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(xfer->rx_dma)) { + if (dma_mapping_error(dev, xfer->rx_dma)) { if (xfer->tx_buf) dma_unmap_single(dev, xfer->tx_dma, xfer->len, diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c index 9149689c79d9..87b73e0169c5 100644 --- a/drivers/spi/au1550_spi.c +++ b/drivers/spi/au1550_spi.c @@ -334,7 +334,7 @@ static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) hw->dma_rx_tmpbuf_size = size; hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, size, DMA_FROM_DEVICE); - if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) { + if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) { kfree(hw->dma_rx_tmpbuf); hw->dma_rx_tmpbuf = 0; hw->dma_rx_tmpbuf_size = 0; @@ -378,7 +378,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_rx_addr = dma_map_single(hw->dev, (void *)t->rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(dma_rx_addr)) + if (dma_mapping_error(hw->dev, dma_rx_addr)) dev_err(hw->dev, "rx dma map error\n"); } } else { @@ -401,7 +401,7 @@ static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) dma_tx_addr = dma_map_single(hw->dev, (void *)t->tx_buf, t->len, DMA_TO_DEVICE); - if (dma_mapping_error(dma_tx_addr)) + if (dma_mapping_error(hw->dev, dma_tx_addr)) dev_err(hw->dev, "tx dma map error\n"); } } else { diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index b1cc148036c1..f6f987bb71ca 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c @@ -836,7 +836,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (tx_buf != NULL) { t->tx_dma = dma_map_single(&spi->dev, (void *) tx_buf, len, DMA_TO_DEVICE); - if (dma_mapping_error(t->tx_dma)) { + if (dma_mapping_error(&spi->dev, t->tx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'T', len); return -EINVAL; @@ -845,7 +845,7 @@ static int omap2_mcspi_transfer(struct spi_device *spi, struct spi_message *m) if (rx_buf != NULL) { t->rx_dma = dma_map_single(&spi->dev, rx_buf, t->len, DMA_FROM_DEVICE); - if (dma_mapping_error(t->rx_dma)) { + if (dma_mapping_error(&spi->dev, t->rx_dma)) { dev_dbg(&spi->dev, "dma %cX %d bytes error\n", 'R', len); if (tx_buf != NULL) diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 0c452c46ab07..067299d6d192 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -353,7 +353,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->rx_dma = dma_map_single(dev, drv_data->rx, drv_data->rx_map_len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return 0; /* Stream map the tx buffer */ @@ -361,7 +361,7 @@ static int map_dma_buffers(struct driver_data *drv_data) drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { dma_unmap_single(dev, drv_data->rx_dma, drv_data->rx_map_len, DMA_FROM_DEVICE); return 0; diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 54ac7bea5f8c..6fb77fcc4971 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c @@ -491,7 +491,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) + if (dma_mapping_error(dev, drv_data->tx_dma)) return -1; drv_data->tx_dma_needs_unmap = 1; @@ -516,7 +516,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->len, DMA_FROM_DEVICE); - if (dma_mapping_error(drv_data->rx_dma)) + if (dma_mapping_error(dev, drv_data->rx_dma)) return -1; drv_data->rx_dma_needs_unmap = 1; } @@ -534,7 +534,7 @@ static int map_dma_buffers(struct driver_data *drv_data) buf, drv_data->tx_map_len, DMA_TO_DEVICE); - if (dma_mapping_error(drv_data->tx_dma)) { + if (dma_mapping_error(dev, drv_data->tx_dma)) { if (drv_data->rx_dma) { dma_unmap_single(dev, drv_data->rx_dma, diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index db351d1296f4..a5801ae02e4b 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -24,8 +24,8 @@ pci_unmap_sg(alpha_gendev_to_pci(dev), sg, nents, dir) #define dma_supported(dev, mask) \ pci_dma_supported(alpha_gendev_to_pci(dev), mask) -#define dma_mapping_error(addr) \ - pci_dma_mapping_error(addr) +#define dma_mapping_error(dev, addr) \ + pci_dma_mapping_error(alpha_gendev_to_pci(dev), addr) #else /* no PCI - no IOMMU. */ @@ -45,7 +45,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_unmap_page(dev, addr, size, dir) ((void)0) #define dma_unmap_sg(dev, sg, nents, dir) ((void)0) -#define dma_mapping_error(addr) (0) +#define dma_mapping_error(dev, addr) (0) #endif /* !CONFIG_PCI */ diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index d31fd49ff79a..2a14302c17a3 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -106,7 +106,7 @@ extern dma_addr_t pci_map_page(struct pci_dev *, struct page *, /* Test for pci_map_single or pci_map_page having generated an error. */ static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index e99406a7bece..f41335ba6337 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -56,7 +56,7 @@ static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) /* * DMA errors are defined by all-bits-set in the DMA address. */ -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == ~0; } diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 57dc672bab8e..0399359ab5d8 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -35,7 +35,7 @@ static inline int dma_set_mask(struct device *dev, u64 dma_mask) /* * dma_map_single can't fail as it is implemented now. */ -static inline int dma_mapping_error(dma_addr_t addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t addr) { return 0; } diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index edc8d1bfaae2..cb2fb25ff8d9 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -120,7 +120,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h index 2e8966ca030d..b2898877c07b 100644 --- a/include/asm-frv/dma-mapping.h +++ b/include/asm-frv/dma-mapping.h @@ -126,7 +126,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-generic/dma-mapping-broken.h b/include/asm-generic/dma-mapping-broken.h index e2468f894d2a..82cd0cb1c3fe 100644 --- a/include/asm-generic/dma-mapping-broken.h +++ b/include/asm-generic/dma-mapping-broken.h @@ -61,7 +61,7 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, #define dma_sync_sg_for_device dma_sync_sg_for_cpu extern int -dma_mapping_error(dma_addr_t dma_addr); +dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index 783ab9944d70..189486c3f92e 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -144,9 +144,9 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { - return pci_dma_mapping_error(dma_addr); + return pci_dma_mapping_error(to_pci_dev(dev), dma_addr); } diff --git a/include/asm-generic/pci-dma-compat.h b/include/asm-generic/pci-dma-compat.h index 25c10e96b2b7..37b3706226e7 100644 --- a/include/asm-generic/pci-dma-compat.h +++ b/include/asm-generic/pci-dma-compat.h @@ -99,9 +99,9 @@ pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, } static inline int -pci_dma_mapping_error(dma_addr_t dma_addr) +pci_dma_mapping_error(struct pci_dev *pdev, dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #endif diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 0721a5e8271e..a6d50c77b6bf 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -54,7 +54,7 @@ typedef void ia64_mv_dma_sync_single_for_cpu (struct device *, dma_addr_t, size_ typedef void ia64_mv_dma_sync_sg_for_cpu (struct device *, struct scatterlist *, int, int); typedef void ia64_mv_dma_sync_single_for_device (struct device *, dma_addr_t, size_t, int); typedef void ia64_mv_dma_sync_sg_for_device (struct device *, struct scatterlist *, int, int); -typedef int ia64_mv_dma_mapping_error (dma_addr_t dma_addr); +typedef int ia64_mv_dma_mapping_error(struct device *, dma_addr_t dma_addr); typedef int ia64_mv_dma_supported (struct device *, u64); typedef dma_addr_t ia64_mv_dma_map_single_attrs (struct device *, void *, size_t, int, struct dma_attrs *); diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index a26cdeb46a57..91f7944333d4 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -84,7 +84,7 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *s { } -static inline int dma_mapping_error(dma_addr_t handle) +static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) { return 0; } diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 230b3f1b69b1..c64afb40cd06 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -42,7 +42,7 @@ extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, enum dma_data_direction direction); -extern int dma_mapping_error(dma_addr_t dma_addr); +extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); extern int dma_supported(struct device *dev, u64 mask); static inline int diff --git a/include/asm-mn10300/dma-mapping.h b/include/asm-mn10300/dma-mapping.h index 7c882fca9ec8..ccae8f6c6326 100644 --- a/include/asm-mn10300/dma-mapping.h +++ b/include/asm-mn10300/dma-mapping.h @@ -182,7 +182,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, } static inline -int dma_mapping_error(dma_addr_t dma_addr) +int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index c6c0e9ff6bde..53af696f23d2 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -248,6 +248,6 @@ void * sba_get_iommu(struct parisc_device *dev); #endif /* At the moment, we panic on error for IOMMU resource exaustion */ -#define dma_mapping_error(x) 0 +#define dma_mapping_error(dev, x) 0 #endif diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 74c549780987..c7ca45f97dd2 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -415,7 +415,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { #ifdef CONFIG_PPC64 return (dma_addr == DMA_ERROR_CODE); diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 22cc419389fe..6c0b8a2de143 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -171,7 +171,7 @@ static inline int dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return dma_addr == 0; } diff --git a/include/asm-sparc/dma-mapping_64.h b/include/asm-sparc/dma-mapping_64.h index 38cbec76a33f..bfa64f9702d5 100644 --- a/include/asm-sparc/dma-mapping_64.h +++ b/include/asm-sparc/dma-mapping_64.h @@ -135,7 +135,7 @@ static inline void dma_sync_sg_for_device(struct device *dev, /* No flushing needed to sync cpu writes to the device. */ } -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return (dma_addr == DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_32.h b/include/asm-sparc/pci_32.h index b93b6c79e08f..0ee949d220c0 100644 --- a/include/asm-sparc/pci_32.h +++ b/include/asm-sparc/pci_32.h @@ -154,7 +154,8 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, #define PCI_DMA_ERROR_CODE (~(dma_addr_t)0x0) -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { return (dma_addr == PCI_DMA_ERROR_CODE); } diff --git a/include/asm-sparc/pci_64.h b/include/asm-sparc/pci_64.h index f59f2571295b..4f79a54948f6 100644 --- a/include/asm-sparc/pci_64.h +++ b/include/asm-sparc/pci_64.h @@ -140,9 +140,10 @@ extern int pci_dma_supported(struct pci_dev *hwdev, u64 mask); #define PCI64_REQUIRED_MASK (~(dma64_addr_t)0) #define PCI64_ADDR_BASE 0xfffc000000000000UL -static inline int pci_dma_mapping_error(dma_addr_t dma_addr) +static inline int pci_dma_mapping_error(struct pci_dev *pdev, + dma_addr_t dma_addr) { - return dma_mapping_error(dma_addr); + return dma_mapping_error(&pdev->dev, dma_addr); } #ifdef CONFIG_PCI diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h index 87a715367a1b..3c034f48fdb0 100644 --- a/include/asm-x86/device.h +++ b/include/asm-x86/device.h @@ -5,6 +5,9 @@ struct dev_archdata { #ifdef CONFIG_ACPI void *acpi_handle; #endif +#ifdef CONFIG_X86_64 +struct dma_mapping_ops *dma_ops; +#endif #ifdef CONFIG_DMAR void *iommu; /* hook for IOMMU specific extension */ #endif diff --git a/include/asm-x86/dma-mapping.h b/include/asm-x86/dma-mapping.h index c2ddd3d1b883..0eaa9bf6011f 100644 --- a/include/asm-x86/dma-mapping.h +++ b/include/asm-x86/dma-mapping.h @@ -17,7 +17,8 @@ extern int panic_on_overflow; extern int force_iommu; struct dma_mapping_ops { - int (*mapping_error)(dma_addr_t dma_addr); + int (*mapping_error)(struct device *dev, + dma_addr_t dma_addr); void* (*alloc_coherent)(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t gfp); void (*free_coherent)(struct device *dev, size_t size, @@ -56,14 +57,32 @@ struct dma_mapping_ops { int is_phys; }; -extern const struct dma_mapping_ops *dma_ops; +extern struct dma_mapping_ops *dma_ops; -static inline int dma_mapping_error(dma_addr_t dma_addr) +static inline struct dma_mapping_ops *get_dma_ops(struct device *dev) { - if (dma_ops->mapping_error) - return dma_ops->mapping_error(dma_addr); +#ifdef CONFIG_X86_32 + return dma_ops; +#else + if (unlikely(!dev) || !dev->archdata.dma_ops) + return dma_ops; + else + return dev->archdata.dma_ops; +#endif +} + +/* Make sure we keep the same behaviour */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ +#ifdef CONFIG_X86_32 + return 0; +#else + struct dma_mapping_ops *ops = get_dma_ops(dev); + if (ops->mapping_error) + return ops->mapping_error(dev, dma_addr); return (dma_addr == bad_dma_address); +#endif } #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) @@ -83,44 +102,53 @@ static inline dma_addr_t dma_map_single(struct device *hwdev, void *ptr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction); + return ops->map_single(hwdev, virt_to_phys(ptr), size, direction); } static inline void dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_single) - dma_ops->unmap_single(dev, addr, size, direction); + if (ops->unmap_single) + ops->unmap_single(dev, addr, size, direction); } static inline int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_sg(hwdev, sg, nents, direction); + return ops->map_sg(hwdev, sg, nents, direction); } static inline void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->unmap_sg) - dma_ops->unmap_sg(hwdev, sg, nents, direction); + if (ops->unmap_sg) + ops->unmap_sg(hwdev, sg, nents, direction); } static inline void dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_cpu) - dma_ops->sync_single_for_cpu(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_cpu) + ops->sync_single_for_cpu(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -128,10 +156,11 @@ static inline void dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_for_device) - dma_ops->sync_single_for_device(hwdev, dma_handle, size, - direction); + if (ops->sync_single_for_device) + ops->sync_single_for_device(hwdev, dma_handle, size, direction); flush_write_buffers(); } @@ -139,11 +168,12 @@ static inline void dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_cpu) - dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, - size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_cpu) + ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, + size, direction); flush_write_buffers(); } @@ -152,11 +182,12 @@ dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle, unsigned long offset, size_t size, int direction) { - BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_single_range_for_device) - dma_ops->sync_single_range_for_device(hwdev, dma_handle, - offset, size, direction); + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); + if (ops->sync_single_range_for_device) + ops->sync_single_range_for_device(hwdev, dma_handle, + offset, size, direction); flush_write_buffers(); } @@ -164,9 +195,11 @@ static inline void dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_cpu) - dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_cpu) + ops->sync_sg_for_cpu(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -174,9 +207,11 @@ static inline void dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, int nelems, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(hwdev); + BUG_ON(!valid_dma_direction(direction)); - if (dma_ops->sync_sg_for_device) - dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction); + if (ops->sync_sg_for_device) + ops->sync_sg_for_device(hwdev, sg, nelems, direction); flush_write_buffers(); } @@ -185,9 +220,11 @@ static inline dma_addr_t dma_map_page(struct device *dev, struct page *page, size_t offset, size_t size, int direction) { + struct dma_mapping_ops *ops = get_dma_ops(dev); + BUG_ON(!valid_dma_direction(direction)); - return dma_ops->map_single(dev, page_to_phys(page)+offset, - size, direction); + return ops->map_single(dev, page_to_phys(page) + offset, + size, direction); } static inline void dma_unmap_page(struct device *dev, dma_addr_t addr, diff --git a/include/asm-x86/swiotlb.h b/include/asm-x86/swiotlb.h index c706a7442633..2730b351afcf 100644 --- a/include/asm-x86/swiotlb.h +++ b/include/asm-x86/swiotlb.h @@ -35,7 +35,7 @@ extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction); -extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr); +extern int swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); extern void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle); extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index 3c7d537dd15d..51882ae3db4d 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -139,7 +139,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems, consistent_sync(sg_virt(sg), sg->length, dir); } static inline int -dma_mapping_error(dma_addr_t dma_addr) +dma_mapping_error(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 7d51cbca49ab..75ae6d8aba4f 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -758,7 +758,7 @@ static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, } dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(dma_addr)) { + if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { #ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 if ((sizeof(dma_addr_t) > 4) && c->pae_support) { *mptr++ = cpu_to_le32(0x7C020002); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 4bf8cade9dbc..e530026eedf7 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -427,9 +427,9 @@ static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: - return pci_dma_mapping_error(addr); + return pci_dma_mapping_error(dev->bus->host_pci, addr); case SSB_BUSTYPE_SSB: - return dma_mapping_error(addr); + return dma_mapping_error(dev->dev, addr); default: __ssb_dma_not_implemented(dev); } diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 90b529f7a154..936e333e7ce5 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1590,7 +1590,7 @@ static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr) { if (dev->dma_ops) return dev->dma_ops->mapping_error(dev, dma_addr); - return dma_mapping_error(dma_addr); + return dma_mapping_error(dev->dma_device, dma_addr); } /** diff --git a/lib/swiotlb.c b/lib/swiotlb.c index d568894df8cc..977edbdbc1de 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -492,7 +492,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, */ dma_addr_t handle; handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE); - if (swiotlb_dma_mapping_error(handle)) + if (swiotlb_dma_mapping_error(hwdev, handle)) return NULL; ret = bus_to_virt(handle); @@ -824,7 +824,7 @@ swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, } int -swiotlb_dma_mapping_error(dma_addr_t dma_addr) +swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr) { return (dma_addr == virt_to_bus(io_tlb_overflow_buffer)); } diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index a19b22b452a3..84d328329d98 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -169,7 +169,8 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, (void *) vec->sge[xdr_sge_no].iov_base + sge_off, sge_bytes, DMA_TO_DEVICE); - if (dma_mapping_error(sge[sge_no].addr)) + if (dma_mapping_error(xprt->sc_cm_id->device->dma_device, + sge[sge_no].addr)) goto err; sge_off = 0; sge_no++; -- cgit v1.2.3 From feb75f07102a85026d41e2c4e4113c34dd035c30 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 27 Jul 2008 06:30:21 -0300 Subject: V4L/DVB (8504): s2255drv: add missing header Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/s2255drv.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 9ff5403483e5..92dfb1845ff4 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 1052efe0fc69130d9d6a44bc9ceecd229221d9a1 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 09:01:24 -0300 Subject: V4L/DVB (8505): saa7134-empress.c: fix deadlock ts_release() locked a mutex that videobuf_stop() also tried to obtain. But ts_release() shouldn't hold that mutex at all. Make empress_users atomic as well to prevent possible race condition. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 12 ++++-------- drivers/media/video/saa7134/saa7134.h | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 8b3f95167781..2ecfbd1b41fc 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -89,14 +89,14 @@ static int ts_open(struct inode *inode, struct file *file) err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) goto done_up; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); - dev->empress_users++; + atomic_inc(&dev->empress_users); file->private_data = dev; err = 0; @@ -110,8 +110,6 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); - videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); @@ -122,9 +120,7 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - dev->empress_users--; - - mutex_unlock(&dev->empress_tsq.vb_lock); + atomic_dec(&dev->empress_users); return 0; } @@ -447,7 +443,7 @@ static void empress_signal_update(struct work_struct *work) ts_reset_encoder(dev); } else { dprintk("video signal acquired\n"); - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) ts_init_encoder(dev); } } diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index ade4e19799e9..ed20dd56379c 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -561,7 +561,7 @@ struct saa7134_dev { /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; struct videobuf_queue empress_tsq; - unsigned int empress_users; + atomic_t empress_users; struct work_struct empress_workqueue; int empress_started; -- cgit v1.2.3 From 531d83a3d39280d191e2b1f0b540dbad22731579 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 09:04:06 -0300 Subject: V4L/DVB (8506): empress: fix control handling oops Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/saa7134/saa7134-empress.c | 20 ++++++++++++-- drivers/media/video/saa7134/saa7134-video.c | 40 +++++++++++++++++++-------- drivers/media/video/saa7134/saa7134.h | 4 +-- 3 files changed, 48 insertions(+), 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 2ecfbd1b41fc..cd52d5be404d 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -329,6 +329,22 @@ static int empress_g_ext_ctrls(struct file *file, void *priv, return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls); } +static int empress_g_ctrl(struct file *file, void *priv, + struct v4l2_control *c) +{ + struct saa7134_dev *dev = file->private_data; + + return saa7134_g_ctrl_internal(dev, NULL, c); +} + +static int empress_s_ctrl(struct file *file, void *priv, + struct v4l2_control *c) +{ + struct saa7134_dev *dev = file->private_data; + + return saa7134_s_ctrl_internal(dev, NULL, c); +} + static int empress_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c) { @@ -415,8 +431,8 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_queryctrl = empress_queryctrl, .vidioc_querymenu = empress_querymenu, - .vidioc_g_ctrl = saa7134_g_ctrl, - .vidioc_s_ctrl = saa7134_s_ctrl, + .vidioc_g_ctrl = empress_g_ctrl, + .vidioc_s_ctrl = empress_s_ctrl, }; /* ----------------------------------------------------------- */ diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index 5e9cfc891be8..eb824897416b 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -1112,10 +1112,8 @@ static struct videobuf_queue_ops video_qops = { /* ------------------------------------------------------------------ */ -int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) +int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; const struct v4l2_queryctrl* ctrl; ctrl = ctrl_by_id(c->id); @@ -1160,20 +1158,31 @@ int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) } return 0; } -EXPORT_SYMBOL_GPL(saa7134_g_ctrl); +EXPORT_SYMBOL_GPL(saa7134_g_ctrl_internal); + +static int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) +{ + struct saa7134_fh *fh = priv; + + return saa7134_g_ctrl_internal(fh->dev, fh, c); +} -int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c) +int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c) { const struct v4l2_queryctrl* ctrl; - struct saa7134_fh *fh = f; - struct saa7134_dev *dev = fh->dev; unsigned long flags; int restart_overlay = 0; - int err = -EINVAL; + int err; - err = v4l2_prio_check(&dev->prio, &fh->prio); - if (0 != err) - return err; + /* When called from the empress code fh == NULL. + That needs to be fixed somehow, but for now this is + good enough. */ + if (fh) { + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; + } + err = -EINVAL; mutex_lock(&dev->lock); @@ -1274,7 +1283,14 @@ error: mutex_unlock(&dev->lock); return err; } -EXPORT_SYMBOL_GPL(saa7134_s_ctrl); +EXPORT_SYMBOL_GPL(saa7134_s_ctrl_internal); + +static int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c) +{ + struct saa7134_fh *fh = f; + + return saa7134_s_ctrl_internal(fh->dev, fh, c); +} /* ------------------------------------------------------------------ */ diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index ed20dd56379c..a0884f639f65 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -663,8 +663,8 @@ extern unsigned int video_debug; extern struct video_device saa7134_video_template; extern struct video_device saa7134_radio_template; -int saa7134_g_ctrl(struct file *file, void *priv, struct v4l2_control *c); -int saa7134_s_ctrl(struct file *file, void *f, struct v4l2_control *c); +int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); +int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); int saa7134_videoport_init(struct saa7134_dev *dev); -- cgit v1.2.3 From 353facd4ab5acc6e9d83985eec9ca17e5d0cb470 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 18:28:26 -0300 Subject: V4L/DVB (8509): pvrusb2: fix device descriptions for HVR-1900 & HVR-1950 Acked-by: Mike Isely Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pvrusb2/pvrusb2-devattr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c index e3b051197087..88e175168438 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c +++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c @@ -330,7 +330,7 @@ static const char *pvr2_fw1_names_73xxx[] = { }; static const struct pvr2_device_desc pvr2_device_73xxx = { - .description = "WinTV PVR USB2 Model Category 73xxx", + .description = "WinTV HVR-1900 Model Category 73xxx", .shortname = "73xxx", .client_modules.lst = pvr2_client_73xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx), @@ -439,7 +439,7 @@ static const char *pvr2_fw1_names_75xxx[] = { }; static const struct pvr2_device_desc pvr2_device_750xx = { - .description = "WinTV PVR USB2 Model Category 750xx", + .description = "WinTV HVR-1950 Model Category 750xx", .shortname = "750xx", .client_modules.lst = pvr2_client_75xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), @@ -461,7 +461,7 @@ static const struct pvr2_device_desc pvr2_device_750xx = { }; static const struct pvr2_device_desc pvr2_device_751xx = { - .description = "WinTV PVR USB2 Model Category 751xx", + .description = "WinTV HVR-1950 Model Category 751xx", .shortname = "751xx", .client_modules.lst = pvr2_client_75xxx, .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx), -- cgit v1.2.3 From c6edaf1674d3c17770b1c9966306b802adb21a2b Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 23 Jul 2008 03:24:06 -0300 Subject: V4L/DVB (8511): gspca: Get the card name of QUERYCAP from the usb product name. This is a preliminary for using the driver_info of the struct usb_device_id to handle the specific per webcam information. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 2a416cf205aa..ab053a26023e 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -834,7 +834,16 @@ static int vidioc_querycap(struct file *file, void *priv, memset(cap, 0, sizeof *cap); strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); - strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); +/* strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); */ + if (gspca_dev->dev->product != NULL) { + strncpy(cap->card, gspca_dev->dev->product, + sizeof cap->card); + } else { + snprintf(cap->card, sizeof cap->card, + "USB Camera (%04x:%04x)", + le16_to_cpu(gspca_dev->dev->descriptor.idVendor), + le16_to_cpu(gspca_dev->dev->descriptor.idProduct)); + } strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name, sizeof cap->bus_info); cap->version = DRIVER_VERSION_NUMBER; -- cgit v1.2.3 From 07767ebda385956bd2b193f9820de719475bfe6e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Wed, 23 Jul 2008 03:39:42 -0300 Subject: V4L/DVB (8512): gspca: Do not use the driver_info field of usb_device_id. The field driver_info will be used to handle the specific per webcam information. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 1 - drivers/media/video/gspca/etoms.c | 1 - drivers/media/video/gspca/mars.c | 1 - drivers/media/video/gspca/ov519.c | 1 - drivers/media/video/gspca/pac7311.c | 1 - drivers/media/video/gspca/sonixj.c | 1 - drivers/media/video/gspca/spca500.c | 1 - drivers/media/video/gspca/spca501.c | 1 - drivers/media/video/gspca/spca505.c | 1 - drivers/media/video/gspca/spca506.c | 1 - drivers/media/video/gspca/spca508.c | 1 - drivers/media/video/gspca/stk014.c | 1 - drivers/media/video/gspca/sunplus.c | 1 - drivers/media/video/gspca/t613.c | 1 - drivers/media/video/gspca/tv8532.c | 1 - drivers/media/video/gspca/vc032x.c | 1 - drivers/media/video/gspca/zc3xx.c | 1 - 17 files changed, 17 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index 18c1dec2f769..f5ef7599d3ca 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -815,7 +815,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 6f2f1d24b7eb..7529bb0bf6fc 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -617,7 +617,6 @@ static int sd_config(struct gspca_dev *gspca_dev, /* break; */ } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 1; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index a4706162f415..2d47876bfec9 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -137,7 +137,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index f15bec7080c9..9109cbbb6fc1 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -1372,7 +1372,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; } - cam->dev_name = (char *) id->driver_info; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value; diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 2267ae7cb87f..ad802a72cf04 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -263,7 +263,6 @@ static int sd_config(struct gspca_dev *gspca_dev, reg_w(gspca_dev, 0x3e, 0x20); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x05; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 35b1a3ee4c3f..3f8418c7e5fd 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -976,7 +976,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 8c83823745f0..2b8ae8095b0e 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -728,7 +728,6 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index 6537acee89dd..a695c42e10cf 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -1973,7 +1973,6 @@ static int sd_config(struct gspca_dev *gspca_dev, break; } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 1bb23d03f048..adff24f503bb 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -662,7 +662,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; if (sd->subtype != IntelPCCameraPro) diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 40e8541b2b89..36dc13c11cbb 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -307,7 +307,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 362f645d08c6..eff5eda70e68 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1541,7 +1541,6 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index 90efde17b08b..f6390b49f693 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -296,7 +296,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct cam *cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x02; gspca_dev->cam.cam_mode = vga_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode); diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 53e20275f26d..030cb18b3557 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -1021,7 +1021,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; switch (sd->bridge) { diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index fc1c62e5a2fd..f7ea9a742725 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -422,7 +422,6 @@ static int sd_config(struct gspca_dev *gspca_dev, struct cam *cam; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; cam->cam_mode = vga_mode_t16; diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index cb2d9da2a224..b024aca9b102 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -246,7 +246,6 @@ static int sd_config(struct gspca_dev *gspca_dev, tv_8532WriteEEprom(gspca_dev); cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 1; cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index e306ac420298..46cff48e6297 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -1438,7 +1438,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x02; if (sd->bridge == BRIDGE_VC0321) { cam->cam_mode = vc0321_mode; diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index f8d6f1780a45..acd538da0784 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7153,7 +7153,6 @@ static int sd_config(struct gspca_dev *gspca_dev, } cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; /*fixme:test*/ gspca_dev->nbalt--; -- cgit v1.2.3 From 9d64fdb15b1b9ce9144cfde4001e9194ccde42d1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Fri, 25 Jul 2008 08:53:03 -0300 Subject: V4L/DVB (8513): gspca: Set the specific per webcam information in driver_info. This patch removes a big part of the code run at probe time. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/conex.c | 3 +- drivers/media/video/gspca/etoms.c | 24 +-- drivers/media/video/gspca/mars.c | 3 +- drivers/media/video/gspca/ov519.c | 27 ++- drivers/media/video/gspca/pac207.c | 19 +- drivers/media/video/gspca/pac7311.c | 16 +- drivers/media/video/gspca/sonixj.c | 243 +++++-------------------- drivers/media/video/gspca/spca500.c | 133 ++------------ drivers/media/video/gspca/spca501.c | 69 +------ drivers/media/video/gspca/spca505.c | 29 +-- drivers/media/video/gspca/spca506.c | 10 +- drivers/media/video/gspca/spca508.c | 67 +------ drivers/media/video/gspca/spca561.c | 57 ++---- drivers/media/video/gspca/stk014.c | 3 +- drivers/media/video/gspca/sunplus.c | 349 ++++++++---------------------------- drivers/media/video/gspca/t613.c | 3 +- drivers/media/video/gspca/tv8532.c | 11 +- drivers/media/video/gspca/vc032x.c | 38 +--- drivers/media/video/gspca/zc3xx.c | 125 ++++++------- 19 files changed, 284 insertions(+), 945 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c index f5ef7599d3ca..44b0bffeb20e 100644 --- a/drivers/media/video/gspca/conex.c +++ b/drivers/media/video/gspca/conex.c @@ -1007,9 +1007,8 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0572, 0x0041), DVNM("Creative Notebook cx11646")}, + {USB_DEVICE(0x0572, 0x0041)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c index 7529bb0bf6fc..c8c2f02fcf00 100644 --- a/drivers/media/video/gspca/etoms.c +++ b/drivers/media/video/gspca/etoms.c @@ -599,25 +599,10 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; -/* switch (vendor) { */ -/* case 0x102c: * Etoms */ - switch (product) { - case 0x6151: - sd->sensor = SENSOR_PAS106; /* Etoms61x151 */ - break; - case 0x6251: - sd->sensor = SENSOR_TAS5130CXX; /* Etoms61x251 */ - break; -/* } */ -/* break; */ - } + cam = &gspca_dev->cam; cam->epaddr = 1; + sd->sensor = id->driver_info; if (sd->sensor == SENSOR_PAS106) { cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; @@ -907,12 +892,11 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_ET61X251 - {USB_DEVICE(0x102c, 0x6151), DVNM("Qcam Sangha CIF")}, + {USB_DEVICE(0x102c, 0x6151), .driver_info = SENSOR_PAS106}, #endif - {USB_DEVICE(0x102c, 0x6251), DVNM("Qcam xxxxxx VGA")}, + {USB_DEVICE(0x102c, 0x6251), .driver_info = SENSOR_TAS5130CXX}, {} }; diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c index 2d47876bfec9..21c4ee56a10a 100644 --- a/drivers/media/video/gspca/mars.c +++ b/drivers/media/video/gspca/mars.c @@ -420,9 +420,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x050f), DVNM("Mars-Semi Pc-Camera")}, + {USB_DEVICE(0x093a, 0x050f)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 9109cbbb6fc1..83139efc4629 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c @@ -2125,21 +2125,20 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4052), DVNM("Creative Live! VISTA IM")}, - {USB_DEVICE(0x041e, 0x405f), DVNM("Creative Live! VISTA VF0330")}, - {USB_DEVICE(0x041e, 0x4060), DVNM("Creative Live! VISTA VF0350")}, - {USB_DEVICE(0x041e, 0x4061), DVNM("Creative Live! VISTA VF0400")}, - {USB_DEVICE(0x041e, 0x4064), DVNM("Creative Live! VISTA VF0420")}, - {USB_DEVICE(0x041e, 0x4068), DVNM("Creative Live! VISTA VF0470")}, - {USB_DEVICE(0x045e, 0x028c), DVNM("Microsoft xbox cam")}, - {USB_DEVICE(0x054c, 0x0154), DVNM("Sonny toy4")}, - {USB_DEVICE(0x054c, 0x0155), DVNM("Sonny toy5")}, - {USB_DEVICE(0x05a9, 0x0519), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x0530), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x4519), DVNM("OmniVision")}, - {USB_DEVICE(0x05a9, 0x8519), DVNM("OmniVision")}, + {USB_DEVICE(0x041e, 0x4052)}, + {USB_DEVICE(0x041e, 0x405f)}, + {USB_DEVICE(0x041e, 0x4060)}, + {USB_DEVICE(0x041e, 0x4061)}, + {USB_DEVICE(0x041e, 0x4064)}, + {USB_DEVICE(0x041e, 0x4068)}, + {USB_DEVICE(0x045e, 0x028c)}, + {USB_DEVICE(0x054c, 0x0154)}, + {USB_DEVICE(0x054c, 0x0155)}, + {USB_DEVICE(0x05a9, 0x0519)}, + {USB_DEVICE(0x05a9, 0x0530)}, + {USB_DEVICE(0x05a9, 0x4519)}, + {USB_DEVICE(0x05a9, 0x8519)}, {} }; #undef DVNAME diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c index f790746370d7..7ef18d578811 100644 --- a/drivers/media/video/gspca/pac207.c +++ b/drivers/media/video/gspca/pac207.c @@ -570,17 +570,16 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x4028), DVNM("Creative Webcam Vista Plus")}, - {USB_DEVICE(0x093a, 0x2460), DVNM("Q-Tec Webcam 100")}, - {USB_DEVICE(0x093a, 0x2463), DVNM("Philips spc200nc pac207")}, - {USB_DEVICE(0x093a, 0x2464), DVNM("Labtec Webcam 1200")}, - {USB_DEVICE(0x093a, 0x2468), DVNM("PAC207")}, - {USB_DEVICE(0x093a, 0x2470), DVNM("Genius GF112")}, - {USB_DEVICE(0x093a, 0x2471), DVNM("Genius VideoCam GE111")}, - {USB_DEVICE(0x093a, 0x2472), DVNM("Genius VideoCam GE110")}, - {USB_DEVICE(0x2001, 0xf115), DVNM("D-Link DSB-C120")}, + {USB_DEVICE(0x041e, 0x4028)}, + {USB_DEVICE(0x093a, 0x2460)}, + {USB_DEVICE(0x093a, 0x2463)}, + {USB_DEVICE(0x093a, 0x2464)}, + {USB_DEVICE(0x093a, 0x2468)}, + {USB_DEVICE(0x093a, 0x2470)}, + {USB_DEVICE(0x093a, 0x2471)}, + {USB_DEVICE(0x093a, 0x2472)}, + {USB_DEVICE(0x2001, 0xf115)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index ad802a72cf04..ea3d7021f401 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -709,16 +709,14 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x093a, 0x2600), DVNM("Typhoon")}, - {USB_DEVICE(0x093a, 0x2601), DVNM("Philips SPC610NC")}, - {USB_DEVICE(0x093a, 0x2603), DVNM("PAC7312")}, - {USB_DEVICE(0x093a, 0x2608), DVNM("Trust WB-3300p")}, - {USB_DEVICE(0x093a, 0x260e), DVNM("Gigaware VGA PC Camera")}, - /* and also ', Trust WB-3350p, SIGMA cam 2350' */ - {USB_DEVICE(0x093a, 0x260f), DVNM("SnakeCam")}, - {USB_DEVICE(0x093a, 0x2621), DVNM("PAC731x")}, + {USB_DEVICE(0x093a, 0x2600)}, + {USB_DEVICE(0x093a, 0x2601)}, + {USB_DEVICE(0x093a, 0x2603)}, + {USB_DEVICE(0x093a, 0x2608)}, + {USB_DEVICE(0x093a, 0x260e)}, + {USB_DEVICE(0x093a, 0x260f)}, + {USB_DEVICE(0x093a, 0x2621)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 3f8418c7e5fd..46f2cf66d48f 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -795,191 +795,16 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; - - product = id->idProduct; - sd->sensor = -1; - switch (id->idVendor) { - case 0x0458: /* Genius */ -/* switch (product) { - case 0x7025: */ - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; -/* break; - } */ - break; - case 0x045e: -/* switch (product) { - case 0x00f5: - case 0x00f7: */ - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; -/* break; - } */ - break; - case 0x0471: /* Philips */ -/* switch (product) { - case 0x0327: - case 0x0328: - case 0x0330: */ - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; -/* break; - } */ - break; - case 0x0c45: /* Sonix */ - switch (product) { - case 0x6040: - sd->bridge = BRIDGE_SN9C102P; -/* sd->sensor = SENSOR_MI0360; * from BW600.inf */ -/*fixme: MI0360 base=5d ? */ - sd->sensor = SENSOR_HV7131R; /* gspcav1 value */ - sd->i2c_base = 0x11; - break; -/* case 0x607a: * from BW600.inf - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x607c: - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x607e: * from BW600.inf - sd->bridge = BRIDGE_SN9C102P; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ - case 0x60c0: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; - break; -/* case 0x60c8: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OM6801; - sd->i2c_base = 0x??; - break; */ -/* case 0x60cc: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_HV7131GP; - sd->i2c_base = 0x??; - break; */ - case 0x60ec: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x60ef: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ -/* case 0x60fa: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x60fb: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; - break; - case 0x60fc: - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x60fe: * from BW600.inf - sd->bridge = BRIDGE_SN9C105; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ -/* case 0x6108: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OM6801; - sd->i2c_base = 0x??; - break; */ -/* case 0x6122: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ - case 0x612a: -/* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */ - sd->bridge = BRIDGE_SN9C325; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x21; -/*fixme: sensor_init has base = 00 et 6e!*/ - break; -/* case 0x6123: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_SanyoCCD; - sd->i2c_base = 0x??; - break; */ - case 0x612c: - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x612e: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ -/* case 0x612f: * from BW600.inf - sd->bridge = BRIDGE_SN9C110; - sd->sensor = SENSOR_ICM105C; - sd->i2c_base = 0x??; - break; */ - case 0x6130: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MI0360; - sd->i2c_base = 0x5d; - break; - case 0x6138: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_MO4000; - sd->i2c_base = 0x21; - break; -/* case 0x613a: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7648; - sd->i2c_base = 0x??; - break; */ - case 0x613b: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7660; - sd->i2c_base = 0x21; - break; - case 0x613c: - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_HV7131R; - sd->i2c_base = 0x11; - break; -/* case 0x613e: * from BW600.inf - sd->bridge = BRIDGE_SN9C120; - sd->sensor = SENSOR_OV7630; - sd->i2c_base = 0x??; - break; */ - } - break; - } - if (sd->sensor < 0) { - PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x", - id->idVendor, product); - return -EINVAL; - } cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); + sd->bridge = id->driver_info >> 16; + sd->sensor = id->driver_info >> 8; + sd->i2c_base = id->driver_info; + sd->qindex = 4; /* set the quantization table */ sd->brightness = BRIGHTNESS_DEF; sd->contrast = CONTRAST_DEF; @@ -1596,29 +1421,51 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define BSI(bridge, sensor, i2c_addr) \ + .driver_info = (BRIDGE_ ## bridge << 16) \ + | (SENSOR_ ## sensor << 8) \ + | (i2c_addr) static const __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")}, - {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")}, - {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")}, - {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")}, - {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")}, + {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, + {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)}, #endif - {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")}, - {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")}, - {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")}, - {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")}, - {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")}, - {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")}, - {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")}, - {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")}, - {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")}, + {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)}, +/* bw600.inf: + {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */ +/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)}, +/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)}, + {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C325, OV7648, 0x21)}, +/* bw600.inf: + {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, */ + {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x??)}, */ +/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */ #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")}, - {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")}, - {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")}, - {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")}, + {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)}, +/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */ + {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)}, + {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, +/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ #endif {} }; diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 2b8ae8095b0e..66cf2b684b7c 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -627,108 +627,10 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x040a: /* Kodak cameras */ -/* switch (product) { */ -/* case 0x0300: */ - sd->subtype = KodakEZ200; -/* break; */ -/* } */ - break; - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x400a: */ - sd->subtype = CreativePCCam300; -/* break; */ -/* } */ - break; - case 0x046d: /* Logitech Labtec */ - switch (product) { - case 0x0890: - sd->subtype = LogitechTraveler; - break; - case 0x0900: - sd->subtype = LogitechClickSmart310; - break; - case 0x0901: - sd->subtype = LogitechClickSmart510; - break; - } - break; - case 0x04a5: /* Benq */ -/* switch (product) { */ -/* case 0x300c: */ - sd->subtype = BenqDC1016; -/* break; */ -/* } */ - break; - case 0x04fc: /* SunPlus */ -/* switch (product) { */ -/* case 0x7333: */ - sd->subtype = PalmPixDC85; -/* break; */ -/* } */ - break; - case 0x055f: /* Mustek cameras */ - switch (product) { - case 0xc200: - sd->subtype = MustekGsmart300; - break; - case 0xc220: - sd->subtype = Gsmartmini; - break; - } - break; - case 0x06bd: /* Agfa Cl20 */ -/* switch (product) { */ -/* case 0x0404: */ - sd->subtype = AgfaCl20; -/* break; */ -/* } */ - break; - case 0x06be: /* Optimedia */ -/* switch (product) { */ -/* case 0x0800: */ - sd->subtype = Optimedia; -/* break; */ -/* } */ - break; - case 0x084d: /* D-Link / Minton */ -/* switch (product) { */ -/* case 0x0003: * DSC-350 / S-Cam F5 */ - sd->subtype = DLinkDSC350; -/* break; */ -/* } */ - break; - case 0x08ca: /* Aiptek */ -/* switch (product) { */ -/* case 0x0103: */ - sd->subtype = AiptekPocketDV; -/* break; */ -/* } */ - break; - case 0x2899: /* ToptroIndustrial */ -/* switch (product) { */ -/* case 0x012c: */ - sd->subtype = ToptroIndus; -/* break; */ -/* } */ - break; - case 0x8086: /* Intel */ -/* switch (product) { */ -/* case 0x0630: * Pocket PC Camera */ - sd->subtype = IntelPocketPCCamera; -/* break; */ -/* } */ - break; - } + cam = &gspca_dev->cam; cam->epaddr = 0x01; + sd->subtype = id->driver_info; if (sd->subtype != LogitechClickSmart310) { cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; @@ -1158,23 +1060,22 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0300), DVNM("Kodak EZ200")}, - {USB_DEVICE(0x041e, 0x400a), DVNM("Creative PC-CAM 300")}, - {USB_DEVICE(0x046d, 0x0890), DVNM("Logitech QuickCam traveler")}, - {USB_DEVICE(0x046d, 0x0900), DVNM("Logitech Inc. ClickSmart 310")}, - {USB_DEVICE(0x046d, 0x0901), DVNM("Logitech Inc. ClickSmart 510")}, - {USB_DEVICE(0x04a5, 0x300c), DVNM("Benq DC1016")}, - {USB_DEVICE(0x04fc, 0x7333), DVNM("PalmPixDC85")}, - {USB_DEVICE(0x055f, 0xc200), DVNM("Mustek Gsmart 300")}, - {USB_DEVICE(0x055f, 0xc220), DVNM("Gsmart Mini")}, - {USB_DEVICE(0x06bd, 0x0404), DVNM("Agfa CL20")}, - {USB_DEVICE(0x06be, 0x0800), DVNM("Optimedia")}, - {USB_DEVICE(0x084d, 0x0003), DVNM("D-Link DSC-350")}, - {USB_DEVICE(0x08ca, 0x0103), DVNM("Aiptek PocketDV")}, - {USB_DEVICE(0x2899, 0x012c), DVNM("Toptro Industrial")}, - {USB_DEVICE(0x8086, 0x0630), DVNM("Intel Pocket PC Camera")}, + {USB_DEVICE(0x040a, 0x0300), KodakEZ200}, + {USB_DEVICE(0x041e, 0x400a), CreativePCCam300}, + {USB_DEVICE(0x046d, 0x0890), LogitechTraveler}, + {USB_DEVICE(0x046d, 0x0900), LogitechClickSmart310}, + {USB_DEVICE(0x046d, 0x0901), LogitechClickSmart510}, + {USB_DEVICE(0x04a5, 0x300c), BenqDC1016}, + {USB_DEVICE(0x04fc, 0x7333), PalmPixDC85}, + {USB_DEVICE(0x055f, 0xc200), MustekGsmart300}, + {USB_DEVICE(0x055f, 0xc220), Gsmartmini}, + {USB_DEVICE(0x06bd, 0x0404), AgfaCl20}, + {USB_DEVICE(0x06be, 0x0800), Optimedia}, + {USB_DEVICE(0x084d, 0x0003), DLinkDSC350}, + {USB_DEVICE(0x08ca, 0x0103), AiptekPocketDV}, + {USB_DEVICE(0x2899, 0x012c), ToptroIndus}, + {USB_DEVICE(0x8086, 0x0630), IntelPocketPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index a695c42e10cf..a8a460c6eb0c 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -1920,62 +1920,12 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x0000: /* Unknow Camera */ -/* switch (product) { */ -/* case 0x0000: */ - sd->subtype = MystFromOriUnknownCamera; -/* break; */ -/* } */ - break; - case 0x040a: /* Kodak cameras */ -/* switch (product) { */ -/* case 0x0002: */ - sd->subtype = KodakDVC325; -/* break; */ -/* } */ - break; - case 0x0497: /* Smile International */ -/* switch (product) { */ -/* case 0xc001: */ - sd->subtype = SmileIntlCamera; -/* break; */ -/* } */ - break; - case 0x0506: /* 3COM cameras */ -/* switch (product) { */ -/* case 0x00df: */ - sd->subtype = ThreeComHomeConnectLite; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ - switch (product) { - case 0x0401: - sd->subtype = IntelCreateAndShare; - break; - case 0x0402: - sd->subtype = ViewQuestM318B; - break; - } - break; - case 0x1776: /* Arowana */ -/* switch (product) { */ -/* case 0x501c: */ - sd->subtype = Arowana300KCMOSCamera; -/* break; */ -/* } */ - break; - } + cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; + sd->subtype = id->driver_info; sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value; sd->colors = sd_ctrls[MY_COLOR].qctrl.default_value; @@ -2179,15 +2129,14 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0002), DVNM("Kodak DVC-325")}, - {USB_DEVICE(0x0497, 0xc001), DVNM("Smile International")}, - {USB_DEVICE(0x0506, 0x00df), DVNM("3Com HomeConnect Lite")}, - {USB_DEVICE(0x0733, 0x0401), DVNM("Intel Create and Share")}, - {USB_DEVICE(0x0733, 0x0402), DVNM("ViewQuest M318B")}, - {USB_DEVICE(0x1776, 0x501c), DVNM("Arowana 300K CMOS Camera")}, - {USB_DEVICE(0x0000, 0x0000), DVNM("MystFromOri Unknow Camera")}, + {USB_DEVICE(0x040a, 0x0002), KodakDVC325}, + {USB_DEVICE(0x0497, 0xc001), SmileIntlCamera}, + {USB_DEVICE(0x0506, 0x00df), ThreeComHomeConnectLite}, + {USB_DEVICE(0x0733, 0x0401), IntelCreateAndShare}, + {USB_DEVICE(0x0733, 0x0402), ViewQuestM318B}, + {USB_DEVICE(0x1776, 0x501c), Arowana300KCMOSCamera}, + {USB_DEVICE(0x0000, 0x0000), MystFromOriUnknownCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index adff24f503bb..284d549e4d3e 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -638,32 +638,11 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 vendor; - __u16 product; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x401d: * here505b */ - sd->subtype = Nxultra; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ -/* switch (product) { */ -/* case 0x0430: */ -/* fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ - sd->subtype = IntelPCCameraPro; -/* break; */ -/* } */ - break; - } cam = &gspca_dev->cam; cam->epaddr = 0x01; cam->cam_mode = vga_mode; + sd->subtype = id->driver_info; if (sd->subtype != IntelPCCameraPro) cam->nmodes = sizeof vga_mode / sizeof vga_mode[0]; else /* no 640x480 for IntelPCCameraPro */ @@ -906,10 +885,10 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401d), DVNM("Creative Webcam NX ULTRA")}, - {USB_DEVICE(0x0733, 0x0430), DVNM("Intel PC Camera Pro")}, + {USB_DEVICE(0x041e, 0x401d), Nxultra}, + {USB_DEVICE(0x0733, 0x0430), IntelPCCameraPro}, +/*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 36dc13c11cbb..2c281a0563e5 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -800,12 +800,12 @@ static struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x06e1, 0xa190), DVNM("ADS Instant VCD")}, -/* {USB_DEVICE(0x0733, 0x0430), DVNM("UsbGrabber PV321c")}, */ - {USB_DEVICE(0x0734, 0x043b), DVNM("3DeMon USB Capture aka")}, - {USB_DEVICE(0x99fa, 0x8988), DVNM("Grandtec V.cap")}, + {USB_DEVICE(0x06e1, 0xa190)}, +/*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 + {USB_DEVICE(0x0733, 0x0430)}, */ + {USB_DEVICE(0x0734, 0x043b)}, + {USB_DEVICE(0x99fa, 0x8988)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index eff5eda70e68..af531d62856c 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1473,58 +1473,8 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; int data1, data2; - product = id->idProduct; - switch (id->idVendor) { - case 0x0130: /* Clone webcam */ -/* switch (product) { */ -/* case 0x0130: */ - sd->subtype = HamaUSBSightcam; /* same as Hama 0010 */ -/* break; */ -/* } */ - break; - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x4018: */ - sd->subtype = CreativeVista; -/* break; */ -/* } */ - break; - case 0x0461: /* MicroInnovation */ -/* switch (product) { */ -/* case 0x0815: */ - sd->subtype = MicroInnovationIC200; -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ -/* switch (product) { */ -/* case 0x110: */ - sd->subtype = ViewQuestVQ110; -/* break; */ -/* } */ - break; - case 0x0af9: /* Hama cameras */ - switch (product) { - case 0x0010: - sd->subtype = HamaUSBSightcam; - break; - case 0x0011: - sd->subtype = HamaUSBSightcam2; - break; - } - break; - case 0x8086: /* Intel */ -/* switch (product) { */ -/* case 0x0110: */ - sd->subtype = IntelEasyPCCamera; -/* break; */ -/* } */ - break; - } - /* Read from global register the USB product and vendor IDs, just to * prove that we can communicate with the device. This works, which * confirms at we are communicating properly and that the device @@ -1544,6 +1494,8 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->epaddr = 0x01; cam->cam_mode = sif_mode; cam->nmodes = ARRAY_SIZE(sif_mode); + + sd->subtype = id->driver_info; sd->brightness = BRIGHTNESS_DEF; switch (sd->subtype) { @@ -1741,15 +1693,14 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0130, 0x0130), DVNM("Clone Digital Webcam 11043")}, - {USB_DEVICE(0x041e, 0x4018), DVNM("Creative Webcam Vista (PD1100)")}, - {USB_DEVICE(0x0461, 0x0815), DVNM("Micro Innovation IC200")}, - {USB_DEVICE(0x0733, 0x0110), DVNM("ViewQuest VQ110")}, - {USB_DEVICE(0x0af9, 0x0010), DVNM("Hama USB Sightcam 100")}, - {USB_DEVICE(0x0af9, 0x0011), DVNM("Hama USB Sightcam 100")}, - {USB_DEVICE(0x8086, 0x0110), DVNM("Intel Easy PC Camera")}, + {USB_DEVICE(0x0130, 0x0130), HamaUSBSightcam}, + {USB_DEVICE(0x041e, 0x4018), CreativeVista}, + {USB_DEVICE(0x0461, 0x0815), MicroInnovationIC200}, + {USB_DEVICE(0x0733, 0x0110), ViewQuestVQ110}, + {USB_DEVICE(0x0af9, 0x0010), HamaUSBSightcam}, + {USB_DEVICE(0x0af9, 0x0011), HamaUSBSightcam2}, + {USB_DEVICE(0x8086, 0x0110), IntelEasyPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 85c37f396aaf..3b46f7dda641 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -579,35 +579,15 @@ static int sd_config(struct gspca_dev *gspca_dev, PDEBUG(D_PROBE, "Bad vendor / product from device"); return -EINVAL; } - switch (product) { - case 0x0928: - case 0x0929: - case 0x092a: - case 0x092b: - case 0x092c: - case 0x092d: - case 0x092e: - case 0x092f: - case 0x403b: - sd->chip_revision = Rev012A; - break; - default: -/* case 0x0561: - case 0x0815: * ?? in spca508.c - case 0x401a: - case 0x7004: - case 0x7e50: - case 0xa001: - case 0xcdee: */ - sd->chip_revision = Rev072A; - break; - } + cam = &gspca_dev->cam; cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */ cam->cam_mode = sif_mode; cam->nmodes = sizeof sif_mode / sizeof sif_mode[0]; + + sd->chip_revision = id->driver_info; sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value; sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value; sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value; @@ -994,23 +974,22 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401a), DVNM("Creative Webcam Vista (PD1100)")}, - {USB_DEVICE(0x041e, 0x403b), DVNM("Creative Webcam Vista (VF0010)")}, - {USB_DEVICE(0x0458, 0x7004), DVNM("Genius VideoCAM Express V2")}, - {USB_DEVICE(0x046d, 0x0928), DVNM("Logitech QC Express Etch2")}, - {USB_DEVICE(0x046d, 0x0929), DVNM("Labtec Webcam Elch2")}, - {USB_DEVICE(0x046d, 0x092a), DVNM("Logitech QC for Notebook")}, - {USB_DEVICE(0x046d, 0x092b), DVNM("Labtec Webcam Plus")}, - {USB_DEVICE(0x046d, 0x092c), DVNM("Logitech QC chat Elch2")}, - {USB_DEVICE(0x046d, 0x092d), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x046d, 0x092e), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x046d, 0x092f), DVNM("Logitech QC Elch2")}, - {USB_DEVICE(0x04fc, 0x0561), DVNM("Flexcam 100")}, - {USB_DEVICE(0x060b, 0xa001), DVNM("Maxell Compact Pc PM3")}, - {USB_DEVICE(0x10fd, 0x7e50), DVNM("FlyCam Usb 100")}, - {USB_DEVICE(0xabcd, 0xcdee), DVNM("Petcam")}, + {USB_DEVICE(0x041e, 0x401a), Rev072A}, + {USB_DEVICE(0x041e, 0x403b), Rev012A}, + {USB_DEVICE(0x0458, 0x7004), Rev072A}, + {USB_DEVICE(0x046d, 0x0928), Rev012A}, + {USB_DEVICE(0x046d, 0x0929), Rev012A}, + {USB_DEVICE(0x046d, 0x092a), Rev012A}, + {USB_DEVICE(0x046d, 0x092b), Rev012A}, + {USB_DEVICE(0x046d, 0x092c), Rev012A}, + {USB_DEVICE(0x046d, 0x092d), Rev012A}, + {USB_DEVICE(0x046d, 0x092e), Rev012A}, + {USB_DEVICE(0x046d, 0x092f), Rev012A}, + {USB_DEVICE(0x04fc, 0x0561), Rev072A}, + {USB_DEVICE(0x060b, 0xa001), Rev072A}, + {USB_DEVICE(0x10fd, 0x7e50), Rev072A}, + {USB_DEVICE(0xabcd, 0xcdee), Rev072A}, {} }; diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c index f6390b49f693..16219cf6a6d5 100644 --- a/drivers/media/video/gspca/stk014.c +++ b/drivers/media/video/gspca/stk014.c @@ -545,9 +545,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")}, + {USB_DEVICE(0x05e1, 0x0893)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c index 030cb18b3557..54efa48bee01 100644 --- a/drivers/media/video/gspca/sunplus.c +++ b/drivers/media/video/gspca/sunplus.c @@ -801,228 +801,29 @@ static int sd_config(struct gspca_dev *gspca_dev, struct sd *sd = (struct sd *) gspca_dev; struct usb_device *dev = gspca_dev->dev; struct cam *cam; - __u16 vendor; - __u16 product; - __u8 fw; - - vendor = id->idVendor; - product = id->idProduct; - switch (vendor) { - case 0x041e: /* Creative cameras */ -/* switch (product) { */ -/* case 0x400b: */ -/* case 0x4012: */ -/* case 0x4013: */ -/* sd->bridge = BRIDGE_SPCA504C; */ -/* break; */ -/* } */ - break; - case 0x0458: /* Genius KYE cameras */ -/* switch (product) { */ -/* case 0x7006: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x0461: /* MicroInnovation */ -/* switch (product) { */ -/* case 0x0821: */ - sd->bridge = BRIDGE_SPCA533; -/* break; */ -/* } */ - break; - case 0x046d: /* Logitech Labtec */ - switch (product) { - case 0x0905: - sd->subtype = LogitechClickSmart820; - sd->bridge = BRIDGE_SPCA533; - break; - case 0x0960: - sd->subtype = LogitechClickSmart420; - sd->bridge = BRIDGE_SPCA504C; - break; - } - break; - case 0x0471: /* Philips */ -/* switch (product) { */ -/* case 0x0322: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x04a5: /* Benq */ - switch (product) { - case 0x3003: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x3008: - case 0x300a: - sd->bridge = BRIDGE_SPCA533; - break; - } - break; - case 0x04f1: /* JVC */ -/* switch (product) { */ -/* case 0x1001: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x04fc: /* SunPlus */ - switch (product) { - case 0x500c: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x504a: + + cam = &gspca_dev->cam; + cam->epaddr = 0x01; + + sd->bridge = id->driver_info >> 8; + sd->subtype = id->driver_info; + + if (sd->subtype == AiptekMiniPenCam13) { /* try to get the firmware as some cam answer 2.0.1.2.2 * and should be a spca504b then overwrite that setting */ - reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); - fw = gspca_dev->usb_buf[0]; - if (fw == 1) { - sd->subtype = AiptekMiniPenCam13; - sd->bridge = BRIDGE_SPCA504; - } else if (fw == 2) { - sd->bridge = BRIDGE_SPCA504B; - } else - return -ENODEV; - break; - case 0x504b: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x5330: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x5360: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xffff: - sd->bridge = BRIDGE_SPCA504B; - break; - } - break; - case 0x052b: /* ?? Megapix */ -/* switch (product) { */ -/* case 0x1513: */ - sd->subtype = MegapixV4; - sd->bridge = BRIDGE_SPCA533; -/* break; */ -/* } */ - break; - case 0x0546: /* Polaroid */ - switch (product) { - case 0x3155: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x3191: - case 0x3273: + reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1); + switch (gspca_dev->usb_buf[0]) { + case 1: + break; /* (right bridge/subtype) */ + case 2: sd->bridge = BRIDGE_SPCA504B; + sd->subtype = 0; break; + default: + return -ENODEV; } - break; - case 0x055f: /* Mustek cameras */ - switch (product) { - case 0xc211: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xc230: - case 0xc232: - sd->bridge = BRIDGE_SPCA533; - break; - case 0xc360: - sd->bridge = BRIDGE_SPCA536; - break; - case 0xc420: - sd->bridge = BRIDGE_SPCA504; - break; - case 0xc430: - case 0xc440: - sd->bridge = BRIDGE_SPCA533; - break; - case 0xc520: - sd->bridge = BRIDGE_SPCA504; - break; - case 0xc530: - case 0xc540: - case 0xc630: - case 0xc650: - sd->bridge = BRIDGE_SPCA533; - break; - } - break; - case 0x05da: /* Digital Dream cameras */ -/* switch (product) { */ -/* case 0x1018: */ - sd->bridge = BRIDGE_SPCA504B; -/* break; */ -/* } */ - break; - case 0x06d6: /* Trust */ -/* switch (product) { */ -/* case 0x0031: */ - sd->bridge = BRIDGE_SPCA533; /* SPCA533A */ -/* break; */ -/* } */ - break; - case 0x0733: /* Rebadged ViewQuest (Intel) and ViewQuest cameras */ - switch (product) { - case 0x1311: - case 0x1314: - case 0x2211: - case 0x2221: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x3261: - case 0x3281: - sd->bridge = BRIDGE_SPCA536; - break; - } - break; - case 0x08ca: /* Aiptek */ - switch (product) { - case 0x0104: - case 0x0106: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2008: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x2010: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2016: - case 0x2018: - sd->bridge = BRIDGE_SPCA504B; - break; - case 0x2020: - case 0x2022: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2024: - sd->bridge = BRIDGE_SPCA536; - break; - case 0x2028: - sd->bridge = BRIDGE_SPCA533; - break; - case 0x2040: - case 0x2042: - case 0x2050: - case 0x2060: - sd->bridge = BRIDGE_SPCA536; - break; - } - break; - case 0x0d64: /* SunPlus */ -/* switch (product) { */ -/* case 0x0303: */ - sd->bridge = BRIDGE_SPCA536; -/* break; */ -/* } */ - break; } - cam = &gspca_dev->cam; - cam->epaddr = 0x01; - switch (sd->bridge) { default: /* case BRIDGE_SPCA504B: */ @@ -1577,65 +1378,67 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define BS(bridge, subtype) \ + .driver_info = (BRIDGE_ ## bridge << 8) \ + | (subtype) static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x400b), DVNM("Creative PC-CAM 600")}, - {USB_DEVICE(0x041e, 0x4012), DVNM("PC-Cam350")}, - {USB_DEVICE(0x041e, 0x4013), DVNM("Creative Pccam750")}, - {USB_DEVICE(0x0458, 0x7006), DVNM("Genius Dsc 1.3 Smart")}, - {USB_DEVICE(0x0461, 0x0821), DVNM("Fujifilm MV-1")}, - {USB_DEVICE(0x046d, 0x0905), DVNM("Logitech ClickSmart 820")}, - {USB_DEVICE(0x046d, 0x0960), DVNM("Logitech ClickSmart 420")}, - {USB_DEVICE(0x0471, 0x0322), DVNM("Philips DMVC1300K")}, - {USB_DEVICE(0x04a5, 0x3003), DVNM("Benq DC 1300")}, - {USB_DEVICE(0x04a5, 0x3008), DVNM("Benq DC 1500")}, - {USB_DEVICE(0x04a5, 0x300a), DVNM("Benq DC3410")}, - {USB_DEVICE(0x04f1, 0x1001), DVNM("JVC GC A50")}, - {USB_DEVICE(0x04fc, 0x500c), DVNM("Sunplus CA500C")}, - {USB_DEVICE(0x04fc, 0x504a), DVNM("Aiptek Mini PenCam 1.3")}, - {USB_DEVICE(0x04fc, 0x504b), DVNM("Maxell MaxPocket LE 1.3")}, - {USB_DEVICE(0x04fc, 0x5330), DVNM("Digitrex 2110")}, - {USB_DEVICE(0x04fc, 0x5360), DVNM("Sunplus Generic")}, - {USB_DEVICE(0x04fc, 0xffff), DVNM("Pure DigitalDakota")}, - {USB_DEVICE(0x052b, 0x1513), DVNM("Megapix V4")}, - {USB_DEVICE(0x0546, 0x3155), DVNM("Polaroid PDC3070")}, - {USB_DEVICE(0x0546, 0x3191), DVNM("Polaroid Ion 80")}, - {USB_DEVICE(0x0546, 0x3273), DVNM("Polaroid PDC2030")}, - {USB_DEVICE(0x055f, 0xc211), DVNM("Kowa Bs888e Microcamera")}, - {USB_DEVICE(0x055f, 0xc230), DVNM("Mustek Digicam 330K")}, - {USB_DEVICE(0x055f, 0xc232), DVNM("Mustek MDC3500")}, - {USB_DEVICE(0x055f, 0xc360), DVNM("Mustek DV4000 Mpeg4 ")}, - {USB_DEVICE(0x055f, 0xc420), DVNM("Mustek gSmart Mini 2")}, - {USB_DEVICE(0x055f, 0xc430), DVNM("Mustek Gsmart LCD 2")}, - {USB_DEVICE(0x055f, 0xc440), DVNM("Mustek DV 3000")}, - {USB_DEVICE(0x055f, 0xc520), DVNM("Mustek gSmart Mini 3")}, - {USB_DEVICE(0x055f, 0xc530), DVNM("Mustek Gsmart LCD 3")}, - {USB_DEVICE(0x055f, 0xc540), DVNM("Gsmart D30")}, - {USB_DEVICE(0x055f, 0xc630), DVNM("Mustek MDC4000")}, - {USB_DEVICE(0x055f, 0xc650), DVNM("Mustek MDC5500Z")}, - {USB_DEVICE(0x05da, 0x1018), DVNM("Digital Dream Enigma 1.3")}, - {USB_DEVICE(0x06d6, 0x0031), DVNM("Trust 610 LCD PowerC@m Zoom")}, - {USB_DEVICE(0x0733, 0x1311), DVNM("Digital Dream Epsilon 1.3")}, - {USB_DEVICE(0x0733, 0x1314), DVNM("Mercury 2.1MEG Deluxe Classic Cam")}, - {USB_DEVICE(0x0733, 0x2211), DVNM("Jenoptik jdc 21 LCD")}, - {USB_DEVICE(0x0733, 0x2221), DVNM("Mercury Digital Pro 3.1p")}, - {USB_DEVICE(0x0733, 0x3261), DVNM("Concord 3045 spca536a")}, - {USB_DEVICE(0x0733, 0x3281), DVNM("Cyberpix S550V")}, - {USB_DEVICE(0x08ca, 0x0104), DVNM("Aiptek PocketDVII 1.3")}, - {USB_DEVICE(0x08ca, 0x0106), DVNM("Aiptek Pocket DV3100+")}, - {USB_DEVICE(0x08ca, 0x2008), DVNM("Aiptek Mini PenCam 2 M")}, - {USB_DEVICE(0x08ca, 0x2010), DVNM("Aiptek PocketCam 3M")}, - {USB_DEVICE(0x08ca, 0x2016), DVNM("Aiptek PocketCam 2 Mega")}, - {USB_DEVICE(0x08ca, 0x2018), DVNM("Aiptek Pencam SD 2M")}, - {USB_DEVICE(0x08ca, 0x2020), DVNM("Aiptek Slim 3000F")}, - {USB_DEVICE(0x08ca, 0x2022), DVNM("Aiptek Slim 3200")}, - {USB_DEVICE(0x08ca, 0x2024), DVNM("Aiptek DV3500 Mpeg4 ")}, - {USB_DEVICE(0x08ca, 0x2028), DVNM("Aiptek PocketCam4M")}, - {USB_DEVICE(0x08ca, 0x2040), DVNM("Aiptek PocketDV4100M")}, - {USB_DEVICE(0x08ca, 0x2042), DVNM("Aiptek PocketDV5100")}, - {USB_DEVICE(0x08ca, 0x2050), DVNM("Medion MD 41437")}, - {USB_DEVICE(0x08ca, 0x2060), DVNM("Aiptek PocketDV5300")}, - {USB_DEVICE(0x0d64, 0x0303), DVNM("Sunplus FashionCam DXG")}, + {USB_DEVICE(0x041e, 0x400b), BS(SPCA504C, 0)}, + {USB_DEVICE(0x041e, 0x4012), BS(SPCA504C, 0)}, + {USB_DEVICE(0x041e, 0x4013), BS(SPCA504C, 0)}, + {USB_DEVICE(0x0458, 0x7006), BS(SPCA504B, 0)}, + {USB_DEVICE(0x0461, 0x0821), BS(SPCA533, 0)}, + {USB_DEVICE(0x046d, 0x0905), BS(SPCA533, LogitechClickSmart820)}, + {USB_DEVICE(0x046d, 0x0960), BS(SPCA504C, LogitechClickSmart420)}, + {USB_DEVICE(0x0471, 0x0322), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04a5, 0x3003), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04a5, 0x3008), BS(SPCA533, 0)}, + {USB_DEVICE(0x04a5, 0x300a), BS(SPCA533, 0)}, + {USB_DEVICE(0x04f1, 0x1001), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x500c), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x504a), BS(SPCA504, AiptekMiniPenCam13)}, + {USB_DEVICE(0x04fc, 0x504b), BS(SPCA504B, 0)}, + {USB_DEVICE(0x04fc, 0x5330), BS(SPCA533, 0)}, + {USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)}, + {USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)}, + {USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)}, + {USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)}, + {USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)}, + {USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)}, + {USB_DEVICE(0x055f, 0xc211), BS(SPCA536, 0)}, + {USB_DEVICE(0x055f, 0xc230), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc232), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc360), BS(SPCA536, 0)}, + {USB_DEVICE(0x055f, 0xc420), BS(SPCA504, 0)}, + {USB_DEVICE(0x055f, 0xc430), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc440), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc520), BS(SPCA504, 0)}, + {USB_DEVICE(0x055f, 0xc530), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc540), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc630), BS(SPCA533, 0)}, + {USB_DEVICE(0x055f, 0xc650), BS(SPCA533, 0)}, + {USB_DEVICE(0x05da, 0x1018), BS(SPCA504B, 0)}, + {USB_DEVICE(0x06d6, 0x0031), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x1311), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x1314), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x2211), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x2221), BS(SPCA533, 0)}, + {USB_DEVICE(0x0733, 0x3261), BS(SPCA536, 0)}, + {USB_DEVICE(0x0733, 0x3281), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x0104), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x0106), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2008), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2010), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2016), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2018), BS(SPCA504B, 0)}, + {USB_DEVICE(0x08ca, 0x2020), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2022), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2024), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2028), BS(SPCA533, 0)}, + {USB_DEVICE(0x08ca, 0x2040), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2042), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2050), BS(SPCA536, 0)}, + {USB_DEVICE(0x08ca, 0x2060), BS(SPCA536, 0)}, + {USB_DEVICE(0x0d64, 0x0303), BS(SPCA536, 0)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c index f7ea9a742725..91b555c34c68 100644 --- a/drivers/media/video/gspca/t613.c +++ b/drivers/media/video/gspca/t613.c @@ -995,9 +995,8 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x17a1, 0x0128), DVNM("XPX Webcam")}, + {USB_DEVICE(0x17a1, 0x0128)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c index b024aca9b102..1ff8ba2f7fe5 100644 --- a/drivers/media/video/gspca/tv8532.c +++ b/drivers/media/video/gspca/tv8532.c @@ -620,13 +620,12 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0920), DVNM("QC Express")}, - {USB_DEVICE(0x046d, 0x0921), DVNM("Labtec Webcam")}, - {USB_DEVICE(0x0545, 0x808b), DVNM("Veo Stingray")}, - {USB_DEVICE(0x0545, 0x8333), DVNM("Veo Stingray")}, - {USB_DEVICE(0x0923, 0x010f), DVNM("ICM532 cams")}, + {USB_DEVICE(0x046d, 0x0920)}, + {USB_DEVICE(0x046d, 0x0921)}, + {USB_DEVICE(0x0545, 0x808b)}, + {USB_DEVICE(0x0545, 0x8333)}, + {USB_DEVICE(0x0923, 0x010f)}, {} }; diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 46cff48e6297..5cf1af96d5f5 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -1416,29 +1416,10 @@ static int sd_config(struct gspca_dev *gspca_dev, struct usb_device *dev = gspca_dev->dev; struct cam *cam; int sensor; - __u16 product; - - product = id->idProduct; - sd->bridge = BRIDGE_VC0321; - switch (id->idVendor) { - case 0x0ac8: /* Vimicro z-star */ - switch (product) { - case 0x0323: - sd->bridge = BRIDGE_VC0323; - break; - } - break; - case 0x17ef: /* Lenovo */ -/* switch (product) { */ -/* case 0x4802: * Lenovo MI1310_SOC */ - sd->bridge = BRIDGE_VC0323; -/* break; */ -/* } */ - break; - } cam = &gspca_dev->cam; cam->epaddr = 0x02; + sd->bridge = id->driver_info; if (sd->bridge == BRIDGE_VC0321) { cam->cam_mode = vc0321_mode; cam->nmodes = ARRAY_SIZE(vc0321_mode); @@ -1767,16 +1748,15 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0892), DVNM("Logitech Orbicam")}, - {USB_DEVICE(0x046d, 0x0896), DVNM("Logitech Orbicam")}, - {USB_DEVICE(0x0ac8, 0x0321), DVNM("Vimicro generic vc0321")}, - {USB_DEVICE(0x0ac8, 0x0323), DVNM("Vimicro Vc0323")}, - {USB_DEVICE(0x0ac8, 0x0328), DVNM("A4Tech PK-130MG")}, - {USB_DEVICE(0x0ac8, 0xc001), DVNM("Sony embedded vimicro")}, - {USB_DEVICE(0x0ac8, 0xc002), DVNM("Sony embedded vimicro")}, - {USB_DEVICE(0x17ef, 0x4802), DVNM("Lenovo Vc0323+MI1310_SOC")}, + {USB_DEVICE(0x046d, 0x0892), BRIDGE_VC0321}, + {USB_DEVICE(0x046d, 0x0896), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0321), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0323), BRIDGE_VC0323}, + {USB_DEVICE(0x0ac8, 0x0328), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc001), BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc002), BRIDGE_VC0321}, + {USB_DEVICE(0x17ef, 0x4802), BRIDGE_VC0323}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index acd538da0784..257195951a5b 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7012,31 +7012,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* define some sensors from the vendor/product */ sd->sharpness = 2; - sd->sensor = -1; - switch (id->idVendor) { - case 0x041e: /* Creative */ - switch (id->idProduct) { - case 0x4051: /* zc301 chips */ - case 0x4053: - sd->sensor = SENSOR_TAS5130C_VF0250; - break; - } - break; - case 0x046d: /* Logitech Labtec */ - switch (id->idProduct) { - case 0x08dd: - sd->sensor = SENSOR_MC501CB; - break; - } - break; - case 0x0ac8: /* Vimicro z-star */ - switch (id->idProduct) { - case 0x305b: - sd->sensor = SENSOR_TAS5130C_VF0250; - break; - } - break; - } + sd->sensor = id->driver_info; sensor = zcxx_probeSensor(gspca_dev); if (sensor >= 0) PDEBUG(D_PROBE, "probe sensor -> %02x", sensor); @@ -7522,70 +7498,69 @@ static const struct sd_desc sd_desc = { .querymenu = sd_querymenu, }; -#define DVNM(name) .driver_info = (kernel_ulong_t) name static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x041e), DVNM("Creative WebCam Live!")}, + {USB_DEVICE(0x041e, 0x041e)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4017), DVNM("Creative Webcam Mobile PD1090")}, - {USB_DEVICE(0x041e, 0x401c), DVNM("Creative NX")}, - {USB_DEVICE(0x041e, 0x401e), DVNM("Creative Nx Pro")}, - {USB_DEVICE(0x041e, 0x401f), DVNM("Creative Webcam Notebook PD1171")}, + {USB_DEVICE(0x041e, 0x4017)}, + {USB_DEVICE(0x041e, 0x401c)}, + {USB_DEVICE(0x041e, 0x401e)}, + {USB_DEVICE(0x041e, 0x401f)}, #endif - {USB_DEVICE(0x041e, 0x4029), DVNM("Creative WebCam Vista Pro")}, + {USB_DEVICE(0x041e, 0x4029)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x041e, 0x4034), DVNM("Creative Instant P0620")}, - {USB_DEVICE(0x041e, 0x4035), DVNM("Creative Instant P0620D")}, - {USB_DEVICE(0x041e, 0x4036), DVNM("Creative Live !")}, - {USB_DEVICE(0x041e, 0x403a), DVNM("Creative Nx Pro 2")}, + {USB_DEVICE(0x041e, 0x4034)}, + {USB_DEVICE(0x041e, 0x4035)}, + {USB_DEVICE(0x041e, 0x4036)}, + {USB_DEVICE(0x041e, 0x403a)}, #endif - {USB_DEVICE(0x041e, 0x4051), DVNM("Creative Notebook Pro (VF0250)")}, - {USB_DEVICE(0x041e, 0x4053), DVNM("Creative Live!Cam Video IM")}, + {USB_DEVICE(0x041e, 0x4051), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4053), SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0458, 0x7007), DVNM("Genius VideoCam V2")}, - {USB_DEVICE(0x0458, 0x700c), DVNM("Genius VideoCam V3")}, - {USB_DEVICE(0x0458, 0x700f), DVNM("Genius VideoCam Web V2")}, + {USB_DEVICE(0x0458, 0x7007)}, + {USB_DEVICE(0x0458, 0x700c)}, + {USB_DEVICE(0x0458, 0x700f)}, #endif - {USB_DEVICE(0x0461, 0x0a00), DVNM("MicroInnovation WebCam320")}, - {USB_DEVICE(0x046d, 0x08a0), DVNM("Logitech QC IM")}, - {USB_DEVICE(0x046d, 0x08a1), DVNM("Logitech QC IM 0x08A1 +sound")}, - {USB_DEVICE(0x046d, 0x08a2), DVNM("Labtec Webcam Pro")}, - {USB_DEVICE(0x046d, 0x08a3), DVNM("Logitech QC Chat")}, - {USB_DEVICE(0x046d, 0x08a6), DVNM("Logitech QCim")}, - {USB_DEVICE(0x046d, 0x08a7), DVNM("Logitech QuickCam Image")}, - {USB_DEVICE(0x046d, 0x08a9), DVNM("Logitech Notebook Deluxe")}, - {USB_DEVICE(0x046d, 0x08aa), DVNM("Labtec Webcam Notebook")}, - {USB_DEVICE(0x046d, 0x08ac), DVNM("Logitech QuickCam Cool")}, - {USB_DEVICE(0x046d, 0x08ad), DVNM("Logitech QCCommunicate STX")}, + {USB_DEVICE(0x0461, 0x0a00)}, + {USB_DEVICE(0x046d, 0x08a0)}, + {USB_DEVICE(0x046d, 0x08a1)}, + {USB_DEVICE(0x046d, 0x08a2)}, + {USB_DEVICE(0x046d, 0x08a3)}, + {USB_DEVICE(0x046d, 0x08a6)}, + {USB_DEVICE(0x046d, 0x08a7)}, + {USB_DEVICE(0x046d, 0x08a9)}, + {USB_DEVICE(0x046d, 0x08aa)}, + {USB_DEVICE(0x046d, 0x08ac)}, + {USB_DEVICE(0x046d, 0x08ad)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x046d, 0x08ae), DVNM("Logitech QuickCam for Notebooks")}, + {USB_DEVICE(0x046d, 0x08ae)}, #endif - {USB_DEVICE(0x046d, 0x08af), DVNM("Logitech QuickCam Cool")}, - {USB_DEVICE(0x046d, 0x08b9), DVNM("Logitech QC IM ???")}, - {USB_DEVICE(0x046d, 0x08d7), DVNM("Logitech QCam STX")}, - {USB_DEVICE(0x046d, 0x08d9), DVNM("Logitech QuickCam IM/Connect")}, - {USB_DEVICE(0x046d, 0x08d8), DVNM("Logitech Notebook Deluxe")}, - {USB_DEVICE(0x046d, 0x08da), DVNM("Logitech QuickCam Messenger")}, - {USB_DEVICE(0x046d, 0x08dd), DVNM("Logitech QuickCam for Notebooks")}, - {USB_DEVICE(0x0471, 0x0325), DVNM("Philips SPC 200 NC")}, - {USB_DEVICE(0x0471, 0x0326), DVNM("Philips SPC 300 NC")}, - {USB_DEVICE(0x0471, 0x032d), DVNM("Philips spc210nc")}, - {USB_DEVICE(0x0471, 0x032e), DVNM("Philips spc315nc")}, - {USB_DEVICE(0x055f, 0xc005), DVNM("Mustek Wcam300A")}, + {USB_DEVICE(0x046d, 0x08af)}, + {USB_DEVICE(0x046d, 0x08b9)}, + {USB_DEVICE(0x046d, 0x08d7)}, + {USB_DEVICE(0x046d, 0x08d9)}, + {USB_DEVICE(0x046d, 0x08d8)}, + {USB_DEVICE(0x046d, 0x08da)}, + {USB_DEVICE(0x046d, 0x08dd), SENSOR_MC501CB}, + {USB_DEVICE(0x0471, 0x0325)}, + {USB_DEVICE(0x0471, 0x0326)}, + {USB_DEVICE(0x0471, 0x032d)}, + {USB_DEVICE(0x0471, 0x032e)}, + {USB_DEVICE(0x055f, 0xc005)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x055f, 0xd003), DVNM("Mustek WCam300A")}, - {USB_DEVICE(0x055f, 0xd004), DVNM("Mustek WCam300 AN")}, + {USB_DEVICE(0x055f, 0xd003)}, + {USB_DEVICE(0x055f, 0xd004)}, #endif - {USB_DEVICE(0x0698, 0x2003), DVNM("CTX M730V built in")}, - {USB_DEVICE(0x0ac8, 0x0302), DVNM("Z-star Vimicro zc0302")}, + {USB_DEVICE(0x0698, 0x2003)}, + {USB_DEVICE(0x0ac8, 0x0302)}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0ac8, 0x301b), DVNM("Z-Star zc301b")}, - {USB_DEVICE(0x0ac8, 0x303b), DVNM("Vimicro 0x303b")}, + {USB_DEVICE(0x0ac8, 0x301b)}, + {USB_DEVICE(0x0ac8, 0x303b)}, #endif - {USB_DEVICE(0x0ac8, 0x305b), DVNM("Z-star Vimicro zc0305b")}, + {USB_DEVICE(0x0ac8, 0x305b), SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 - {USB_DEVICE(0x0ac8, 0x307b), DVNM("Z-Star 307b")}, - {USB_DEVICE(0x10fd, 0x0128), DVNM("Typhoon Webshot II 300k 0x0128")}, - {USB_DEVICE(0x10fd, 0x8050), DVNM("Typhoon Webshot II USB 300k")}, + {USB_DEVICE(0x0ac8, 0x307b)}, + {USB_DEVICE(0x10fd, 0x0128)}, + {USB_DEVICE(0x10fd, 0x8050)}, #endif {} /* end of entry */ }; -- cgit v1.2.3 From e546f4bb6d3b320d60c33025597bc8fc31532394 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 03:43:59 -0300 Subject: V4L/DVB (8515): gspca: Webcam 0c45:6143 added in sonixj. It is an other Pccam168. The .inf says SN9C120B + SP80708, but it should work as SN9C120 + MI0360. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixj.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 46f2cf66d48f..33a3df1f6915 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -1467,6 +1467,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)}, /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */ #endif + {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From 496cd7e977c73df2c287eaf6d612fc49d6f83dd7 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 07:49:55 -0300 Subject: V4L/DVB (8517): gspca: Bad sensor for some webcams in zc3xx since 28b8203a830e. '.driver_info = ' forgotten in usb device id table. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/zc3xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index 257195951a5b..22a994ccb1d5 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7513,8 +7513,8 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x041e, 0x4036)}, {USB_DEVICE(0x041e, 0x403a)}, #endif - {USB_DEVICE(0x041e, 0x4051), SENSOR_TAS5130C_VF0250}, - {USB_DEVICE(0x041e, 0x4053), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4051), .driver_info = SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x041e, 0x4053), .driver_info = SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0458, 0x7007)}, {USB_DEVICE(0x0458, 0x700c)}, @@ -7540,7 +7540,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08d9)}, {USB_DEVICE(0x046d, 0x08d8)}, {USB_DEVICE(0x046d, 0x08da)}, - {USB_DEVICE(0x046d, 0x08dd), SENSOR_MC501CB}, + {USB_DEVICE(0x046d, 0x08dd), .driver_info = SENSOR_MC501CB}, {USB_DEVICE(0x0471, 0x0325)}, {USB_DEVICE(0x0471, 0x0326)}, {USB_DEVICE(0x0471, 0x032d)}, @@ -7556,7 +7556,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0ac8, 0x301b)}, {USB_DEVICE(0x0ac8, 0x303b)}, #endif - {USB_DEVICE(0x0ac8, 0x305b), SENSOR_TAS5130C_VF0250}, + {USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250}, #ifndef CONFIG_USB_ZC0301 {USB_DEVICE(0x0ac8, 0x307b)}, {USB_DEVICE(0x10fd, 0x0128)}, -- cgit v1.2.3 From 1250ac6d4ab716dafe0ac245fd31cd3a7cbc0a98 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 08:02:47 -0300 Subject: V4L/DVB (8518): gspca: Remove the remaining frame decoding functions from the subdrivers. SPCA505 and SPCA508 added in the pixel formats. Decode functions and associated resources removed in spca505, 506 and 508. The decode routines are now found in the V4L library. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/spca505.c | 105 ++++++++++-------------------------- drivers/media/video/gspca/spca506.c | 105 ++++++++++-------------------------- drivers/media/video/gspca/spca508.c | 91 +++++++------------------------ include/linux/videodev2.h | 2 + 4 files changed, 76 insertions(+), 227 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 284d549e4d3e..32ffe5556061 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -31,10 +31,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - unsigned char tmpbuf[640 * 480 * 3 / 2]; /* YYUV per line */ - unsigned char tmpbuf2[640 * 480 * 2]; /* YUYV */ - unsigned char brightness; char subtype; @@ -64,29 +60,29 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, - {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, - {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, + {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 640 * 3, + .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -760,77 +756,30 @@ static void sd_close(struct gspca_dev *gspca_dev) reg_write(gspca_dev->dev, 0x05, 0x11, 0xf); } -/* convert YYUV per line to YUYV (YUV 4:2:2) */ -static void yyuv_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - yi1 = yi + width; - Ui = yi1 + width; - Vi = Ui + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yyuv_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 2c281a0563e5..6fe715c80ad2 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c @@ -33,10 +33,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - __u8 tmpbuf[640 * 480 * 3]; /* YYUV per line */ - __u8 tmpbuf2[640 * 480 * 2]; /* YUYV */ - unsigned char brightness; unsigned char contrast; unsigned char colors; @@ -115,29 +111,29 @@ static struct ctrl sd_ctrls[] = { }; static struct v4l2_pix_format vga_mode[] = { - {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + {160, 120, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 5}, - {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + {176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 4}, - {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + {320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, - {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + {352, 288, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, - {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 640 * 2, - .sizeimage = 640 * 480 * 2, + {640, 480, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE, + .bytesperline = 640 * 3, + .sizeimage = 640 * 480 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -572,77 +568,30 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* convert YYUV per line to YUYV (YUV 4:2:2) */ -static void yyuv_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - yi1 = yi + width; - Ui = yi1 + width; - Vi = Ui + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yyuv_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA50X_OFFSET_DATA; len -= SPCA50X_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index af531d62856c..4378e966edcc 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -30,10 +30,6 @@ MODULE_LICENSE("GPL"); struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - int buflen; - unsigned char tmpbuf[352 * 288 * 3 / 2]; /* YUVY per line */ - unsigned char tmpbuf2[352 * 288 * 2]; /* YUYV */ - unsigned char brightness; char subtype; @@ -68,23 +64,23 @@ static struct ctrl sd_ctrls[] = { static struct v4l2_pix_format sif_mode[] = { {160, 120, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 160 * 2, - .sizeimage = 160 * 120 * 2, + .bytesperline = 160 * 3, + .sizeimage = 160 * 120 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 3}, {176, 144, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 176 * 2, - .sizeimage = 176 * 144 * 2, + .bytesperline = 176 * 3, + .sizeimage = 176 * 144 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 2}, {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 320 * 2, - .sizeimage = 320 * 240 * 2, + .bytesperline = 320 * 3, + .sizeimage = 320 * 240 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 1}, {352, 288, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, - .bytesperline = 352 * 2, - .sizeimage = 352 * 288 * 2, + .bytesperline = 352 * 3, + .sizeimage = 352 * 288 * 3 / 2, .colorspace = V4L2_COLORSPACE_SRGB, .priv = 0}, }; @@ -1567,77 +1563,30 @@ static void sd_close(struct gspca_dev *gspca_dev) { } -/* convert YUVY per line to YUYV (YUV 4:2:2) */ -static void yuvy_decode(unsigned char *out, - unsigned char *in, - int width, - int height) -{ - unsigned char *Ui, *Vi, *yi, *yi1; - unsigned char *out1; - int i, j; - - yi = in; - for (i = height / 2; --i >= 0; ) { - out1 = out + width * 2; /* next line */ - Ui = yi + width; - Vi = Ui + width / 2; - yi1 = Vi + width / 2; - for (j = width / 2; --j >= 0; ) { - *out++ = 128 + *yi++; - *out++ = 128 + *Ui; - *out++ = 128 + *yi++; - *out++ = 128 + *Vi; - - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Ui++; - *out1++ = 128 + *yi1++; - *out1++ = 128 + *Vi++; - } - yi += width * 2; - out = out1; - } -} - static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* target */ __u8 *data, /* isoc packet */ int len) /* iso packet length */ { - struct sd *sd = (struct sd *) gspca_dev; - switch (data[0]) { case 0: /* start of frame */ - if (gspca_dev->last_packet_type == FIRST_PACKET) { - yuvy_decode(sd->tmpbuf2, sd->tmpbuf, - gspca_dev->width, - gspca_dev->height); - frame = gspca_frame_add(gspca_dev, - LAST_PACKET, - frame, - sd->tmpbuf2, - gspca_dev->width - * gspca_dev->height - * 2); - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, 0); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, + data, 0); data += SPCA508_OFFSET_DATA; len -= SPCA508_OFFSET_DATA; - if (len > 0) - memcpy(sd->tmpbuf, data, len); - else - len = 0; - sd->buflen = len; - return; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; case 0xff: /* drop */ /* gspca_dev->last_packet_type = DISCARD_PACKET; */ - return; + break; + default: + data += 1; + len -= 1; + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + break; } - data += 1; - len -= 1; - memcpy(&sd->tmpbuf[sd->buflen], data, len); - sd->buflen += len; } static void setbrightness(struct gspca_dev *gspca_dev) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index cc0c8952323b..7d9ac046389e 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -324,6 +324,8 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */ #define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */ #define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */ +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S','5','0','5') /* YYUV per line */ +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S','5','0','8') /* YUVY per line */ #define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */ #define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */ -- cgit v1.2.3 From 5da162e7e2246851b6d5899688bba5b25a7fea3e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 14:17:23 -0300 Subject: V4L/DVB (8519): gspca: Set the specific per webcam information in driver_info for sonixb. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 134 ++++++++++++++++--------------------- 1 file changed, 57 insertions(+), 77 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 93d365456591..3db49a854fe2 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -58,6 +58,12 @@ struct sd { __u8 reg11; }; +/* flags used in the device id table */ +#define F_GAIN 0x01 /* has gain */ +#define F_AUTO 0x02 /* has autogain */ +#define F_SIF 0x04 /* sif or vga */ +#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */ + #define COMP2 0x8f #define COMP 0xc7 /* 0x87 //0x07 */ #define COMP1 0xc9 /* 0x89 //0x09 */ @@ -751,74 +757,28 @@ static int sd_config(struct gspca_dev *gspca_dev, { struct sd *sd = (struct sd *) gspca_dev; struct cam *cam; - __u16 product; int sif = 0; /* nctrls depends upon the sensor, so we use a per cam copy */ memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc)); gspca_dev->sd_desc = &sd->sd_desc; - sd->fr_h_sz = 12; /* default size of the frame header */ - sd->sd_desc.nctrls = 2; /* default nb of ctrls */ - product = id->idProduct; -/* switch (id->idVendor) { */ -/* case 0x0c45: * Sonix */ - switch (product) { - case 0x6001: /* SN9C102 */ - case 0x6005: /* SN9C101 */ - case 0x6007: /* SN9C101 */ - sd->sensor = SENSOR_TAS5110; - sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 4; - sd->sd_desc.dq_callback = do_autogain; - sif = 1; - break; - case 0x6009: /* SN9C101 */ - case 0x600d: /* SN9C101 */ - case 0x6029: /* SN9C101 */ - sd->sensor = SENSOR_PAS106; - sif = 1; - break; - case 0x6011: /* SN9C101 - SN9C101G */ - sd->sensor = SENSOR_OV6650; - sd->sensor_has_gain = 1; - sd->sensor_addr = 0x60; - sd->sd_desc.nctrls = 5; - sd->sd_desc.dq_callback = do_autogain; - sif = 1; - break; - case 0x6019: /* SN9C101 */ - case 0x602c: /* SN9C102 */ - case 0x602e: /* SN9C102 */ - case 0x60b0: /* SN9C103 */ - sd->sensor = SENSOR_OV7630; - sd->sensor_addr = 0x21; - sd->sensor_has_gain = 1; - sd->sd_desc.nctrls = 5; - sd->sd_desc.dq_callback = do_autogain; - if (product == 0x60b0) - sd->fr_h_sz = 18; /* size of frame header */ - break; - case 0x6024: /* SN9C102 */ - case 0x6025: /* SN9C102 */ - sd->sensor = SENSOR_TAS5130CXX; - break; - case 0x6028: /* SN9C102 */ - sd->sensor = SENSOR_PAS202; - break; - case 0x602d: /* SN9C102 */ - sd->sensor = SENSOR_HV7131R; - break; - case 0x60af: /* SN9C103 */ - sd->sensor = SENSOR_PAS202; - sd->fr_h_sz = 18; /* size of frame header (?) */ - break; - } -/* break; */ -/* } */ + /* copy the webcam info from the device id */ + sd->sensor = (id->driver_info >> 24) & 0xff; + if (id->driver_info & (F_GAIN << 16)) + sd->sensor_has_gain = 1; + if (id->driver_info & (F_AUTO << 16)) + sd->sd_desc.dq_callback = do_autogain; + if (id->driver_info & (F_SIF << 16)) + sif = 1; + if (id->driver_info & (F_H18 << 16)) + sd->fr_h_sz = 18; /* size of frame header */ + else + sd->fr_h_sz = 12; + sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff; + sd->sensor_addr = id->driver_info & 0xff; cam = &gspca_dev->cam; - cam->dev_name = (char *) id->driver_info; cam->epaddr = 0x01; if (!sif) { cam->cam_mode = vga_mode; @@ -1212,27 +1172,47 @@ static const struct sd_desc sd_desc = { }; /* -- module initialisation -- */ -#define DVNM(name) .driver_info = (kernel_ulong_t) name +#define SFCI(sensor, flags, nctrls, i2c_addr) \ + .driver_info = (SENSOR_ ## sensor << 24) \ + | ((flags) << 16) \ + | ((nctrls) << 8) \ + | (i2c_addr) static __devinitdata struct usb_device_id device_table[] = { #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")}, - {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")}, - {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")}, - {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")}, - {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")}, + {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */ + SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)}, + {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, + {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, #endif - {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")}, + {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */ + SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, #ifndef CONFIG_USB_SN9C102 - {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")}, - {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")}, - {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")}, - {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")}, - {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")}, - {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")}, - {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")}, - {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")}, - {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")}, - {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")}, + {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ + SFCI(TAS5130CXX, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ + SFCI(TAS5130CXX, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */ + SFCI(PAS202, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ + SFCI(PAS106, F_SIF, 2, 0)}, + {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ + SFCI(HV7131R, 0, 2, 0)}, + {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ + SFCI(PAS202, F_H18, 2, 0)}, + {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ + SFCI(OV7630, F_GAIN|F_AUTO|F_SIF|F_H18, 5, 0x21)}, #endif {} }; -- cgit v1.2.3 From 87581aa5f10959224fc7e1a30ac9af53949d0ef2 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sat, 26 Jul 2008 14:30:01 -0300 Subject: V4L/DVB (8520): gspca: Bad webcam information in some modules since 28b8203a830e. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/spca500.c | 30 +++++++++++++++--------------- drivers/media/video/gspca/spca501.c | 14 +++++++------- drivers/media/video/gspca/spca505.c | 4 ++-- drivers/media/video/gspca/spca508.c | 14 +++++++------- drivers/media/video/gspca/spca561.c | 30 +++++++++++++++--------------- drivers/media/video/gspca/vc032x.c | 16 ++++++++-------- 6 files changed, 54 insertions(+), 54 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c index 66cf2b684b7c..17fe2c2a440d 100644 --- a/drivers/media/video/gspca/spca500.c +++ b/drivers/media/video/gspca/spca500.c @@ -1061,21 +1061,21 @@ static struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0300), KodakEZ200}, - {USB_DEVICE(0x041e, 0x400a), CreativePCCam300}, - {USB_DEVICE(0x046d, 0x0890), LogitechTraveler}, - {USB_DEVICE(0x046d, 0x0900), LogitechClickSmart310}, - {USB_DEVICE(0x046d, 0x0901), LogitechClickSmart510}, - {USB_DEVICE(0x04a5, 0x300c), BenqDC1016}, - {USB_DEVICE(0x04fc, 0x7333), PalmPixDC85}, - {USB_DEVICE(0x055f, 0xc200), MustekGsmart300}, - {USB_DEVICE(0x055f, 0xc220), Gsmartmini}, - {USB_DEVICE(0x06bd, 0x0404), AgfaCl20}, - {USB_DEVICE(0x06be, 0x0800), Optimedia}, - {USB_DEVICE(0x084d, 0x0003), DLinkDSC350}, - {USB_DEVICE(0x08ca, 0x0103), AiptekPocketDV}, - {USB_DEVICE(0x2899, 0x012c), ToptroIndus}, - {USB_DEVICE(0x8086, 0x0630), IntelPocketPCCamera}, + {USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200}, + {USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300}, + {USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler}, + {USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310}, + {USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510}, + {USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016}, + {USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85}, + {USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300}, + {USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini}, + {USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20}, + {USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia}, + {USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350}, + {USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV}, + {USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus}, + {USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c index a8a460c6eb0c..51a3c3429ef0 100644 --- a/drivers/media/video/gspca/spca501.c +++ b/drivers/media/video/gspca/spca501.c @@ -2130,13 +2130,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x040a, 0x0002), KodakDVC325}, - {USB_DEVICE(0x0497, 0xc001), SmileIntlCamera}, - {USB_DEVICE(0x0506, 0x00df), ThreeComHomeConnectLite}, - {USB_DEVICE(0x0733, 0x0401), IntelCreateAndShare}, - {USB_DEVICE(0x0733, 0x0402), ViewQuestM318B}, - {USB_DEVICE(0x1776, 0x501c), Arowana300KCMOSCamera}, - {USB_DEVICE(0x0000, 0x0000), MystFromOriUnknownCamera}, + {USB_DEVICE(0x040a, 0x0002), .driver_info = KodakDVC325}, + {USB_DEVICE(0x0497, 0xc001), .driver_info = SmileIntlCamera}, + {USB_DEVICE(0x0506, 0x00df), .driver_info = ThreeComHomeConnectLite}, + {USB_DEVICE(0x0733, 0x0401), .driver_info = IntelCreateAndShare}, + {USB_DEVICE(0x0733, 0x0402), .driver_info = ViewQuestM318B}, + {USB_DEVICE(0x1776, 0x501c), .driver_info = Arowana300KCMOSCamera}, + {USB_DEVICE(0x0000, 0x0000), .driver_info = MystFromOriUnknownCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c index 32ffe5556061..3c2be80cbd65 100644 --- a/drivers/media/video/gspca/spca505.c +++ b/drivers/media/video/gspca/spca505.c @@ -835,8 +835,8 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401d), Nxultra}, - {USB_DEVICE(0x0733, 0x0430), IntelPCCameraPro}, + {USB_DEVICE(0x041e, 0x401d), .driver_info = Nxultra}, + {USB_DEVICE(0x0733, 0x0430), .driver_info = IntelPCCameraPro}, /*fixme: may be UsbGrabberPV321 BRIDGE_SPCA506 SENSOR_SAA7113 */ {} }; diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c index 4378e966edcc..b608a27ad115 100644 --- a/drivers/media/video/gspca/spca508.c +++ b/drivers/media/video/gspca/spca508.c @@ -1643,13 +1643,13 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x0130, 0x0130), HamaUSBSightcam}, - {USB_DEVICE(0x041e, 0x4018), CreativeVista}, - {USB_DEVICE(0x0461, 0x0815), MicroInnovationIC200}, - {USB_DEVICE(0x0733, 0x0110), ViewQuestVQ110}, - {USB_DEVICE(0x0af9, 0x0010), HamaUSBSightcam}, - {USB_DEVICE(0x0af9, 0x0011), HamaUSBSightcam2}, - {USB_DEVICE(0x8086, 0x0110), IntelEasyPCCamera}, + {USB_DEVICE(0x0130, 0x0130), .driver_info = HamaUSBSightcam}, + {USB_DEVICE(0x041e, 0x4018), .driver_info = CreativeVista}, + {USB_DEVICE(0x0461, 0x0815), .driver_info = MicroInnovationIC200}, + {USB_DEVICE(0x0733, 0x0110), .driver_info = ViewQuestVQ110}, + {USB_DEVICE(0x0af9, 0x0010), .driver_info = HamaUSBSightcam}, + {USB_DEVICE(0x0af9, 0x0011), .driver_info = HamaUSBSightcam2}, + {USB_DEVICE(0x8086, 0x0110), .driver_info = IntelEasyPCCamera}, {} }; MODULE_DEVICE_TABLE(usb, device_table); diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c index 3b46f7dda641..a26174508cb9 100644 --- a/drivers/media/video/gspca/spca561.c +++ b/drivers/media/video/gspca/spca561.c @@ -975,21 +975,21 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x041e, 0x401a), Rev072A}, - {USB_DEVICE(0x041e, 0x403b), Rev012A}, - {USB_DEVICE(0x0458, 0x7004), Rev072A}, - {USB_DEVICE(0x046d, 0x0928), Rev012A}, - {USB_DEVICE(0x046d, 0x0929), Rev012A}, - {USB_DEVICE(0x046d, 0x092a), Rev012A}, - {USB_DEVICE(0x046d, 0x092b), Rev012A}, - {USB_DEVICE(0x046d, 0x092c), Rev012A}, - {USB_DEVICE(0x046d, 0x092d), Rev012A}, - {USB_DEVICE(0x046d, 0x092e), Rev012A}, - {USB_DEVICE(0x046d, 0x092f), Rev012A}, - {USB_DEVICE(0x04fc, 0x0561), Rev072A}, - {USB_DEVICE(0x060b, 0xa001), Rev072A}, - {USB_DEVICE(0x10fd, 0x7e50), Rev072A}, - {USB_DEVICE(0xabcd, 0xcdee), Rev072A}, + {USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A}, + {USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A}, + {USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A}, + {USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A}, + {USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A}, + {USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A}, + {USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A}, + {USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A}, + {USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A}, {} }; diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c index 5cf1af96d5f5..a4221753e1bf 100644 --- a/drivers/media/video/gspca/vc032x.c +++ b/drivers/media/video/gspca/vc032x.c @@ -1749,14 +1749,14 @@ static const struct sd_desc sd_desc = { /* -- module initialisation -- */ static const __devinitdata struct usb_device_id device_table[] = { - {USB_DEVICE(0x046d, 0x0892), BRIDGE_VC0321}, - {USB_DEVICE(0x046d, 0x0896), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0x0321), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0x0323), BRIDGE_VC0323}, - {USB_DEVICE(0x0ac8, 0x0328), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0xc001), BRIDGE_VC0321}, - {USB_DEVICE(0x0ac8, 0xc002), BRIDGE_VC0321}, - {USB_DEVICE(0x17ef, 0x4802), BRIDGE_VC0323}, + {USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323}, + {USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321}, + {USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323}, {} }; MODULE_DEVICE_TABLE(usb, device_table); -- cgit v1.2.3 From c52e4f5836cff0a70a25665f475cf5294c9fe5eb Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 27 Jul 2008 02:56:33 -0300 Subject: V4L/DVB (8521): gspca: Webcams with Sonix bridge and sensor ov7630 are VGA. This fixes a bug introduced in c503a6f8332a (thanks to Hans de Goede). Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/sonixb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c index 3db49a854fe2..e18748c5a14d 100644 --- a/drivers/media/video/gspca/sonixb.c +++ b/drivers/media/video/gspca/sonixb.c @@ -1194,7 +1194,7 @@ static __devinitdata struct usb_device_id device_table[] = { SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)}, #ifndef CONFIG_USB_SN9C102 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */ SFCI(TAS5130CXX, 0, 2, 0)}, {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */ @@ -1204,15 +1204,15 @@ static __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */ SFCI(PAS106, F_SIF, 2, 0)}, {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */ SFCI(HV7131R, 0, 2, 0)}, {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)}, {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */ SFCI(PAS202, F_H18, 2, 0)}, {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */ - SFCI(OV7630, F_GAIN|F_AUTO|F_SIF|F_H18, 5, 0x21)}, + SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)}, #endif {} }; -- cgit v1.2.3 From 0ea6bc8d43c9ee3c5384bea184eab020927a5b2c Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 08:26:43 -0300 Subject: V4L/DVB (8523): v4l2-dev: remove unused type and type2 field from video_device The type and type2 fields were unused and so could be removed. Instead add a vfl_type field that contains the type of the video device. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_fops.c | 2 +- drivers/media/radio/dsbr100.c | 1 - drivers/media/radio/miropcm20-radio.c | 1 - drivers/media/radio/radio-aimslab.c | 1 - drivers/media/radio/radio-aztech.c | 1 - drivers/media/radio/radio-cadet.c | 1 - drivers/media/radio/radio-gemtek-pci.c | 1 - drivers/media/radio/radio-gemtek.c | 1 - drivers/media/radio/radio-maestro.c | 1 - drivers/media/radio/radio-maxiradio.c | 1 - drivers/media/radio/radio-rtrack2.c | 1 - drivers/media/radio/radio-sf16fmi.c | 1 - drivers/media/radio/radio-sf16fmr2.c | 1 - drivers/media/radio/radio-si470x.c | 1 - drivers/media/radio/radio-terratec.c | 1 - drivers/media/radio/radio-trust.c | 1 - drivers/media/radio/radio-typhoon.c | 1 - drivers/media/radio/radio-zoltrix.c | 1 - drivers/media/video/bt8xx/bttv-driver.c | 23 +++++------------------ drivers/media/video/bw-qcam.c | 1 - drivers/media/video/c-qcam.c | 1 - drivers/media/video/cafe_ccic.c | 2 -- drivers/media/video/cpia.c | 1 - drivers/media/video/cpia2/cpia2_v4l.c | 3 --- drivers/media/video/cx18/cx18-streams.c | 3 --- drivers/media/video/cx23885/cx23885-417.c | 4 ---- drivers/media/video/cx23885/cx23885-video.c | 2 -- drivers/media/video/cx88/cx88-blackbird.c | 2 -- drivers/media/video/cx88/cx88-video.c | 3 --- drivers/media/video/em28xx/em28xx-video.c | 14 +++----------- drivers/media/video/et61x251/et61x251_core.c | 1 - drivers/media/video/gspca/gspca.c | 1 - drivers/media/video/ivtv/ivtv-streams.c | 5 ----- drivers/media/video/meye.c | 1 - drivers/media/video/ov511.c | 1 - drivers/media/video/pms.c | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 4 ---- drivers/media/video/pwc/pwc-if.c | 1 - drivers/media/video/s2255drv.c | 1 - drivers/media/video/saa5246a.c | 1 - drivers/media/video/saa5249.c | 1 - drivers/media/video/saa7134/saa7134-core.c | 9 +++------ drivers/media/video/saa7134/saa7134-empress.c | 2 -- drivers/media/video/saa7134/saa7134-video.c | 3 --- drivers/media/video/se401.c | 1 - drivers/media/video/sn9c102/sn9c102_core.c | 1 - drivers/media/video/soc_camera.c | 1 - drivers/media/video/stk-webcam.c | 2 -- drivers/media/video/stradis.c | 1 - drivers/media/video/stv680.c | 1 - drivers/media/video/usbvideo/usbvideo.c | 1 - drivers/media/video/usbvideo/vicam.c | 1 - drivers/media/video/usbvision/usbvision-video.c | 3 --- drivers/media/video/uvc/uvc_driver.c | 2 -- drivers/media/video/v4l2-dev.c | 1 + drivers/media/video/vino.c | 2 -- drivers/media/video/vivi.c | 1 - drivers/media/video/w9966.c | 1 - drivers/media/video/w9968cf.c | 1 - drivers/media/video/zc0301/zc0301_core.c | 1 - drivers/media/video/zoran_driver.c | 2 -- drivers/media/video/zr364xx.c | 1 - include/media/v4l2-dev.h | 3 +-- sound/i2c/other/tea575x-tuner.c | 1 - 64 files changed, 14 insertions(+), 124 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 171afe7da6b6..cf6a817d5059 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -563,7 +563,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev DEB_EE(("dev:%p\n",dev)); - if( VFL_TYPE_GRABBER == (*vid)->type ) { + if ((*vid)->vfl_type == VFL_TYPE_GRABBER) { vv->video_minor = -1; } else { vv->vbi_minor = -1; diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 0edada6f4b31..1ed88f3abe61 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -463,7 +463,6 @@ static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { /* V4L2 interface */ static struct video_device dsbr100_videodev_template = { .name = "D-Link DSB-R 100", - .type = VID_TYPE_TUNER, .fops = &usb_dsbr100_fops, .ioctl_ops = &usb_dsbr100_ioctl_ops, .release = video_device_release, diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c index 594e246dfcff..7fd7ee2d32c1 100644 --- a/drivers/media/radio/miropcm20-radio.c +++ b/drivers/media/radio/miropcm20-radio.c @@ -230,7 +230,6 @@ static const struct file_operations pcm20_fops = { static struct video_device pcm20_radio = { .name = "Miro PCM 20 radio", - .type = VID_TYPE_TUNER, .fops = &pcm20_fops, .priv = &pcm20_unit }; diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 2540df6dc2c8..eba9209b3024 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -406,7 +406,6 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { static struct video_device rtrack_radio = { .name = "RadioTrack radio", - .type = VID_TYPE_TUNER, .fops = &rtrack_fops, .ioctl_ops = &rtrack_ioctl_ops, }; diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 537f2f479506..3fe5504428c5 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -370,7 +370,6 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = { static struct video_device aztech_radio = { .name = "Aztech radio", - .type = VID_TYPE_TUNER, .fops = &aztech_fops, .ioctl_ops = &aztech_ioctl_ops, }; diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index 362a279f0680..6166e726ed72 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c @@ -587,7 +587,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = { static struct video_device cadet_radio = { .name = "Cadet radio", - .type = VID_TYPE_TUNER, .fops = &cadet_fops, .ioctl_ops = &cadet_ioctl_ops, }; diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index b8c515762b49..36e754e3ffb2 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c @@ -392,7 +392,6 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { static struct video_device vdev_template = { .name = "Gemtek PCI Radio", - .type = VID_TYPE_TUNER, .fops = &gemtek_pci_fops, .ioctl_ops = &gemtek_pci_ioctl_ops, }; diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 45b47c1643ee..2b1a6221de6d 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -570,7 +570,6 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = { static struct video_device gemtek_radio = { .name = "GemTek Radio card", - .type = VID_TYPE_TUNER, .fops = &gemtek_fops, .ioctl_ops = &gemtek_ioctl_ops, }; diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index d074a8c90674..0ada1c697e8a 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c @@ -372,7 +372,6 @@ static const struct v4l2_ioctl_ops maestro_ioctl_ops = { static struct video_device maestro_radio = { .name = "Maestro radio", - .type = VID_TYPE_TUNER, .fops = &maestro_fops, .ioctl_ops = &maestro_ioctl_ops, }; diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 1b9099606494..43c75497dc49 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -391,7 +391,6 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { static struct video_device maxiradio_radio = { .name = "Maxi Radio FM2000 radio", - .type = VID_TYPE_TUNER, .fops = &maxiradio_fops, .ioctl_ops = &maxiradio_ioctl_ops, }; diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index e065cb16dc5a..e2dde0807268 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -312,7 +312,6 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { static struct video_device rtrack2_radio = { .name = "RadioTrack II radio", - .type = VID_TYPE_TUNER, .fops = &rtrack2_fops, .ioctl_ops = &rtrack2_ioctl_ops, }; diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 975f8521848a..bb5d92f104af 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c @@ -312,7 +312,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = { static struct video_device fmi_radio = { .name = "SF16FMx radio", - .type = VID_TYPE_TUNER, .fops = &fmi_fops, .ioctl_ops = &fmi_ioctl_ops, }; diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 2786722b4946..6290553d24be 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -428,7 +428,6 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { static struct video_device fmr2_radio = { .name = "SF16FMR2 radio", - .type = VID_TYPE_TUNER, .fops = &fmr2_fops, .ioctl_ops = &fmr2_ioctl_ops, }; diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c index 3cf78ccdc58f..a4984ff87c9c 100644 --- a/drivers/media/radio/radio-si470x.c +++ b/drivers/media/radio/radio-si470x.c @@ -1609,7 +1609,6 @@ static struct video_device si470x_viddev_template = { .fops = &si470x_fops, .ioctl_ops = &si470x_ioctl_ops, .name = DRIVER_NAME, - .type = VID_TYPE_TUNER, .release = video_device_release, }; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index b3f669d0691f..cefa44fc5aed 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -384,7 +384,6 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = { static struct video_device terratec_radio = { .name = "TerraTec ActiveRadio", - .type = VID_TYPE_TUNER, .fops = &terratec_fops, .ioctl_ops = &terratec_ioctl_ops, }; diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 74aefda868e6..d70172d23edb 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -364,7 +364,6 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = { static struct video_device trust_radio = { .name = "Trust FM Radio", - .type = VID_TYPE_TUNER, .fops = &trust_fops, .ioctl_ops = &trust_ioctl_ops, }; diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 6eb39b7ab75e..f8d62cfea774 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -362,7 +362,6 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { static struct video_device typhoon_radio = { .name = "Typhoon Radio", - .type = VID_TYPE_TUNER, .fops = &typhoon_fops, .ioctl_ops = &typhoon_ioctl_ops, }; diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index 4afcb09a4af3..9f17a332fa11 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -425,7 +425,6 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { static struct video_device zoltrix_radio = { .name = "Zoltrix Radio Plus", - .type = VID_TYPE_TUNER, .fops = &zoltrix_fops, .ioctl_ops = &zoltrix_ioctl_ops, }; diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index dfa399da587d..85bf31ab8789 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -4182,8 +4182,7 @@ static irqreturn_t bttv_irq(int irq, void *dev_id) static struct video_device *vdev_init(struct bttv *btv, const struct video_device *template, - const char *type_name, - const int type) + const char *type_name) { struct video_device *vfd; @@ -4194,7 +4193,6 @@ static struct video_device *vdev_init(struct bttv *btv, vfd->minor = -1; vfd->parent = &btv->c.pci->dev; vfd->release = video_device_release; - vfd->type = type; vfd->debug = bttv_debug; snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", @@ -4230,20 +4228,11 @@ static void bttv_unregister_video(struct bttv *btv) /* register video4linux devices */ static int __devinit bttv_register_video(struct bttv *btv) { - int video_type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_CLIPPING| - VID_TYPE_SCALES; - - if (no_overlay <= 0) { - bttv_video_template.type |= VID_TYPE_OVERLAY; - } else { + if (no_overlay > 0) printk("bttv: Overlay support disabled.\n"); - } /* video */ - btv->video_dev = vdev_init(btv, &bttv_video_template, - "video", video_type); + btv->video_dev = vdev_init(btv, &bttv_video_template, "video"); if (NULL == btv->video_dev) goto err; @@ -4259,8 +4248,7 @@ static int __devinit bttv_register_video(struct bttv *btv) } /* vbi */ - btv->vbi_dev = vdev_init(btv, &bttv_video_template, - "vbi", VID_TYPE_TUNER | VID_TYPE_TELETEXT); + btv->vbi_dev = vdev_init(btv, &bttv_video_template, "vbi"); if (NULL == btv->vbi_dev) goto err; @@ -4272,8 +4260,7 @@ static int __devinit bttv_register_video(struct bttv *btv) if (!btv->has_radio) return 0; /* radio */ - btv->radio_dev = vdev_init(btv, &radio_template, - "radio", VID_TYPE_TUNER); + btv->radio_dev = vdev_init(btv, &radio_template, "radio"); if (NULL == btv->radio_dev) goto err; if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0) diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index ec870c781c02..d3b3268bace8 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -908,7 +908,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { .name = "Connectix Quickcam", - .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, }; diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 62ed8949d461..fe9379b282d3 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c @@ -703,7 +703,6 @@ static const struct file_operations qcam_fops = { static struct video_device qcam_template= { .name = "Colour QuickCam", - .type = VID_TYPE_CAPTURE, .fops = &qcam_fops, }; diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 4bbea458d0c0..c149b7d712e5 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -1794,8 +1794,6 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { static struct video_device cafe_v4l_template = { .name = "cafe", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, .minor = -1, /* Get one dynamically */ .tvnorms = V4L2_STD_NTSC_M, .current_norm = V4L2_STD_NTSC_M, /* make mplayer happy */ diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c index 5d2ef48137c4..dc8cc6115e2f 100644 --- a/drivers/media/video/cpia.c +++ b/drivers/media/video/cpia.c @@ -3800,7 +3800,6 @@ static const struct file_operations cpia_fops = { static struct video_device cpia_template = { .name = "CPiA Camera", - .type = VID_TYPE_CAPTURE, .fops = &cpia_fops, }; diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c index 4e45de78df59..515c8b57a60d 100644 --- a/drivers/media/video/cpia2/cpia2_v4l.c +++ b/drivers/media/video/cpia2/cpia2_v4l.c @@ -1937,9 +1937,6 @@ static const struct file_operations fops_template = { static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name= "CPiA2 Camera", - .type= VID_TYPE_CAPTURE, - .type2 = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING, .minor= -1, .fops= &fops_template, .release= video_device_release, diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 210a2416b320..0da57f583bf7 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c @@ -187,9 +187,6 @@ static int cx18_prep_dev(struct cx18 *cx, int type) return -ENOMEM; } - s->v4l2dev->type = - VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | - VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", cx->num); diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c index 9d15d8a353fa..8118091568fc 100644 --- a/drivers/media/video/cx23885/cx23885-417.c +++ b/drivers/media/video/cx23885/cx23885-417.c @@ -1731,10 +1731,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { static struct video_device cx23885_mpeg_template = { .name = "cx23885", - .type = VID_TYPE_CAPTURE | - VID_TYPE_TUNER | - VID_TYPE_SCALES | - VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index 308caa2085ba..ad2235dab5b1 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -1472,7 +1472,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { static struct video_device cx23885_vbi_template; static struct video_device cx23885_video_template = { .name = "cx23885-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, .fops = &video_fops, .minor = -1, .ioctl_ops = &video_ioctl_ops, @@ -1517,7 +1516,6 @@ int cx23885_video_register(struct cx23885_dev *dev) memcpy(&cx23885_vbi_template, &cx23885_video_template, sizeof(cx23885_vbi_template)); strcpy(cx23885_vbi_template.name, "cx23885-vbi"); - cx23885_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; dev->tvnorm = cx23885_video_template.current_norm; diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 55c35482089e..9a1374a38ec7 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -1207,8 +1207,6 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { static struct video_device cx8802_mpeg_template = { .name = "cx8802", - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | - VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER, .fops = &mpeg_fops, .ioctl_ops = &mpeg_ioctl_ops, .minor = -1, diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 24b403b238d1..ef4d56ea0027 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c @@ -1722,7 +1722,6 @@ static struct video_device cx8800_vbi_template; static struct video_device cx8800_video_template = { .name = "cx8800-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|VID_TYPE_SCALES, .fops = &video_fops, .minor = -1, .ioctl_ops = &video_ioctl_ops, @@ -1761,7 +1760,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device cx8800_radio_template = { .name = "cx8800-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .minor = -1, .ioctl_ops = &radio_ioctl_ops, @@ -1838,7 +1836,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, memcpy( &cx8800_vbi_template, &cx8800_video_template, sizeof(cx8800_vbi_template) ); strcpy(cx8800_vbi_template.name,"cx8800-vbi"); - cx8800_vbi_template.type = VID_TYPE_TELETEXT|VID_TYPE_TUNER; /* initialize driver struct */ spin_lock_init(&dev->slock); diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index fcfc7413f74c..49ab0629702e 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1845,7 +1845,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { static struct video_device em28xx_radio_template = { .name = "em28xx-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, .minor = -1, @@ -1891,7 +1890,6 @@ EXPORT_SYMBOL(em28xx_unregister_extension); static struct video_device *em28xx_vdev_init(struct em28xx *dev, const struct video_device *template, - const int type, const char *type_name) { struct video_device *vfd; @@ -1903,7 +1901,6 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, vfd->minor = -1; vfd->parent = &dev->udev->dev; vfd->release = video_device_release; - vfd->type = type; vfd->debug = video_debug; snprintf(vfd->name, sizeof(vfd->name), "%s %s", @@ -1981,14 +1978,11 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, list_add_tail(&dev->devlist, &em28xx_devlist); /* allocate and fill video video_device struct */ - dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, - VID_TYPE_CAPTURE, "video"); + dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); if (NULL == dev->vdev) { em28xx_errdev("cannot allocate video_device.\n"); goto fail_unreg; } - if (dev->tuner_type != TUNER_ABSENT) - dev->vdev->type |= VID_TYPE_TUNER; /* register v4l2 video video_device */ retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, @@ -2000,8 +1994,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } /* Allocate and fill vbi video_device struct */ - dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, - VFL_TYPE_VBI, "vbi"); + dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); /* register v4l2 vbi video_device */ if (video_register_device(dev->vbi_dev, VFL_TYPE_VBI, vbi_nr[dev->devno]) < 0) { @@ -2011,8 +2004,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, } if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { - dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, - VFL_TYPE_RADIO, "radio"); + dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio"); if (NULL == dev->radio_dev) { em28xx_errdev("cannot allocate video_device.\n"); goto fail_unreg; diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index 3e71ea7bbe24..2d170d101c21 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c @@ -2585,7 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &et61x251_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index ab053a26023e..bc301bae0482 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1691,7 +1691,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = { static struct video_device gspca_template = { .name = "gspca main driver", - .type = VID_TYPE_CAPTURE, .fops = &dev_fops, .ioctl_ops = &dev_ioctl_ops, .release = dev_release, /* mandatory */ diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index b883c4e08fbd..54d2023b26c4 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -208,11 +208,6 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) return -ENOMEM; } - s->v4l2dev->type = VID_TYPE_CAPTURE | VID_TYPE_TUNER | VID_TYPE_TELETEXT | - VID_TYPE_CLIPPING | VID_TYPE_SCALES | VID_TYPE_MPEG_ENCODER; - if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { - s->v4l2dev->type |= VID_TYPE_MPEG_DECODER; - } snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "ivtv%d %s", itv->num, s->name); diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index f9a6e1e8b4bd..7c8ef6ac6c39 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1721,7 +1721,6 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = { static struct video_device meye_template = { .name = "meye", - .type = VID_TYPE_CAPTURE, .fops = &meye_fops, .ioctl_ops = &meye_ioctl_ops, .release = video_device_release, diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c index 2374ebc084d4..9edaca4371d7 100644 --- a/drivers/media/video/ov511.c +++ b/drivers/media/video/ov511.c @@ -4667,7 +4667,6 @@ static const struct file_operations ov511_fops = { static struct video_device vdev_template = { .name = "OV511 USB Camera", - .type = VID_TYPE_CAPTURE, .fops = &ov511_fops, .release = video_device_release, .minor = -1, diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 8c72e4df85ab..00425d743656 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -896,7 +896,6 @@ static const struct file_operations pms_fops = { static struct video_device pms_template= { .name = "Mediavision PMS", - .type = VID_TYPE_CAPTURE, .fops = &pms_fops, }; diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index ceb549ac752d..00306faeac01 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -1161,10 +1161,6 @@ static const struct file_operations vdev_fops = { static struct video_device vdev_template = { - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, - .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE - | V4L2_CAP_TUNER | V4L2_CAP_AUDIO - | V4L2_CAP_READWRITE), .fops = &vdev_fops, }; diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 436a47caf52d..9aee7cb6f79a 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -166,7 +166,6 @@ static const struct file_operations pwc_fops = { }; static struct video_device pwc_template = { .name = "Philips Webcam", /* Filled in later */ - .type = VID_TYPE_CAPTURE, .release = video_device_release, .fops = &pwc_fops, .minor = -1, diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c index 92dfb1845ff4..b1d09d8e2b85 100644 --- a/drivers/media/video/s2255drv.c +++ b/drivers/media/video/s2255drv.c @@ -1705,7 +1705,6 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = { static struct video_device template = { .name = "s2255v", - .type = VID_TYPE_CAPTURE, .fops = &s2255_fops_v4l, .ioctl_ops = &s2255_ioctl_ops, .minor = -1, diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c index e6a3fa482982..6ee63e69b36c 100644 --- a/drivers/media/video/saa5246a.c +++ b/drivers/media/video/saa5246a.c @@ -831,7 +831,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { .name = IF_NAME, - .type = VID_TYPE_TELETEXT, .fops = &saa_fops, .release = video_device_release, .minor = -1, diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c index 6f14619bda4a..0d639738d4e6 100644 --- a/drivers/media/video/saa5249.c +++ b/drivers/media/video/saa5249.c @@ -712,7 +712,6 @@ static const struct file_operations saa_fops = { static struct video_device saa_template = { .name = IF_NAME, - .type = VID_TYPE_TELETEXT, /*| VID_TYPE_TUNER ?? */ .fops = &saa_fops, }; diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index a404368308aa..75d618415f4f 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -1008,11 +1008,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, v4l2_prio_init(&dev->prio); /* register v4l devices */ - if (saa7134_no_overlay <= 0) { - saa7134_video_template.type |= VID_TYPE_OVERLAY; - } else { - printk("%s: Overlay support disabled.\n",dev->name); - } + if (saa7134_no_overlay > 0) + printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name); + dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); err = video_register_device(dev->video_dev,VFL_TYPE_GRABBER, video_nr[dev->nr]); @@ -1025,7 +1023,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->name,dev->video_dev->minor & 0x1f); dev->vbi_dev = vdev_init(dev, &saa7134_video_template, "vbi"); - dev->vbi_dev->type = VID_TYPE_TUNER | VID_TYPE_TELETEXT; err = video_register_device(dev->vbi_dev,VFL_TYPE_VBI, vbi_nr[dev->nr]); diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index cd52d5be404d..c0c5d7509c25 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -439,8 +439,6 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { static struct video_device saa7134_empress_template = { .name = "saa7134-empress", - .type = 0 /* FIXME */, - .type2 = 0 /* FIXME */, .fops = &ts_fops, .minor = -1, .ioctl_ops = &ts_ioctl_ops, diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c index eb824897416b..68c268981861 100644 --- a/drivers/media/video/saa7134/saa7134-video.c +++ b/drivers/media/video/saa7134/saa7134-video.c @@ -2451,8 +2451,6 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = { struct video_device saa7134_video_template = { .name = "saa7134-video", - .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER | - VID_TYPE_CLIPPING|VID_TYPE_SCALES, .fops = &video_fops, .ioctl_ops = &video_ioctl_ops, .minor = -1, @@ -2462,7 +2460,6 @@ struct video_device saa7134_video_template = { struct video_device saa7134_radio_template = { .name = "saa7134-radio", - .type = VID_TYPE_TUNER, .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, .minor = -1, diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c index b4dd60b0f8f2..f481277892da 100644 --- a/drivers/media/video/se401.c +++ b/drivers/media/video/se401.c @@ -1231,7 +1231,6 @@ static const struct file_operations se401_fops = { }; static struct video_device se401_template = { .name = "se401 USB camera", - .type = VID_TYPE_CAPTURE, .fops = &se401_fops, }; diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index c68bf0921e9e..23408764d0ef 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c @@ -3309,7 +3309,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "SN9C1xx PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 9ff561452587..b6be5ee678b6 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -908,7 +908,6 @@ int soc_camera_video_start(struct soc_camera_device *icd) strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); /* Maybe better &ici->dev */ vdev->parent = &icd->dev; - vdev->type = VID_TYPE_CAPTURE; vdev->current_norm = V4L2_STD_UNKNOWN; vdev->fops = &soc_camera_fops; vdev->ioctl_ops = &soc_camera_ioctl_ops; diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c index a8a72768ca91..ad36af30e099 100644 --- a/drivers/media/video/stk-webcam.c +++ b/drivers/media/video/stk-webcam.c @@ -1359,8 +1359,6 @@ static void stk_v4l_dev_release(struct video_device *vd) static struct video_device stk_v4l_data = { .name = "stkwebcam", - .type = VFL_TYPE_GRABBER, - .type2 = VID_TYPE_CAPTURE, .minor = -1, .tvnorms = V4L2_STD_UNKNOWN, .current_norm = V4L2_STD_UNKNOWN, diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 6ace8923b797..276bded06ab3 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c @@ -1919,7 +1919,6 @@ static const struct file_operations saa_fops = { /* template for video_device-structure */ static struct video_device saa_template = { .name = "SAA7146A", - .type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY, .fops = &saa_fops, .minor = -1, }; diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c index 9053d5a0b1c3..56dc3d6b5b29 100644 --- a/drivers/media/video/stv680.c +++ b/drivers/media/video/stv680.c @@ -1403,7 +1403,6 @@ static const struct file_operations stv680_fops = { }; static struct video_device stv680_template = { .name = "STV0680 USB camera", - .type = VID_TYPE_CAPTURE, .fops = &stv680_fops, .release = video_device_release, .minor = -1, diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c index 357cee40fb38..bf1bc2f69b02 100644 --- a/drivers/media/video/usbvideo/usbvideo.c +++ b/drivers/media/video/usbvideo/usbvideo.c @@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = { .llseek = no_llseek, }; static const struct video_device usbvideo_template = { - .type = VID_TYPE_CAPTURE, .fops = &usbvideo_fops, }; diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c index b8e8fceee525..b7792451a299 100644 --- a/drivers/media/video/usbvideo/vicam.c +++ b/drivers/media/video/usbvideo/vicam.c @@ -793,7 +793,6 @@ static const struct file_operations vicam_fops = { static struct video_device vicam_template = { .name = "ViCam-based USB Camera", - .type = VID_TYPE_CAPTURE, .fops = &vicam_fops, .minor = -1, }; diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index a65e5db0a325..b977116a0dd9 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1405,7 +1405,6 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = { }; static struct video_device usbvision_video_template = { - .type = VID_TYPE_TUNER | VID_TYPE_CAPTURE, .fops = &usbvision_fops, .ioctl_ops = &usbvision_ioctl_ops, .name = "usbvision-video", @@ -1443,7 +1442,6 @@ static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = { }; static struct video_device usbvision_radio_template = { - .type = VID_TYPE_TUNER, .fops = &usbvision_radio_fops, .name = "usbvision-radio", .release = video_device_release, @@ -1466,7 +1464,6 @@ static const struct file_operations usbvision_vbi_fops = { static struct video_device usbvision_vbi_template= { - .type = VID_TYPE_TUNER, .fops = &usbvision_vbi_fops, .release = video_device_release, .name = "usbvision-vbi", diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index 79d6821c4741..b3c4d75e8490 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c @@ -1459,8 +1459,6 @@ static int uvc_register_video(struct uvc_device *dev) * get another one. */ vdev->parent = &dev->intf->dev; - vdev->type = 0; - vdev->type2 = 0; vdev->minor = -1; vdev->fops = &uvc_fops; vdev->release = video_device_release; diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 88eeee1d8baf..556615fe93de 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -302,6 +302,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, } } video_device[i] = vfd; + vfd->vfl_type = type; vfd->minor = i; ret = get_index(vfd, index); diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index f0fcb008b723..3989b0eded28 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -4385,8 +4385,6 @@ static const struct file_operations vino_fops = { 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 */ .fops = &vino_fops, .minor = -1, }; diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 639210e52647..3518af071a2e 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1092,7 +1092,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = { static struct video_device vivi_template = { .name = "vivi", - .type = VID_TYPE_CAPTURE, .fops = &vivi_fops, .ioctl_ops = &vivi_ioctl_ops, .minor = -1, diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 925b4e7b557d..9402f40095b4 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -197,7 +197,6 @@ static const struct file_operations w9966_fops = { }; static struct video_device w9966_template = { .name = W9966_DRIVERNAME, - .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES, .fops = &w9966_fops, }; diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c index 8f665953c80c..168baabe4659 100644 --- a/drivers/media/video/w9968cf.c +++ b/drivers/media/video/w9968cf.c @@ -3550,7 +3550,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, symbolic(camlist, mod_id)); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &w9968cf_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c index 0978a7e946b4..550ce7bd5c87 100644 --- a/drivers/media/video/zc0301/zc0301_core.c +++ b/drivers/media/video/zc0301/zc0301_core.c @@ -1985,7 +1985,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) } strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera"); - cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; cam->v4ldev->fops = &zc0301_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c index 3ca58221d5a9..ec6f59674b10 100644 --- a/drivers/media/video/zoran_driver.c +++ b/drivers/media/video/zoran_driver.c @@ -4644,8 +4644,6 @@ static const struct file_operations zoran_fops = { struct video_device zoran_template __devinitdata = { .name = ZORAN_NAME, - .type = ZORAN_VID_TYPE, - .type2 = ZORAN_V4L2_VID_FLAGS, .fops = &zoran_fops, .release = &zoran_vdev_release, .minor = -1 diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c index 36ba36a5e2ea..18d1c4ba79fb 100644 --- a/drivers/media/video/zr364xx.c +++ b/drivers/media/video/zr364xx.c @@ -780,7 +780,6 @@ static const struct v4l2_ioctl_ops zr364xx_ioctl_ops = { static struct video_device zr364xx_template = { .name = DRIVER_DESC, - .type = VID_TYPE_CAPTURE, .fops = &zr364xx_fops, .ioctl_ops = &zr364xx_ioctl_ops, .release = video_device_release, diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 2fe38858516b..21419da44cb6 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -53,8 +53,7 @@ struct video_device /* device info */ char name[32]; - int type; /* v4l1 */ - int type2; /* v4l2 */ + int vfl_type; int minor; /* attribute to diferentiate multiple indexs on one physical device */ int index; diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 187c9527725f..83e90057270e 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -190,7 +190,6 @@ void snd_tea575x_init(struct snd_tea575x *tea) memset(&tea->vd, 0, sizeof(tea->vd)); strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio"); - tea->vd.type = VID_TYPE_TUNER; tea->vd.release = snd_tea575x_release; video_set_drvdata(&tea->vd, tea); tea->vd.fops = &tea->fops; -- cgit v1.2.3 From de1e575db21a341b77b296af7dd87f163ebf6020 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 08:37:58 -0300 Subject: V4L/DVB (8525): fix a few assorted spelling mistakes. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/videobuf-vmalloc.c | 2 +- include/media/v4l2-dev.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c index a868b7ed75ff..be65a2fb3976 100644 --- a/drivers/media/video/videobuf-vmalloc.c +++ b/drivers/media/video/videobuf-vmalloc.c @@ -203,7 +203,7 @@ static int __videobuf_iolock (struct videobuf_queue* q, return 0; /* FIXME: to properly support USERPTR, remap should occur. - The code bellow won't work, since mem->vma = NULL + The code below won't work, since mem->vma = NULL */ /* Try to remap memory */ rc = remap_vmalloc_range(mem->vma, (void *)vb->baddr, 0); diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 21419da44cb6..2745e1afc722 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -55,7 +55,7 @@ struct video_device char name[32]; int vfl_type; int minor; - /* attribute to diferentiate multiple indexs on one physical device */ + /* attribute to differentiate multiple indices on one physical device */ int index; int debug; /* Activates debug level*/ @@ -78,7 +78,7 @@ struct video_device void *priv; #endif - /* for videodev.c intenal usage -- please don't touch */ + /* for videodev.c internal usage -- please don't touch */ int users; /* video_exclusive_{open|close} ... */ struct mutex lock; /* ... helper function uses these */ }; -- cgit v1.2.3 From f796804f01429b832e1e734c54f0f535b322c665 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 26 Jul 2008 09:16:29 -0300 Subject: V4L/DVB (8526): saa7146: fix VIDIOC_ENUM_FMT VIDIOC_ENUM_FMT should keep the index and type fields. Instead, type was zeroed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_video.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index a5e62750eea3..acaddc15dadc 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -958,21 +958,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; - int index; switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: - case V4L2_BUF_TYPE_VIDEO_OVERLAY: { - index = f->index; - if (index < 0 || index >= NUM_FORMATS) { + case V4L2_BUF_TYPE_VIDEO_OVERLAY: + if (f->index >= NUM_FORMATS) return -EINVAL; - } - memset(f,0,sizeof(*f)); - f->index = index; - strlcpy((char *)f->description,formats[index].name,sizeof(f->description)); - f->pixelformat = formats[index].pixelformat; + strlcpy((char *)f->description, formats[f->index].name, + sizeof(f->description)); + f->pixelformat = formats[f->index].pixelformat; + f->flags = 0; + memset(f->reserved, 0, sizeof(f->reserved)); break; - } default: return -EINVAL; } -- cgit v1.2.3 From 2a83e4d5e40fd8eda3c04a5847f0876a4be9d45b Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 7 Jul 2008 18:20:58 -0300 Subject: V4L/DVB (8528): add support for MaxLinear MxL5007T silicon tuner Signed-off-by: Michael Krufky Signed-off-by: Asaf Fishov Signed-off-by: Charles Kim Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/Kconfig | 7 + drivers/media/common/tuners/Makefile | 1 + drivers/media/common/tuners/mxl5007t.c | 1017 ++++++++++++++++++++++++++++++++ drivers/media/common/tuners/mxl5007t.h | 105 ++++ 4 files changed, 1130 insertions(+) create mode 100644 drivers/media/common/tuners/mxl5007t.c create mode 100644 drivers/media/common/tuners/mxl5007t.h (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 850d5689b14d..8d93ba857361 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -162,4 +162,11 @@ config MEDIA_TUNER_MXL5005S help A driver for the silicon tuner MXL5005S from MaxLinear. +config MEDIA_TUNER_MXL5007T + tristate "MaxLinear MxL5007T silicon tuner" + depends on VIDEO_MEDIA && I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the silicon tuner MxL5007T from MaxLinear. + endif # MEDIA_TUNER_CUSTOMIZE diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile index 55f7e6706297..4dfbe5b8264f 100644 --- a/drivers/media/common/tuners/Makefile +++ b/drivers/media/common/tuners/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o +obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core EXTRA_CFLAGS += -Idrivers/media/dvb/frontends diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c new file mode 100644 index 000000000000..80cfa9ba1dcf --- /dev/null +++ b/drivers/media/common/tuners/mxl5007t.c @@ -0,0 +1,1017 @@ +/* + * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner + * + * Copyright (C) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "tuner-i2c.h" +#include "mxl5007t.h" + +static DEFINE_MUTEX(mxl5007t_list_mutex); +static LIST_HEAD(hybrid_tuner_instance_list); + +static int mxl5007t_debug; +module_param_named(debug, mxl5007t_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debug level"); + +/* ------------------------------------------------------------------------- */ + +#define mxl_printk(kern, fmt, arg...) \ + printk(kern "%s: " fmt "\n", __func__, ##arg) + +#define mxl_err(fmt, arg...) \ + mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg) + +#define mxl_warn(fmt, arg...) \ + mxl_printk(KERN_WARNING, fmt, ##arg) + +#define mxl_info(fmt, arg...) \ + mxl_printk(KERN_INFO, fmt, ##arg) + +#define mxl_debug(fmt, arg...) \ +({ \ + if (mxl5007t_debug) \ + mxl_printk(KERN_DEBUG, fmt, ##arg); \ +}) + +#define mxl_fail(ret) \ +({ \ + int __ret; \ + __ret = (ret < 0); \ + if (__ret) \ + mxl_printk(KERN_ERR, "error %d on line %d", \ + ret, __LINE__); \ + __ret; \ +}) + +/* ------------------------------------------------------------------------- */ + +#define MHz 1000000 + +enum mxl5007t_mode { + MxL_MODE_OTA_DVBT_ATSC = 0, + MxL_MODE_OTA_NTSC_PAL_GH = 1, + MxL_MODE_OTA_PAL_IB = 2, + MxL_MODE_OTA_PAL_D_SECAM_KL = 3, + MxL_MODE_OTA_ISDBT = 4, + MxL_MODE_CABLE_DIGITAL = 0x10, + MxL_MODE_CABLE_NTSC_PAL_GH = 0x11, + MxL_MODE_CABLE_PAL_IB = 0x12, + MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13, + MxL_MODE_CABLE_SCTE40 = 0x14, +}; + +enum mxl5007t_chip_version { + MxL_UNKNOWN_ID = 0x00, + MxL_5007_V1_F1 = 0x11, + MxL_5007_V1_F2 = 0x12, + MxL_5007_V2_100_F1 = 0x21, + MxL_5007_V2_100_F2 = 0x22, + MxL_5007_V2_200_F1 = 0x23, + MxL_5007_V2_200_F2 = 0x24, +}; + +struct reg_pair_t { + u8 reg; + u8 val; +}; + +/* ------------------------------------------------------------------------- */ + +static struct reg_pair_t init_tab[] = { + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE Analog/Digital */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x83, 0x00 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0, 0 } +}; + +static struct reg_pair_t init_tab_cable[] = { + { 0x0b, 0x44 }, /* XTAL */ + { 0x0c, 0x60 }, /* IF */ + { 0x10, 0x00 }, /* MISC */ + { 0x12, 0xca }, /* IDAC */ + { 0x16, 0x90 }, /* MODE */ + { 0x32, 0x38 }, /* MODE A/D */ + { 0x71, 0x3f }, /* TOP1 */ + { 0x72, 0x3f }, /* TOP2 */ + { 0x74, 0x3f }, /* TOP3 */ + { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ + { 0x2c, 0x34 }, /* OVERRIDE */ + { 0x4d, 0x40 }, /* OVERRIDE */ + { 0x7f, 0x02 }, /* OVERRIDE */ + { 0x9a, 0x52 }, /* OVERRIDE */ + { 0x48, 0x5a }, /* OVERRIDE */ + { 0x76, 0x1a }, /* OVERRIDE */ + { 0x6a, 0x48 }, /* OVERRIDE */ + { 0x64, 0x28 }, /* OVERRIDE */ + { 0x66, 0xe6 }, /* OVERRIDE */ + { 0x35, 0x0e }, /* OVERRIDE */ + { 0x7e, 0x01 }, /* OVERRIDE */ + { 0x04, 0x0b }, /* OVERRIDE */ + { 0x68, 0xb4 }, /* OVERRIDE */ + { 0x36, 0x00 }, /* OVERRIDE */ + { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ + { 0, 0 } +}; + +/* ------------------------------------------------------------------------- */ + +static struct reg_pair_t reg_pair_rftune[] = { + { 0x11, 0x00 }, /* abort tune */ + { 0x13, 0x15 }, + { 0x14, 0x40 }, + { 0x15, 0x0e }, + { 0x11, 0x02 }, /* start tune */ + { 0, 0 } +}; + +/* ------------------------------------------------------------------------- */ + +struct mxl5007t_state { + struct list_head hybrid_tuner_instance_list; + struct tuner_i2c_props i2c_props; + + struct mutex lock; + + struct mxl5007t_config *config; + + enum mxl5007t_chip_version chip_id; + + struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)]; + struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)]; + struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)]; + + u32 frequency; + u32 bandwidth; +}; + +/* ------------------------------------------------------------------------- */ + +/* called by _init and _rftun to manipulate the register arrays */ + +static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val) +{ + unsigned int i = 0; + + while (reg_pair[i].reg || reg_pair[i].val) { + if (reg_pair[i].reg == reg) { + reg_pair[i].val &= ~mask; + reg_pair[i].val |= val; + } + i++; + + } + return; +} + +static void copy_reg_bits(struct reg_pair_t *reg_pair1, + struct reg_pair_t *reg_pair2) +{ + unsigned int i, j; + + i = j = 0; + + while (reg_pair1[i].reg || reg_pair1[i].val) { + while (reg_pair2[j].reg || reg_pair2[j].reg) { + if (reg_pair1[i].reg != reg_pair2[j].reg) { + j++; + continue; + } + reg_pair2[j].val = reg_pair1[i].val; + break; + } + i++; + } + return; +} + +/* ------------------------------------------------------------------------- */ + +static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, + enum mxl5007t_mode mode, + s32 if_diff_out_level) +{ + switch (mode) { + case MxL_MODE_OTA_DVBT_ATSC: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e); + break; + case MxL_MODE_OTA_ISDBT: + set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); + set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); + break; + case MxL_MODE_OTA_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_OTA_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_OTA_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + break; + case MxL_MODE_CABLE_DIGITAL: + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_NTSC_PAL_GH: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_IB: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_PAL_D_SECAM_KL: + set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); + set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + case MxL_MODE_CABLE_SCTE40: + set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08); + set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc); + set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); + set_reg_bits(state->tab_init_cable, 0x72, 0xff, + 8 - if_diff_out_level); + set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); + break; + default: + mxl_fail(-EINVAL); + } + return; +} + +static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, + enum mxl5007t_if_freq if_freq, + int invert_if) +{ + u8 val; + + switch (if_freq) { + case MxL_IF_4_MHZ: + val = 0x00; + break; + case MxL_IF_4_5_MHZ: + val = 0x20; + break; + case MxL_IF_4_57_MHZ: + val = 0x30; + break; + case MxL_IF_5_MHZ: + val = 0x40; + break; + case MxL_IF_5_38_MHZ: + val = 0x50; + break; + case MxL_IF_6_MHZ: + val = 0x60; + break; + case MxL_IF_6_28_MHZ: + val = 0x70; + break; + case MxL_IF_9_1915_MHZ: + val = 0x80; + break; + case MxL_IF_35_25_MHZ: + val = 0x90; + break; + case MxL_IF_36_15_MHZ: + val = 0xa0; + break; + case MxL_IF_44_MHZ: + val = 0xb0; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_init, 0x0c, 0xf0, val); + + /* set inverted IF or normal IF */ + set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00); + + return; +} + +static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, + enum mxl5007t_xtal_freq xtal_freq) +{ + u8 val; + + switch (xtal_freq) { + case MxL_XTAL_16_MHZ: + val = 0x00; /* select xtal freq & Ref Freq */ + break; + case MxL_XTAL_20_MHZ: + val = 0x11; + break; + case MxL_XTAL_20_25_MHZ: + val = 0x22; + break; + case MxL_XTAL_20_48_MHZ: + val = 0x33; + break; + case MxL_XTAL_24_MHZ: + val = 0x44; + break; + case MxL_XTAL_25_MHZ: + val = 0x55; + break; + case MxL_XTAL_25_14_MHZ: + val = 0x66; + break; + case MxL_XTAL_27_MHZ: + val = 0x77; + break; + case MxL_XTAL_28_8_MHZ: + val = 0x88; + break; + case MxL_XTAL_32_MHZ: + val = 0x99; + break; + case MxL_XTAL_40_MHZ: + val = 0xaa; + break; + case MxL_XTAL_44_MHZ: + val = 0xbb; + break; + case MxL_XTAL_48_MHZ: + val = 0xcc; + break; + case MxL_XTAL_49_3811_MHZ: + val = 0xdd; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_init, 0x0b, 0xff, val); + + return; +} + +static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, + enum mxl5007t_mode mode) +{ + struct mxl5007t_config *cfg = state->config; + + memcpy(&state->tab_init, &init_tab, sizeof(init_tab)); + memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable)); + + mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level); + mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); + mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); + + set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6); + + set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3); + + set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp); + + /* set IDAC to automatic mode control by AGC */ + set_reg_bits(state->tab_init, 0x12, 0x80, 0x00); + + if (mode >= MxL_MODE_CABLE_DIGITAL) { + copy_reg_bits(state->tab_init, state->tab_init_cable); + return state->tab_init_cable; + } else + return state->tab_init; +} + +/* ------------------------------------------------------------------------- */ + +enum mxl5007t_bw_mhz { + MxL_BW_6MHz = 6, + MxL_BW_7MHz = 7, + MxL_BW_8MHz = 8, +}; + +static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, + enum mxl5007t_bw_mhz bw) +{ + u8 val; + + switch (bw) { + case MxL_BW_6MHz: + val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A, + * and DIG_MODEINDEX_CSF */ + break; + case MxL_BW_7MHz: + val = 0x21; + break; + case MxL_BW_8MHz: + val = 0x3f; + break; + default: + mxl_fail(-EINVAL); + return; + } + set_reg_bits(state->tab_rftune, 0x13, 0x3f, val); + + return; +} + +static struct +reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state, + u32 rf_freq, enum mxl5007t_bw_mhz bw) +{ + u32 dig_rf_freq = 0; + u32 temp; + u32 frac_divider = 1000000; + unsigned int i; + + memcpy(&state->tab_rftune, ®_pair_rftune, sizeof(reg_pair_rftune)); + + mxl5007t_set_bw_bits(state, bw); + + /* Convert RF frequency into 16 bits => + * 10 bit integer (MHz) + 6 bit fraction */ + dig_rf_freq = rf_freq / MHz; + + temp = rf_freq % MHz; + + for (i = 0; i < 6; i++) { + dig_rf_freq <<= 1; + frac_divider /= 2; + if (temp > frac_divider) { + temp -= frac_divider; + dig_rf_freq++; + } + } + + /* add to have shift center point by 7.8124 kHz */ + if (temp > 7812) + dig_rf_freq++; + + set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq); + set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8)); + + return state->tab_rftune; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val) +{ + u8 buf[] = { reg, val }; + struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, + .buf = buf, .len = 2 }; + int ret; + + ret = i2c_transfer(state->i2c_props.adap, &msg, 1); + if (ret != 1) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_write_regs(struct mxl5007t_state *state, + struct reg_pair_t *reg_pair) +{ + unsigned int i = 0; + int ret = 0; + + while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) { + ret = mxl5007t_write_reg(state, + reg_pair[i].reg, reg_pair[i].val); + i++; + } + return ret; +} + +static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) +{ + struct i2c_msg msg[] = { + { .addr = state->i2c_props.addr, .flags = 0, + .buf = ®, .len = 1 }, + { .addr = state->i2c_props.addr, .flags = I2C_M_RD, + .buf = val, .len = 1 }, + }; + int ret; + + ret = i2c_transfer(state->i2c_props.adap, msg, 2); + if (ret != 2) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_soft_reset(struct mxl5007t_state *state) +{ + u8 d = 0xff; + struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, + .buf = &d, .len = 1 }; + + int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); + + if (ret != 1) { + mxl_err("failed!"); + return -EREMOTEIO; + } + return 0; +} + +static int mxl5007t_tuner_init(struct mxl5007t_state *state, + enum mxl5007t_mode mode) +{ + struct reg_pair_t *init_regs; + int ret; + + ret = mxl5007t_soft_reset(state); + if (mxl_fail(ret)) + goto fail; + + /* calculate initialization reg array */ + init_regs = mxl5007t_calc_init_regs(state, mode); + + ret = mxl5007t_write_regs(state, init_regs); + if (mxl_fail(ret)) + goto fail; + mdelay(1); + + ret = mxl5007t_write_reg(state, 0x2c, 0x35); + mxl_fail(ret); +fail: + return ret; +} + +static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz, + enum mxl5007t_bw_mhz bw) +{ + struct reg_pair_t *rf_tune_regs; + int ret; + + /* calculate channel change reg array */ + rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw); + + ret = mxl5007t_write_regs(state, rf_tune_regs); + if (mxl_fail(ret)) + goto fail; + msleep(3); +fail: + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, + int *rf_locked, int *ref_locked) +{ + u8 d; + int ret; + + *rf_locked = 0; + *ref_locked = 0; + + ret = mxl5007t_read_reg(state, 0xcf, &d); + if (mxl_fail(ret)) + goto fail; + + if ((d & 0x0c) == 0x0c) + *rf_locked = 1; + + if ((d & 0x03) == 0x03) + *ref_locked = 1; +fail: + return ret; +} + +static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state, + s32 *rf_input_level) +{ + u8 d1, d2; + int ret; + + ret = mxl5007t_read_reg(state, 0xb7, &d1); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_read_reg(state, 0xbf, &d2); + if (mxl_fail(ret)) + goto fail; + + d2 = d2 >> 4; + if (d2 > 7) + d2 += 0xf0; + + *rf_input_level = (s32)(d1 + d2 - 113); +fail: + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) +{ + struct mxl5007t_state *state = fe->tuner_priv; + int rf_locked, ref_locked; + s32 rf_input_level; + int ret; + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); + if (mxl_fail(ret)) + goto fail; + mxl_debug("%s%s", rf_locked ? "rf locked " : "", + ref_locked ? "ref locked" : ""); + + ret = mxl5007t_check_rf_input_power(state, &rf_input_level); + if (mxl_fail(ret)) + goto fail; + mxl_debug("rf input power: %d", rf_input_level); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct mxl5007t_state *state = fe->tuner_priv; + enum mxl5007t_bw_mhz bw; + enum mxl5007t_mode mode; + int ret; + u32 freq = params->frequency; + + if (fe->ops.info.type == FE_ATSC) { + switch (params->u.vsb.modulation) { + case VSB_8: + case VSB_16: + mode = MxL_MODE_OTA_DVBT_ATSC; + break; + case QAM_64: + case QAM_256: + mode = MxL_MODE_CABLE_DIGITAL; + break; + default: + mxl_err("modulation not set!"); + return -EINVAL; + } + bw = MxL_BW_6MHz; + } else if (fe->ops.info.type == FE_OFDM) { + switch (params->u.ofdm.bandwidth) { + case BANDWIDTH_6_MHZ: + bw = MxL_BW_6MHz; + break; + case BANDWIDTH_7_MHZ: + bw = MxL_BW_7MHz; + break; + case BANDWIDTH_8_MHZ: + bw = MxL_BW_8MHz; + break; + default: + mxl_err("bandwidth not set!"); + return -EINVAL; + } + mode = MxL_MODE_OTA_DVBT_ATSC; + } else { + mxl_err("modulation type not supported!"); + return -EINVAL; + } + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_tuner_init(state, mode); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_tuner_rf_tune(state, freq, bw); + if (mxl_fail(ret)) + goto fail; + + state->frequency = freq; + state->bandwidth = (fe->ops.info.type == FE_OFDM) ? + params->u.ofdm.bandwidth : 0; +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +static int mxl5007t_set_analog_params(struct dvb_frontend *fe, + struct analog_parameters *params) +{ + struct mxl5007t_state *state = fe->tuner_priv; + enum mxl5007t_bw_mhz bw = 0; /* FIXME */ + enum mxl5007t_mode cbl_mode; + enum mxl5007t_mode ota_mode; + char *mode_name; + int ret; + u32 freq = params->frequency * 62500; + +#define cable 1 + if (params->std & V4L2_STD_MN) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "MN"; + } else if (params->std & V4L2_STD_B) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "B"; + } else if (params->std & V4L2_STD_GH) { + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + mode_name = "GH"; + } else if (params->std & V4L2_STD_PAL_I) { + cbl_mode = MxL_MODE_CABLE_PAL_IB; + ota_mode = MxL_MODE_OTA_PAL_IB; + mode_name = "I"; + } else if (params->std & V4L2_STD_DK) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "DK"; + } else if (params->std & V4L2_STD_SECAM_L) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L"; + } else if (params->std & V4L2_STD_SECAM_LC) { + cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; + ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; + mode_name = "L'"; + } else { + mode_name = "xx"; + /* FIXME */ + cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; + ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; + } + mxl_debug("setting mxl5007 to system %s", mode_name); + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_tuner_rf_tune(state, freq, bw); + if (mxl_fail(ret)) + goto fail; + + state->frequency = freq; + state->bandwidth = 0; +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + return ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_init(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + //int ret; + + mutex_lock(&state->lock); + /* do init */ +//fail: + mutex_unlock(&state->lock); + + return 0;//ret; +} + +static int mxl5007t_sleep(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + //int ret; + + mutex_lock(&state->lock); + /* do standby */ +//fail: + mutex_unlock(&state->lock); + + return 0;//ret; +} + +/* ------------------------------------------------------------------------- */ + +static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct mxl5007t_state *state = fe->tuner_priv; + *frequency = state->frequency; + return 0; +} + +static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) +{ + struct mxl5007t_state *state = fe->tuner_priv; + *bandwidth = state->bandwidth; + return 0; +} + +static int mxl5007t_release(struct dvb_frontend *fe) +{ + struct mxl5007t_state *state = fe->tuner_priv; + + mutex_lock(&mxl5007t_list_mutex); + + if (state) + hybrid_tuner_release_state(state); + + mutex_unlock(&mxl5007t_list_mutex); + + fe->tuner_priv = NULL; + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +static struct dvb_tuner_ops mxl5007t_tuner_ops = { + .info = { + .name = "MaxLinear MxL5007T", + }, + .init = mxl5007t_init, + .sleep = mxl5007t_sleep, + .set_params = mxl5007t_set_params, + .set_analog_params = mxl5007t_set_analog_params, + .get_status = mxl5007t_get_status, + .get_frequency = mxl5007t_get_frequency, + .get_bandwidth = mxl5007t_get_bandwidth, + .release = mxl5007t_release, +}; + +static int mxl5007t_get_chip_id(struct mxl5007t_state *state) +{ + char *name; + int ret; + u8 id; + + ret = mxl5007t_read_reg(state, 0xd3, &id); + if (mxl_fail(ret)) + goto fail; + + switch (id) { + case MxL_5007_V1_F1: + name = "MxL5007.v1.f1"; + break; + case MxL_5007_V1_F2: + name = "MxL5007.v1.f2"; + break; + case MxL_5007_V2_100_F1: + name = "MxL5007.v2.100.f1"; + break; + case MxL_5007_V2_100_F2: + name = "MxL5007.v2.100.f2"; + break; + case MxL_5007_V2_200_F1: + name = "MxL5007.v2.200.f1"; + break; + case MxL_5007_V2_200_F2: + name = "MxL5007.v2.200.f2"; + break; + default: + name = "MxL5007T"; + id = MxL_UNKNOWN_ID; + } + state->chip_id = id; + mxl_info("%s detected @ %d-%04x", name, + i2c_adapter_id(state->i2c_props.adap), + state->i2c_props.addr); + return 0; +fail: + mxl_warn("unable to identify device @ %d-%04x", + i2c_adapter_id(state->i2c_props.adap), + state->i2c_props.addr); + + state->chip_id = MxL_UNKNOWN_ID; + return ret; +} + +struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 addr, + struct mxl5007t_config *cfg) +{ + struct mxl5007t_state *state = NULL; + int instance, ret; + + mutex_lock(&mxl5007t_list_mutex); + instance = hybrid_tuner_request_state(struct mxl5007t_state, state, + hybrid_tuner_instance_list, + i2c, addr, "mxl5007"); + switch (instance) { + case 0: + goto fail; + break; + case 1: + /* new tuner instance */ + state->config = cfg; + + mutex_init(&state->lock); + + mutex_lock(&state->lock); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_get_chip_id(state); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + mutex_unlock(&state->lock); + + /* check return value of mxl5007t_get_chip_id */ + if (mxl_fail(ret)) + goto fail; + break; + default: + /* existing tuner instance */ + break; + } + fe->tuner_priv = state; + mutex_unlock(&mxl5007t_list_mutex); + + memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops, + sizeof(struct dvb_tuner_ops)); + + return fe; +fail: + mutex_unlock(&mxl5007t_list_mutex); + + mxl5007t_release(fe); + return NULL; +} +EXPORT_SYMBOL_GPL(mxl5007t_attach); +MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); +MODULE_AUTHOR("Michael Krufky "); +MODULE_LICENSE("GPL"); +MODULE_VERSION("0.1"); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/common/tuners/mxl5007t.h new file mode 100644 index 000000000000..a1ee3628b7ff --- /dev/null +++ b/drivers/media/common/tuners/mxl5007t.h @@ -0,0 +1,105 @@ +/* + * mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner + * + * Copyright (C) 2008 Michael Krufky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MXL5007T_H__ +#define __MXL5007T_H__ + +#include "dvb_frontend.h" + +/* ------------------------------------------------------------------------- */ + +enum mxl5007t_if_freq { + MxL_IF_4_MHZ, /* 4000000 */ + MxL_IF_4_5_MHZ, /* 4500000 */ + MxL_IF_4_57_MHZ, /* 4570000 */ + MxL_IF_5_MHZ, /* 5000000 */ + MxL_IF_5_38_MHZ, /* 5380000 */ + MxL_IF_6_MHZ, /* 6000000 */ + MxL_IF_6_28_MHZ, /* 6280000 */ + MxL_IF_9_1915_MHZ, /* 9191500 */ + MxL_IF_35_25_MHZ, /* 35250000 */ + MxL_IF_36_15_MHZ, /* 36150000 */ + MxL_IF_44_MHZ, /* 44000000 */ +}; + +enum mxl5007t_xtal_freq { + MxL_XTAL_16_MHZ, /* 16000000 */ + MxL_XTAL_20_MHZ, /* 20000000 */ + MxL_XTAL_20_25_MHZ, /* 20250000 */ + MxL_XTAL_20_48_MHZ, /* 20480000 */ + MxL_XTAL_24_MHZ, /* 24000000 */ + MxL_XTAL_25_MHZ, /* 25000000 */ + MxL_XTAL_25_14_MHZ, /* 25140000 */ + MxL_XTAL_27_MHZ, /* 27000000 */ + MxL_XTAL_28_8_MHZ, /* 28800000 */ + MxL_XTAL_32_MHZ, /* 32000000 */ + MxL_XTAL_40_MHZ, /* 40000000 */ + MxL_XTAL_44_MHZ, /* 44000000 */ + MxL_XTAL_48_MHZ, /* 48000000 */ + MxL_XTAL_49_3811_MHZ, /* 49381100 */ +}; + +enum mxl5007t_clkout_amp { + MxL_CLKOUT_AMP_0_94V = 0, + MxL_CLKOUT_AMP_0_53V = 1, + MxL_CLKOUT_AMP_0_37V = 2, + MxL_CLKOUT_AMP_0_28V = 3, + MxL_CLKOUT_AMP_0_23V = 4, + MxL_CLKOUT_AMP_0_20V = 5, + MxL_CLKOUT_AMP_0_17V = 6, + MxL_CLKOUT_AMP_0_15V = 7, +}; + +struct mxl5007t_config { + s32 if_diff_out_level; + enum mxl5007t_clkout_amp clk_out_amp; + enum mxl5007t_xtal_freq xtal_freq_hz; + enum mxl5007t_if_freq if_freq_hz; + unsigned int invert_if:1; + unsigned int loop_thru_enable:1; + unsigned int clk_out_enable:1; +}; + +#define CONFIG_MEDIA_TUNER_MXL5007T +#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE)) +extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, u8 addr, + struct mxl5007t_config *cfg); +#else +static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, + struct i2c_adapter *i2c, + u8 addr, + struct mxl5007t_config *cfg) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif + +#endif /* __MXL5007T_H__ */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ + -- cgit v1.2.3 From 452a53a247d9181bb0ec07ce1def51769619e9d2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 12 Jul 2008 18:22:38 -0300 Subject: V4L/DVB (8529): mxl5007t: enable _init and _sleep power management functionality Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5007t.c | 42 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 80cfa9ba1dcf..f3b193ac6614 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -830,27 +830,53 @@ fail: static int mxl5007t_init(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; - //int ret; + int ret; + u8 d; mutex_lock(&state->lock); - /* do init */ -//fail: + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_write_reg(state, 0x05, d | 0x01); + mxl_fail(ret); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + mutex_unlock(&state->lock); - return 0;//ret; + return ret; } static int mxl5007t_sleep(struct dvb_frontend *fe) { struct mxl5007t_state *state = fe->tuner_priv; - //int ret; + int ret; + u8 d; mutex_lock(&state->lock); - /* do standby */ -//fail: + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = mxl5007t_read_reg(state, 0x05, &d); + if (mxl_fail(ret)) + goto fail; + + ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); + mxl_fail(ret); +fail: + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + mutex_unlock(&state->lock); - return 0;//ret; + return ret; } /* ------------------------------------------------------------------------- */ -- cgit v1.2.3 From 59d27521c0f50fadf3382e2b325a7e8a04d9a770 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 9 Jul 2008 00:23:08 -0300 Subject: V4L/DVB (8530): au0828: add support for new revision of HVR950Q Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.au0828 | 1 + drivers/media/video/au0828/Kconfig | 1 + drivers/media/video/au0828/au0828-cards.c | 12 ++++++++++++ drivers/media/video/au0828/au0828-cards.h | 1 + drivers/media/video/au0828/au0828-dvb.c | 15 +++++++++++++++ 5 files changed, 30 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828 index 86d1c8e7b18f..eedc399e8deb 100644 --- a/Documentation/video4linux/CARDLIST.au0828 +++ b/Documentation/video4linux/CARDLIST.au0828 @@ -2,3 +2,4 @@ 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] 2 -> Hauppauge HVR850 (au0828) [2040:7240] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] + 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig index 52b2491581a8..ed9a50f189fc 100644 --- a/drivers/media/video/au0828/Kconfig +++ b/drivers/media/video/au0828/Kconfig @@ -6,6 +6,7 @@ config VIDEO_AU0828 select VIDEO_TVEEPROM select DVB_AU8522 if !DVB_FE_CUSTOMIZE select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE + select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE ---help--- This is a video4linux driver for Auvitek's USB device. diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c index 898e12395e7c..443e59009762 100644 --- a/drivers/media/video/au0828/au0828-cards.c +++ b/drivers/media/video/au0828/au0828-cards.c @@ -32,6 +32,9 @@ struct au0828_board au0828_boards[] = { [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { .name = "Hauppauge HVR950Q", }, + [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = { + .name = "Hauppauge HVR950Q rev xxF8", + }, [AU0828_BOARD_DVICO_FUSIONHDTV7] = { .name = "DViCO FusionHDTV USB", }, @@ -49,6 +52,7 @@ int au0828_tuner_callback(void *priv, int command, int arg) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: case AU0828_BOARD_DVICO_FUSIONHDTV7: if (command == 0) { /* Tuner Reset Command from xc5000 */ @@ -110,6 +114,7 @@ void au0828_card_setup(struct au0828_dev *dev) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: if (dev->i2c_rc == 0) hauppauge_eeprom(dev, eeprom+0xa0); break; @@ -128,6 +133,7 @@ void au0828_gpio_setup(struct au0828_dev *dev) switch (dev->board) { case AU0828_BOARD_HAUPPAUGE_HVR850: case AU0828_BOARD_HAUPPAUGE_HVR950Q: + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: /* GPIO's * 4 - CS5340 * 5 - AU8522 Demodulator @@ -193,6 +199,12 @@ struct usb_device_id au0828_usb_id_table [] = { .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, { USB_DEVICE(0x0fd9, 0x0008), .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q }, + { USB_DEVICE(0x2040, 0x7201), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, + { USB_DEVICE(0x2040, 0x7211), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, + { USB_DEVICE(0x2040, 0x7281), + .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL }, { }, }; diff --git a/drivers/media/video/au0828/au0828-cards.h b/drivers/media/video/au0828/au0828-cards.h index e26f54a961d0..c37f5fd0fa80 100644 --- a/drivers/media/video/au0828/au0828-cards.h +++ b/drivers/media/video/au0828/au0828-cards.h @@ -23,3 +23,4 @@ #define AU0828_BOARD_HAUPPAUGE_HVR950Q 1 #define AU0828_BOARD_HAUPPAUGE_HVR850 2 #define AU0828_BOARD_DVICO_FUSIONHDTV7 3 +#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4 diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c index c6d470590380..584a83a94a2a 100644 --- a/drivers/media/video/au0828/au0828-dvb.c +++ b/drivers/media/video/au0828/au0828-dvb.c @@ -28,6 +28,7 @@ #include "au0828.h" #include "au8522.h" #include "xc5000.h" +#include "mxl5007t.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); @@ -45,6 +46,11 @@ static struct xc5000_config hauppauge_hvr950q_tunerconfig = { .tuner_callback = au0828_tuner_callback }; +static struct mxl5007t_config mxl5007t_hvr950q_config = { + .xtal_freq_hz = MxL_XTAL_24_MHZ, + .if_freq_hz = MxL_IF_6_MHZ, +}; + /*-------------------------------------------------------------------*/ static void urb_completion(struct urb *purb) { @@ -342,6 +348,15 @@ int au0828_dvb_register(struct au0828_dev *dev) &dev->i2c_adap, &hauppauge_hvr950q_tunerconfig, dev); break; + case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL: + dvb->frontend = dvb_attach(au8522_attach, + &hauppauge_hvr950q_config, + &dev->i2c_adap); + if (dvb->frontend != NULL) + dvb_attach(mxl5007t_attach, dvb->frontend, + &dev->i2c_adap, 0x60, + &mxl5007t_hvr950q_config); + break; default: printk(KERN_WARNING "The frontend of your DVB/ATSC card " "isn't supported yet\n"); -- cgit v1.2.3 From c39c1fd29373d204b11b71946d0f4c97e4974dd9 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 12:06:57 -0300 Subject: V4L/DVB (8531): mxl5007t: move i2c gate handling outside of mutex protected code blocks There is no reason to protect the i2c gate handling within the mxl5007t state mutex. Thanks to Steven Toth for pointing this out. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5007t.c | 45 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index f3b193ac6614..4a1ea5425850 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -660,11 +660,11 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) s32 rf_input_level; int ret; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); if (mxl_fail(ret)) goto fail; @@ -676,10 +676,11 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("rf input power: %d", rf_input_level); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -730,11 +731,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, return -EINVAL; } - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_tuner_init(state, mode); if (mxl_fail(ret)) goto fail; @@ -747,10 +748,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, state->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -802,11 +804,11 @@ static int mxl5007t_set_analog_params(struct dvb_frontend *fe, } mxl_debug("setting mxl5007 to system %s", mode_name); - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); if (mxl_fail(ret)) goto fail; @@ -818,10 +820,11 @@ static int mxl5007t_set_analog_params(struct dvb_frontend *fe, state->frequency = freq; state->bandwidth = 0; fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); return ret; } @@ -833,11 +836,11 @@ static int mxl5007t_init(struct dvb_frontend *fe) int ret; u8 d; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -845,11 +848,11 @@ static int mxl5007t_init(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d | 0x01); mxl_fail(ret); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - return ret; } @@ -859,11 +862,11 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) int ret; u8 d; - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -871,11 +874,11 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); mxl_fail(ret); fail: + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - return ret; } @@ -995,18 +998,18 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, mutex_init(&state->lock); - mutex_lock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + mutex_lock(&state->lock); + ret = mxl5007t_get_chip_id(state); + mutex_unlock(&state->lock); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - mutex_unlock(&state->lock); - /* check return value of mxl5007t_get_chip_id */ if (mxl_fail(ret)) goto fail; -- cgit v1.2.3 From 74b9ef21162fd81d9de87319c4373f523e2869cd Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Sat, 26 Jul 2008 15:43:17 -0300 Subject: V4L/DVB (8532): mxl5007t: remove excessive locks The use of mutex locking is overly paranoid in this driver. The only locks we need are around the manipulation of the register arrays. The other locks are not needed - remove them. Thanks to Steven Toth for pointing this out. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5007t.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 4a1ea5425850..cb25e43502fe 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c @@ -663,8 +663,6 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked); if (mxl_fail(ret)) goto fail; @@ -676,8 +674,6 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) goto fail; mxl_debug("rf input power: %d", rf_input_level); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -839,8 +835,6 @@ static int mxl5007t_init(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -848,8 +842,6 @@ static int mxl5007t_init(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d | 0x01); mxl_fail(ret); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -865,8 +857,6 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_read_reg(state, 0x05, &d); if (mxl_fail(ret)) goto fail; @@ -874,8 +864,6 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); mxl_fail(ret); fail: - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); @@ -1001,12 +989,8 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - mutex_lock(&state->lock); - ret = mxl5007t_get_chip_id(state); - mutex_unlock(&state->lock); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); -- cgit v1.2.3 From 445c2714cf72817ab1ad3ca894c6d9b2047b3a3e Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 27 Jul 2008 10:04:55 -0300 Subject: V4L/DVB (8534): remove select's of FW_LOADER After commit d9b19199e4894089456aaad295023263b5225c1a (always enable FW_LOADER unless EMBEDDED=y) we can remove the FW_LOADER select's and corresponding dependencies on HOTPLUG. Signed-off-by: Adrian Bunk Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/Kconfig | 9 ++------- drivers/media/dvb/bt8xx/Kconfig | 2 -- drivers/media/dvb/dvb-usb/Kconfig | 2 -- drivers/media/dvb/frontends/Kconfig | 24 ++++++++---------------- drivers/media/dvb/ttpci/Kconfig | 4 ---- drivers/media/dvb/ttusb-dec/Kconfig | 2 -- drivers/media/video/bt8xx/Kconfig | 2 -- drivers/media/video/cx18/Kconfig | 2 -- drivers/media/video/cx23885/Kconfig | 2 -- drivers/media/video/cx25840/Kconfig | 2 -- drivers/media/video/cx88/Kconfig | 3 +-- drivers/media/video/ivtv/Kconfig | 2 -- drivers/media/video/pvrusb2/Kconfig | 2 -- drivers/media/video/saa7134/Kconfig | 2 -- 14 files changed, 11 insertions(+), 49 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index 8d93ba857361..6f92beaa5ac8 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig @@ -21,9 +21,8 @@ config MEDIA_TUNER tristate default VIDEO_MEDIA && I2C depends on VIDEO_MEDIA && I2C - select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG + select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE + select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE @@ -138,8 +137,6 @@ config MEDIA_TUNER_QT1010 config MEDIA_TUNER_XC2028 tristate "XCeive xc2028/xc3028 tuners" depends on VIDEO_MEDIA && I2C - depends on HOTPLUG - select FW_LOADER default m if MEDIA_TUNER_CUSTOMIZE help Say Y here to include support for the xc2028/xc3028 tuners. @@ -147,8 +144,6 @@ config MEDIA_TUNER_XC2028 config MEDIA_TUNER_XC5000 tristate "Xceive XC5000 silicon tuner" depends on VIDEO_MEDIA && I2C - depends on HOTPLUG - select FW_LOADER default m if DVB_FE_CUSTOMISE help A driver for the silicon tuner XC5000 from Xceive. diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index 7588db1319d0..7e9c090fc04e 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig @@ -1,7 +1,6 @@ config DVB_BT8XX tristate "BT8xx based PCI cards" depends on DVB_CORE && PCI && I2C && VIDEO_BT848 - depends on HOTPLUG # due to FW_LOADER select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_SP887X if !DVB_FE_CUSTOMISE select DVB_NXT6000 if !DVB_FE_CUSTOMISE @@ -10,7 +9,6 @@ config DVB_BT8XX select DVB_LGDT330X if !DVB_FE_CUSTOMISE select DVB_ZL10353 if !DVB_FE_CUSTOMISE select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE - select FW_LOADER help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 3c663c65ef66..e84152b7576d 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -1,8 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" depends on DVB_CORE && USB && I2C && INPUT - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER help By enabling this you will be able to choose the various supported USB1.1 and USB2.0 DVB devices. diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index fa7f0c563770..574dffe91b68 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -97,9 +97,8 @@ comment "DVB-T (terrestrial) frontends" config DVB_SP8870 tristate "Spase sp8870 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -110,9 +109,8 @@ config DVB_SP8870 config DVB_SP887X tristate "Spase sp887x based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -158,9 +156,8 @@ config DVB_L64781 config DVB_TDA1004X tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -225,9 +222,8 @@ config DVB_DIB7000P config DVB_TDA10048 tristate "Philips TDA10048HN based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend. @@ -267,9 +263,8 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" config DVB_NXT200X tristate "NxtWave Communications NXT2002/NXT2004 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. @@ -282,9 +277,8 @@ config DVB_NXT200X config DVB_OR51211 tristate "Oren OR51211 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB tuner module. Say Y when you want to support this frontend. @@ -295,9 +289,8 @@ config DVB_OR51211 config DVB_OR51132 tristate "Oren OR51132 based" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. @@ -311,9 +304,8 @@ config DVB_OR51132 config DVB_BCM3510 tristate "Broadcom BCM3510" - depends on DVB_CORE && I2C && HOTPLUG + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE - select FW_LOADER help An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig index 87c973ac668b..41b5a988b619 100644 --- a/drivers/media/dvb/ttpci/Kconfig +++ b/drivers/media/dvb/ttpci/Kconfig @@ -5,8 +5,6 @@ config TTPCI_EEPROM config DVB_AV7110 tristate "AV7110 cards" depends on DVB_CORE && PCI && I2C - depends on HOTPLUG - select FW_LOADER if !DVB_AV7110_FIRMWARE select TTPCI_EEPROM select VIDEO_SAA7146_VV depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV @@ -127,14 +125,12 @@ config DVB_BUDGET_AV depends on DVB_BUDGET_CORE && I2C select VIDEO_SAA7146_VV depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - depends on HOTPLUG # dependency of FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_STV0299 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_TDA10021 if !DVB_FE_CUSTOMISE select DVB_TDA10023 if !DVB_FE_CUSTOMISE select DVB_TUA6100 if !DVB_FE_CUSTOMISE - select FW_LOADER help Support for simple SAA7146 based DVB cards (so called Budget- or Nova-PCI cards) without onboard diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig index a23cc0aa17d3..d5f48a3102bd 100644 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ b/drivers/media/dvb/ttusb-dec/Kconfig @@ -1,8 +1,6 @@ config DVB_TTUSB_DEC tristate "Technotrend/Hauppauge USB DEC devices" depends on DVB_CORE && USB && INPUT - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER select CRC32 help Support for external USB adapters designed by Technotrend and diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig index 24a34fc1f2b3..ce71e8e7b835 100644 --- a/drivers/media/video/bt8xx/Kconfig +++ b/drivers/media/video/bt8xx/Kconfig @@ -1,9 +1,7 @@ config VIDEO_BT848 tristate "BT848 Video For Linux" depends on VIDEO_DEV && PCI && I2C && VIDEO_V4L2 && INPUT - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEOBUF_DMA_SG select VIDEO_IR diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index 9aefdc5ea79a..ef48565de7f1 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig @@ -2,9 +2,7 @@ config VIDEO_CX18 tristate "Conexant cx23418 MPEG encoder support" depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL depends on INPUT # due to VIDEO_IR - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_IR select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 5cfb46bbdaa9..e60bd31b51a3 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig @@ -1,9 +1,7 @@ config VIDEO_CX23885 tristate "Conexant cx23885 (2388x successor) support" depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_BTCX select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/cx25840/Kconfig b/drivers/media/video/cx25840/Kconfig index 448f4cd0ce34..de515dadadc2 100644 --- a/drivers/media/video/cx25840/Kconfig +++ b/drivers/media/video/cx25840/Kconfig @@ -1,8 +1,6 @@ config VIDEO_CX25840 tristate "Conexant CX2584x audio/video decoders" depends on VIDEO_V4L2 && I2C && EXPERIMENTAL - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER ---help--- Support for the Conexant CX2584x audio/video decoders. diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 10e20d8196dc..9dd7bdf659b9 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -33,9 +33,8 @@ config VIDEO_CX88_ALSA config VIDEO_CX88_BLACKBIRD tristate "Blackbird MPEG encoder support (cx2388x + cx23416)" - depends on VIDEO_CX88 && HOTPLUG + depends on VIDEO_CX88 select VIDEO_CX2341X - select FW_LOADER ---help--- This adds support for MPEG encoder cards based on the Blackbird reference design, using the Conexant 2388x diff --git a/drivers/media/video/ivtv/Kconfig b/drivers/media/video/ivtv/Kconfig index 5d7ee8fcdd50..0069898bddab 100644 --- a/drivers/media/video/ivtv/Kconfig +++ b/drivers/media/video/ivtv/Kconfig @@ -2,9 +2,7 @@ config VIDEO_IVTV tristate "Conexant cx23416/cx23415 MPEG encoder/decoder support" depends on VIDEO_V4L1 && VIDEO_V4L2 && PCI && I2C && EXPERIMENTAL depends on INPUT # due to VIDEO_IR - depends on HOTPLUG # due to FW_LOADER select I2C_ALGOBIT - select FW_LOADER select VIDEO_IR select VIDEO_TUNER select VIDEO_TVEEPROM diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig index 4482b2c72ced..19eb274c9cd0 100644 --- a/drivers/media/video/pvrusb2/Kconfig +++ b/drivers/media/video/pvrusb2/Kconfig @@ -2,8 +2,6 @@ config VIDEO_PVRUSB2 tristate "Hauppauge WinTV-PVR USB2 support" depends on VIDEO_V4L2 && I2C depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M - depends on HOTPLUG # due to FW_LOADER - select FW_LOADER select VIDEO_TUNER select VIDEO_TVEEPROM select VIDEO_CX2341X diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 83f076abce35..7021bbf5897b 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig @@ -27,9 +27,7 @@ config VIDEO_SAA7134_ALSA config VIDEO_SAA7134_DVB tristate "DVB/ATSC Support for saa7134 based TV cards" depends on VIDEO_SAA7134 && DVB_CORE - depends on HOTPLUG # due to FW_LOADER select VIDEOBUF_DVB - select FW_LOADER select DVB_PLL if !DVB_FE_CUSTOMISE select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE -- cgit v1.2.3 From 59d07f1b705c466ea4eaca9c43d46be6d6a065a4 Mon Sep 17 00:00:00 2001 From: Aron Szabo Date: Sun, 27 Jul 2008 13:47:52 -0300 Subject: V4L/DVB (8538): em28xx-cards: Add GrabBeeX+ USB2800 model Added GrabBeeX+ USB2800 model (analog only) [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Aron Szabo Signed-off-by: Douglas Schilling Landgraf Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 19 +++++++++++++++++++ drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 21 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index ef0c3ddacae6..42be129609b7 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -19,3 +19,4 @@ 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 19 -> PointNix Intra-Oral Camera (em2860) 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] + 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 81f9ff55588d..9b29c8f4c18a 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -375,6 +375,21 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2800_BOARD_GRABBEEX_USB2800] = { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { .name = "Leadtek Winfast USB II", .is_em2800 = 1, @@ -541,6 +556,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, + { USB_DEVICE(0xeb1a, 0x2801), + .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -863,6 +880,8 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir) break; case (EM2800_BOARD_KWORLD_USB2800): break; + case (EM2800_BOARD_GRABBEEX_USB2800): + break; } } diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 9da877375cfb..84bc0b902ac8 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -59,6 +59,7 @@ #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 +#define EM2800_BOARD_GRABBEEX_USB2800 21 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 95b86a9a9020da22e7c25abc77aae4dc8f02ab55 Mon Sep 17 00:00:00 2001 From: Douglas Schilling Landgraf Date: Sun, 27 Jul 2008 14:03:32 -0300 Subject: V4L/DVB (8539): em28xx-cards: New supported IDs for analog models - New supported IDs for analog models (Based on Markus Rechberger version of em28xx driver) - Validation field for new em28xx boards. Signed-off-by: Douglas Schilling Landgraf [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 41 +- drivers/media/video/em28xx/em28xx-cards.c | 1220 +++++++++++++++++++++++++---- drivers/media/video/em28xx/em28xx.h | 45 +- 3 files changed, 1130 insertions(+), 176 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 42be129609b7..4126397a3ec8 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -1,11 +1,11 @@ 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] + 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 5 -> MSI VOX USB 2.0 (em2820/em2840) 6 -> Terratec Cinergy 200 USB (em2800) - 7 -> Leadtek Winfast USB II (em2800) + 7 -> Leadtek Winfast USB II (em2800) [0413:6023] 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] @@ -20,3 +20,40 @@ 19 -> PointNix Intra-Oral Camera (em2860) 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] + 22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751] + 23 -> Huaqi DLCW-130 (em2750) + 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] + 25 -> Gadmei UTV310 (em2820/em2840) + 26 -> Hercules Smart TV USB 2.0 (em2820/em2840) + 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840) + 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840) + 29 -> Pinnacle Dazzle DVC 100 (em2820/em2840) + 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) + 31 -> Usbgear VD204v9 (em2821) + 32 -> Supercomp USB 2.0 TV (em2821) + 33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821) + 34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f] + 35 -> Typhoon DVD Maker (em2860) + 36 -> NetGMBH Cam (em2860) + 37 -> Gadmei UTV330 (em2860) + 38 -> Yakumo MovieMixer (em2861) + 39 -> KWorld PVRTV 300U (em2861) [eb1a:e300] + 40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005] + 41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350] + 42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357] + 43 -> Terratec Cinergy T XS (em2870) [0ccd:0043] + 44 -> Terratec Cinergy T XS (MT2060) (em2870) + 45 -> Pinnacle PCTV DVB-T (em2870) + 46 -> Compro, VideoMate U3 (em2870) [185b:2870] + 47 -> KWorld DVB-T 305U (em2880) [eb1a:e305] + 48 -> KWorld DVB-T 310U (em2880) + 49 -> MSI DigiVox A/D (em2880) [eb1a:e310] + 50 -> MSI DigiVox A/D II (em2880) [eb1a:e320] + 51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c] + 52 -> DNT DA2 Hybrid (em2881) + 53 -> Pinnacle Hybrid Pro (em2881) + 54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323] + 55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e] + 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226] + 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] + 58 -> Hauppauge WinTV HVR 950 (em2883) diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 9b29c8f4c18a..e3e965defd5a 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -52,6 +52,15 @@ struct em28xx_hash_table { }; struct em28xx_board em28xx_boards[] = { + [EM2750_BOARD_UNKNOWN] = { + .name = "Unknown EM2750/EM2751 webcam grabber", + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, [EM2800_BOARD_UNKNOWN] = { .name = "Unknown EM2800 video grabber", .is_em2800 = 1, @@ -73,6 +82,39 @@ struct em28xx_board em28xx_boards[] = { .is_em2800 = 0, .tuner_type = TUNER_ABSENT, }, + [EM2750_BOARD_DLCW_130] = { + /* Beijing Huaqi Information Digital Technology Co., Ltd */ + .name = "Huaqi DLCW-130", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2800_BOARD_KWORLD_USB2800] = { + .name = "Kworld USB2800", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FCV1236D, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, [EM2820_BOARD_KWORLD_PVRTV2800RF] = { .name = "Kworld PVR TV 2800 RF", .is_em2800 = 0, @@ -151,13 +193,251 @@ struct em28xx_board em28xx_boards[] = { MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { - .name = "Hauppauge WinTV HVR 900", + [EM2820_BOARD_DLINK_USB_TV] = { + .name = "D-Link DUB-T210 TV Tuner", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { + .name = "Hercules Smart TV USB 2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { + .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_GADMEI_UTV310] = { + .name = "Gadmei UTV310", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { + .name = "Leadtek Winfast USB II Deluxe", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7114, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = 2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = 9, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_DVC_100] = { + .name = "Pinnacle Dazzle DVC 100", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { + .name = "Videology 20K14XUSB USB2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { + .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ + .tda9887_conf = TDA9887_PRESENT, /* unknown? */ + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2821_BOARD_SUPERCOMP_USB_2] = { + .name = "Supercomp USB 2.0 TV", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .is_em2800 = 0, + .tuner_type = TUNER_PHILIPS_FM1236_MK3, + .tda9887_conf = TDA9887_PRESENT | + TDA9887_PORT1_ACTIVE | + TDA9887_PORT2_ACTIVE, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 1, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2821_BOARD_USBGEAR_VD204] = { + .name = "Usbgear VD204v9", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_NETGMBH_CAM] = { + /* Beijing Huaqi Information Digital Technology Co., Ltd */ + .name = "NetGMBH Cam", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = 0, + .amux = 0, + } }, + }, + [EM2860_BOARD_TYPHOON_DVD_MAKER] = { + .name = "Typhoon DVD Maker", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_GADMEI_UTV330] = { + .name = "Gadmei UTV330", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2860_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Cinergy A Hybrid XS", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_dvb = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -173,12 +453,11 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { - .name = "Hauppauge WinTV HVR 900 (R2)", + [EM2861_BOARD_KWORLD_PVRTV_300U] = { + .name = "KWorld PVRTV 300U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, - .mts_firmware = 1, .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, @@ -194,16 +473,12 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { - .name = "Hauppauge WinTV HVR 950", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, - .input = { { + [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { + .name = "Yakumo MovieMixer", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 1, + .decoder = EM28XX_TVP5150, + .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, .amux = 0, @@ -217,19 +492,17 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { - .name = "Pinnacle PCTV HD Pro Stick", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2861_BOARD_PLEXTOR_PX_TV100U] = { + .name = "Plextor ConvertX PX-TV100U", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_TNF_5335MF, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, - .amux = 0, + .amux = 1, }, { .type = EM28XX_VMUX_COMPOSITE1, .vmux = TVP5150_COMPOSITE1, @@ -240,15 +513,42 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2870_BOARD_TERRATEC_XS] = { + .name = "Terratec Cinergy T XS", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_XC2028, + }, + [EM2870_BOARD_TERRATEC_XS_MT2060] = { + .name = "Terratec Cinergy T XS (MT2060)", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2870_BOARD_KWORLD_350U] = { + .name = "Kworld 350 U DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_XC2028, + }, + [EM2870_BOARD_KWORLD_355U] = { + .name = "Kworld 355 U DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + }, + [EM2870_BOARD_PINNACLE_PCTV_DVB] = { + .name = "Pinnacle PCTV DVB-T", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2870_BOARD_COMPRO_VIDEOMATE] = { + .name = "Compro, VideoMate U3", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .tuner_type = TUNER_ABSENT, /* MT2060 */ + }, + [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { + .name = "Terratec Hybrid XS Secam", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .has_msp34xx = 1, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -263,15 +563,382 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { + .name = "Hauppauge WinTV HVR 900", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { + .name = "Hauppauge WinTV HVR 900 (R2)", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + .name = "Hauppauge WinTV HVR 950", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { + .name = "Pinnacle PCTV HD Pro Stick", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { + .name = "AMD ATI TV Wonder HD 600", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .mts_firmware = 1, + .has_12mhz_i2s = 1, + .has_dvb = 1, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Hybrid XS", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .has_dvb = 1, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + /* maybe there's a reason behind it why Terratec sells the Hybrid XS + as Prodigy XS with a different PID, let's keep it separated for now + maybe we'll need it lateron */ + [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { + .name = "Terratec Prodigy XS", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2820_BOARD_MSI_VOX_USB_2] = { + .name = "MSI VOX USB 2.0", + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT | + TDA9887_PORT1_ACTIVE | + TDA9887_PORT2_ACTIVE, + .max_range_640_480 = 1, + + .decoder = EM28XX_SAA7114, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE4, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_TERRATEC_CINERGY_200] = { + .name = "Terratec Cinergy 200 USB", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_GRABBEEX_USB2800] = { + .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", + .is_em2800 = 1, + .vchannels = 2, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { + .name = "Leadtek Winfast USB II", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_KWORLD_USB2800] = { + .name = "Kworld USB2800", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_PHILIPS_FCV1236D, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PINNACLE_DVC_90] = { + .name = "Pinnacle Dazzle DVC 90/DVC 100", + .vchannels = 3, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2800_BOARD_VGEAR_POCKETTV] = { + .name = "V-Gear PocketTV", + .is_em2800 = 1, + .vchannels = 3, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 1, + } }, + }, + [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { + .name = "Pixelview Prolink PlayTV USB 2.0", + .vchannels = 3, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_YMEC_TVF_5533MF, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = SAA7115_COMPOSITE2, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = SAA7115_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, + [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { + .name = "PointNix Intra-Oral Camera", + .has_snapshot_button = 1, + .vchannels = 1, + .tda9887_conf = TDA9887_PRESENT, + .tuner_type = TUNER_ABSENT, + .decoder = EM28XX_SAA7113, + .input = { { + .type = EM28XX_VMUX_SVIDEO, + .vmux = SAA7115_SVIDEO3, + .amux = 0, + } }, + }, + [EM2880_BOARD_MSI_DIGIVOX_AD] = { + .name = "MSI DigiVox A/D", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { + .type = EM28XX_VMUX_COMPOSITE1, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = 1, + } }, + }, + [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { + .name = "MSI DigiVox A/D II", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -286,13 +953,12 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_TERRATEC_HYBRID_XS] = { - .name = "Terratec Hybrid XS", + [EM2880_BOARD_KWORLD_DVB_305U] = { + .name = "KWorld DVB-T 305U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, - .has_dvb = 1, .input = { { .type = EM28XX_VMUX_TELEVISION, .vmux = TVP5150_COMPOSITE0, @@ -307,13 +973,10 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - /* maybe there's a reason behind it why Terratec sells the Hybrid XS - as Prodigy XS with a different PID, let's keep it separated for now - maybe we'll need it lateron */ - [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { - .name = "Terratec Prodigy XS", + [EM2880_BOARD_KWORLD_DVB_310U] = { + .name = "KWorld DVB-T 310U", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, .tuner_type = TUNER_XC2028, .decoder = EM28XX_TVP5150, .input = { { @@ -330,175 +993,145 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2820_BOARD_MSI_VOX_USB_2] = { - .name = "MSI VOX USB 2.0", - .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT | - TDA9887_PORT1_ACTIVE | - TDA9887_PORT2_ACTIVE, - .max_range_640_480 = 1, - - .decoder = EM28XX_SAA7114, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE4, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = 1, - } }, - }, - [EM2800_BOARD_TERRATEC_CINERGY_200] = { - .name = "Terratec Cinergy 200 USB", - .is_em2800 = 1, + [EM2881_BOARD_DNT_DA2_HYBRID] = { + .name = "DNT DA2 Hybrid", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_GRABBEEX_USB2800] = { - .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", - .is_em2800 = 1, - .vchannels = 2, - .decoder = EM28XX_SAA7113, + [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { + .name = "Pinnacle Hybrid Pro", + .valid = EM28XX_BOARD_NOT_VALIDATED, + .vchannels = 3, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { - .name = "Leadtek Winfast USB II", - .is_em2800 = 1, + [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { + .name = "Pinnacle Hybrid Pro (2)", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_KWORLD_USB2800] = { - .name = "Kworld USB2800", - .is_em2800 = 1, + [EM2882_BOARD_KWORLD_VS_DVBT] = { + .name = "Kworld VS-DVB-T 323UR", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_PHILIPS_FCV1236D, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2820_BOARD_PINNACLE_DVC_90] = { - .name = "Pinnacle Dazzle DVC 90/DVC 100", + [EM2882_BOARD_TERRATEC_HYBRID_XS] = { + .name = "Terratec Hybrid XS (em2882)", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_ABSENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, + }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2800_BOARD_VGEAR_POCKETTV] = { - .name = "V-Gear PocketTV", - .is_em2800 = 1, + [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + .name = "Hauppauge WinTV HVR 950", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tuner_type = TUNER_LG_PAL_NEW_TAPC, - .tda9887_conf = TDA9887_PRESENT, - .decoder = EM28XX_SAA7113, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, + .vmux = TVP5150_COMPOSITE0, .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, + .vmux = TVP5150_COMPOSITE1, .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, + .vmux = TVP5150_SVIDEO, .amux = 1, } }, }, - [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { - .name = "Pixelview Prolink PlayTV USB 2.0", + [EM2883_BOARD_KWORLD_HYBRID_A316] = { + .name = "Kworld PlusTV HD Hybrid 330", + .valid = EM28XX_BOARD_NOT_VALIDATED, .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_YMEC_TVF_5533MF, - .decoder = EM28XX_SAA7113, + .is_em2800 = 0, + .tuner_type = TUNER_XC2028, + .decoder = EM28XX_TVP5150, .input = { { .type = EM28XX_VMUX_TELEVISION, - .vmux = SAA7115_COMPOSITE2, - .amux = EM28XX_AMUX_LINE_IN, + .vmux = TVP5150_COMPOSITE0, + .amux = 0, }, { .type = EM28XX_VMUX_COMPOSITE1, - .vmux = SAA7115_COMPOSITE0, - .amux = EM28XX_AMUX_LINE_IN, + .vmux = TVP5150_COMPOSITE1, + .amux = 1, }, { .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = EM28XX_AMUX_LINE_IN, - } }, - }, - [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { - .name = "PointNix Intra-Oral Camera", - .has_snapshot_button = 1, - .vchannels = 1, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_ABSENT, - .decoder = EM28XX_SAA7113, - .input = { { - .type = EM28XX_VMUX_SVIDEO, - .vmux = SAA7115_SVIDEO3, - .amux = 0, + .vmux = TVP5150_SVIDEO, + .amux = 1, } }, }, }; @@ -507,7 +1140,9 @@ const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); /* table of devices that work with this driver */ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0xeb1a, 0x2750), - .driver_info = EM2820_BOARD_UNKNOWN }, + .driver_info = EM2750_BOARD_UNKNOWN }, + { USB_DEVICE(0xeb1a, 0x2751), + .driver_info = EM2750_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2820), @@ -524,20 +1159,46 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2820_BOARD_UNKNOWN }, { USB_DEVICE(0xeb1a, 0x2883), .driver_info = EM2820_BOARD_UNKNOWN }, + { USB_DEVICE(0xeb1a, 0xe300), + .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, + { USB_DEVICE(0xeb1a, 0xe305), + .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, + { USB_DEVICE(0xeb1a, 0xe310), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, + { USB_DEVICE(0xeb1a, 0xa316), + .driver_info = EM2883_BOARD_KWORLD_HYBRID_A316 }, + { USB_DEVICE(0xeb1a, 0xe320), + .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, + { USB_DEVICE(0xeb1a, 0xe323), + .driver_info = EM2882_BOARD_KWORLD_VS_DVBT }, + { USB_DEVICE(0xeb1a, 0xe350), + .driver_info = EM2870_BOARD_KWORLD_350U }, + { USB_DEVICE(0xeb1a, 0xe355), + .driver_info = EM2870_BOARD_KWORLD_355U }, + { USB_DEVICE(0xeb1a, 0x2801), + .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, + { USB_DEVICE(0xeb1a, 0xe357), + .driver_info = EM2870_BOARD_KWORLD_355U }, { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, - { USB_DEVICE(0x2304, 0x0208), - .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, + { USB_DEVICE(0x0ccd, 0x004c), + .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR }, + { USB_DEVICE(0x0ccd, 0x004f), + .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x005e), + .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0042), + .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0043), + .driver_info = EM2870_BOARD_TERRATEC_XS }, + { USB_DEVICE(0x0ccd, 0x0047), + .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, + { USB_DEVICE(0x185b, 0x2870), + .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, - { USB_DEVICE(0x2304, 0x0207), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, - { USB_DEVICE(0x2304, 0x021a), - .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, - { USB_DEVICE(0x2304, 0x0227), - .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, { USB_DEVICE(0x2040, 0x6500), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, { USB_DEVICE(0x2040, 0x6502), @@ -550,14 +1211,24 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, - { USB_DEVICE(0x0ccd, 0x0042), - .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, - { USB_DEVICE(0x0ccd, 0x0047), - .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, - { USB_DEVICE(0xeb1a, 0x2801), - .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, + { USB_DEVICE(0x2001, 0xf112), + .driver_info = EM2820_BOARD_DLINK_USB_TV }, + { USB_DEVICE(0x2304, 0x0207), + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0208), + .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, + { USB_DEVICE(0x2304, 0x021a), + .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, + { USB_DEVICE(0x2304, 0x0226), + .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO }, + { USB_DEVICE(0x2304, 0x0227), + .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, + { USB_DEVICE(0x0413, 0x6023), + .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, + { USB_DEVICE(0x093b, 0xa005), + .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -566,6 +1237,18 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table); * Reset sequences for analog/digital modes */ +/* Reset for the most [analog] boards */ +static struct em28xx_reg_seq default_analog[] = { + {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Reset for the most [digital] boards */ +static struct em28xx_reg_seq default_digital[] = { + {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + /* Board Hauppauge WinTV HVR 900 analog */ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, @@ -581,14 +1264,42 @@ static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { { -1, -1, -1, -1}, }; -/* Board Hauppauge WinTV HVR 900 tuner_callback */ -static struct em28xx_reg_seq hauppauge_wintv_hvr_900_tuner_callback[] = { +/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ +static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { + {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ +static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = { + {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10}, + { -1, -1, -1, -1}, +}; + +/* Board - EM2870 Kworld 355u + Analog - No input analog */ +static struct em28xx_reg_seq em2870_kworld_355u_digital[] = { + {EM2880_R04_GPO, 0x01, 0xff, 10}, + { -1, -1, -1, -1}, +}; + +/* Callback for the most boards */ +static struct em28xx_reg_seq default_callback[] = { {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, { -1, -1, -1, -1}, }; +/* Callback for EM2882 TERRATEC HYBRID XS */ +static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = { + {EM28XX_R08_GPIO, 0x2e, 0xff, 6}, + {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6}, + {EM2880_R04_GPO, 0x04, 0xff, 10}, + {EM2880_R04_GPO, 0x0c, 0xff, 10}, + { -1, -1, -1, -1}, +}; + /* * EEPROM hash table for devices with generic USB IDs */ @@ -635,6 +1346,7 @@ static void em28xx_set_model(struct em28xx *dev) dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; dev->has_dvb = em28xx_boards[dev->model].has_dvb; dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; + dev->valid = em28xx_boards[dev->model].valid; } /* Since em28xx_pre_card_setup() requires a proper dev->model, @@ -670,9 +1382,12 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_TERRATEC_PRODIGY_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: - case EM2880_BOARD_TERRATEC_HYBRID_XS: + case EM2860_BOARD_TERRATEC_HYBRID_XS: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: + case EM2882_BOARD_PINNACLE_HYBRID_PRO: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_KWORLD_HYBRID_A316: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); @@ -681,9 +1396,158 @@ void em28xx_pre_card_setup(struct em28xx *dev) /* Sets GPO/GPIO sequences for this device */ dev->analog_gpio = hauppauge_wintv_hvr_900_analog; dev->digital_gpio = hauppauge_wintv_hvr_900_digital; - dev->tun_analog_gpio = hauppauge_wintv_hvr_900_tuner_callback; - dev->tun_digital_gpio = hauppauge_wintv_hvr_900_tuner_callback; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + + case EM2882_BOARD_TERRATEC_HYBRID_XS: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* should be added ir_codes here */ + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = hauppauge_wintv_hvr_900_analog; + dev->digital_gpio = hauppauge_wintv_hvr_900_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital; + break; + + case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: + case EM2880_BOARD_TERRATEC_HYBRID_XS: + case EM2870_BOARD_TERRATEC_XS: + case EM2881_BOARD_PINNACLE_HYBRID_PRO: + case EM2880_BOARD_KWORLD_DVB_310U: + case EM2870_BOARD_KWORLD_350U: + case EM2881_BOARD_DNT_DA2_HYBRID: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital + and analog commands. If this commands doesn't work, + add this timer. */ + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = default_analog; + dev->digital_gpio = default_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + + case EM2880_BOARD_MSI_DIGIVOX_AD: + case EM2880_BOARD_MSI_DIGIVOX_AD_II: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* Sets GPO/GPIO sequences for this device */ + dev->analog_gpio = em2880_msi_digivox_ad_analog; + dev->digital_gpio = em2880_msi_digivox_ad_digital; + dev->tun_analog_gpio = default_callback; + dev->tun_digital_gpio = default_callback; + break; + case EM2750_BOARD_UNKNOWN: + case EM2750_BOARD_DLCW_130: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1); + break; + + case EM2861_BOARD_PLEXTOR_PX_TV100U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* FIXME guess */ + /* Turn on analog audio output */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); + break; + + case EM2861_BOARD_KWORLD_PVRTV_300U: + case EM2880_BOARD_KWORLD_DVB_305U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x6d", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\x7d", 1); + msleep(10); + break; + + case EM2870_BOARD_KWORLD_355U: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + msleep(50); + + /* Sets GPO/GPIO sequences for this device */ + dev->digital_gpio = em2870_kworld_355u_digital; + break; + + case EM2870_BOARD_COMPRO_VIDEOMATE: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* TODO: someone can do some cleanup here... + not everything's needed */ + em28xx_write_regs(dev, 0x04, "\x00", 1); + msleep(10); + em28xx_write_regs(dev, 0x04, "\x01", 1); + msleep(10); + em28xx_write_regs(dev, 0x08, "\xfd", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfc", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xdc", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfc", 1); + mdelay(70); + break; + + case EM2870_BOARD_TERRATEC_XS_MT2060: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* this device needs some gpio writes to get the DVB-T + demod work */ + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xde", 1); + mdelay(70); + dev->em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + break; + + case EM2870_BOARD_PINNACLE_PCTV_DVB: + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* this device needs some gpio writes to get the + DVB-T demod work */ + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xde", 1); + mdelay(70); + em28xx_write_regs(dev, 0x08, "\xfe", 1); + mdelay(70); + /* switch em2880 rc protocol */ + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1); + /* should be added ir_codes here */ + break; + + case EM2820_BOARD_GADMEI_UTV310: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* Turn on analog audio output */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); + break; + + case EM2860_BOARD_GADMEI_UTV330: + /* Turn on IR */ + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* should be added ir_codes here */ + break; + + case EM2820_BOARD_MSI_VOX_USB_2: + em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); + em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); + /* enables audio for that device */ + em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); break; } @@ -927,11 +1791,21 @@ void em28xx_card_setup(struct em28xx *dev) case EM2800_BOARD_UNKNOWN: if (!em28xx_hint_board(dev)) em28xx_set_model(dev); + break; } if (dev->has_snapshot_button) em28xx_register_snapshot_button(dev); + if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) { + em28xx_errdev("\n\n"); + em28xx_errdev("The support for this board weren't " + "valid yet.\n"); + em28xx_errdev("Please send a report of having this working\n"); + em28xx_errdev("not to V4L mailing list (and/or to other " + "addresses)\n\n"); + } + /* Allow override tuner type by a module parameter */ if (tuner >= 0) dev->tuner_type = tuner; diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 84bc0b902ac8..1b7364d664bf 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -60,11 +60,52 @@ #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 #define EM2800_BOARD_GRABBEEX_USB2800 21 +#define EM2750_BOARD_UNKNOWN 22 +#define EM2750_BOARD_DLCW_130 23 +#define EM2820_BOARD_DLINK_USB_TV 24 +#define EM2820_BOARD_GADMEI_UTV310 25 +#define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 +#define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 +#define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 +#define EM2820_BOARD_PINNACLE_DVC_100 29 +#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 +#define EM2821_BOARD_USBGEAR_VD204 31 +#define EM2821_BOARD_SUPERCOMP_USB_2 32 +#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33 +#define EM2860_BOARD_TERRATEC_HYBRID_XS 34 +#define EM2860_BOARD_TYPHOON_DVD_MAKER 35 +#define EM2860_BOARD_NETGMBH_CAM 36 +#define EM2860_BOARD_GADMEI_UTV330 37 +#define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38 +#define EM2861_BOARD_KWORLD_PVRTV_300U 39 +#define EM2861_BOARD_PLEXTOR_PX_TV100U 40 +#define EM2870_BOARD_KWORLD_350U 41 +#define EM2870_BOARD_KWORLD_355U 42 +#define EM2870_BOARD_TERRATEC_XS 43 +#define EM2870_BOARD_TERRATEC_XS_MT2060 44 +#define EM2870_BOARD_PINNACLE_PCTV_DVB 45 +#define EM2870_BOARD_COMPRO_VIDEOMATE 46 +#define EM2880_BOARD_KWORLD_DVB_305U 47 +#define EM2880_BOARD_KWORLD_DVB_310U 48 +#define EM2880_BOARD_MSI_DIGIVOX_AD 49 +#define EM2880_BOARD_MSI_DIGIVOX_AD_II 50 +#define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51 +#define EM2881_BOARD_DNT_DA2_HYBRID 52 +#define EM2881_BOARD_PINNACLE_HYBRID_PRO 53 +#define EM2882_BOARD_KWORLD_VS_DVBT 54 +#define EM2882_BOARD_TERRATEC_HYBRID_XS 55 +#define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 +#define EM2883_BOARD_KWORLD_HYBRID_A316 57 +#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 #define EM28XX_DEF_BUF 8 +/* Params for validated field */ +#define EM28XX_BOARD_NOT_VALIDATED 1 +#define EM28XX_BOARD_VALIDATED 0 + /* maximum number of em28xx boards */ #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ @@ -253,6 +294,7 @@ struct em28xx_board { unsigned int max_range_640_480:1; unsigned int has_dvb:1; unsigned int has_snapshot_button:1; + unsigned int valid:1; enum em28xx_decoder decoder; @@ -333,6 +375,7 @@ struct em28xx { unsigned int max_range_640_480:1; unsigned int has_dvb:1; unsigned int has_snapshot_button:1; + unsigned int valid:1; /* report for validated boards */ /* Some older em28xx chips needs a waiting time after writing */ unsigned int wait_after_write; @@ -362,7 +405,7 @@ struct em28xx { v4l2_std_id norm; /* selected tv norm */ int ctl_freq; /* selected frequency */ unsigned int ctl_input; /* selected input */ - unsigned int ctl_ainput; /* slected audio input */ + unsigned int ctl_ainput;/* selected audio input */ int mute; int volume; /* frame properties */ -- cgit v1.2.3 From d3603341e2f3c39f017f8df4b1cd734aeb0d453b Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Sun, 27 Jul 2008 14:10:11 -0300 Subject: V4L/DVB (8540): em28xx-cards: Add Compro VideoMate ForYou/Stereo model Added Compro VideoMate ForYou/Stereo model (analog only) Signed-off-by: Vitaly Wool [dougsland@gmail.com: Solved conflicts with v4l-dvb devel tree] Signed-off-by: Douglas Schilling Landgraf [mchehab@infradead.org: Need to fix some merge conflicts] Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 1 + drivers/media/video/em28xx/em28xx-cards.c | 18 ++++++++++++++++++ drivers/media/video/em28xx/em28xx.h | 1 + 3 files changed, 20 insertions(+) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 4126397a3ec8..57dfb2340181 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -57,3 +57,4 @@ 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226] 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] 58 -> Hauppauge WinTV HVR 950 (em2883) + 59 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index e3e965defd5a..766b0bed7e7f 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1134,6 +1134,22 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, + [EM2820_BOARD_COMPRO_VIDEO_MATE] = { + .name = "Compro VideoMate ForYou/Stereo", + .vchannels = 2, + .tuner_type = TUNER_LG_PAL_NEW_TAPC, + .tda9887_conf = TDA9887_PRESENT, + .decoder = EM28XX_TVP5150, + .input = { { + .type = EM28XX_VMUX_TELEVISION, + .vmux = TVP5150_COMPOSITE0, + .amux = EM28XX_AMUX_LINE_IN, + }, { + .type = EM28XX_VMUX_SVIDEO, + .vmux = TVP5150_SVIDEO, + .amux = EM28XX_AMUX_LINE_IN, + } }, + }, }; const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); @@ -1195,6 +1211,8 @@ struct usb_device_id em28xx_id_table [] = { .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS }, { USB_DEVICE(0x185b, 0x2870), .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, + { USB_DEVICE(0x185b, 0x2041), + .driver_info = EM2820_BOARD_COMPRO_VIDEO_MATE }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 1b7364d664bf..746a7acaf9d0 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -97,6 +97,7 @@ #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 +#define EM2820_BOARD_COMPRO_VIDEO_MATE 59 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From 10ac6603613d46a43a4544fbbe9581e50879bd45 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 14:58:58 -0300 Subject: V4L/DVB (8541): em28xx: HVR-950 entry is duplicated. Thanks to "Devin Heitmueller" for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- Documentation/video4linux/CARDLIST.em28xx | 5 ++--- drivers/media/video/em28xx/em28xx-cards.c | 37 +++++++------------------------ drivers/media/video/em28xx/em28xx-dvb.c | 2 +- drivers/media/video/em28xx/em28xx.h | 5 ++--- 4 files changed, 13 insertions(+), 36 deletions(-) (limited to 'drivers/media') diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 57dfb2340181..89c7f32abf9f 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -14,7 +14,7 @@ 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) - 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] + 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 19 -> PointNix Intra-Oral Camera (em2860) @@ -56,5 +56,4 @@ 55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e] 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226] 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] - 58 -> Hauppauge WinTV HVR 950 (em2883) - 59 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] + 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 766b0bed7e7f..2064f7203376 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -606,7 +606,7 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = { + [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { .name = "Hauppauge WinTV HVR 950", .vchannels = 3, .tda9887_conf = TDA9887_PRESENT, @@ -1093,26 +1093,6 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { - .name = "Hauppauge WinTV HVR 950", - .valid = EM28XX_BOARD_NOT_VALIDATED, - .vchannels = 3, - .tuner_type = TUNER_XC2028, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = 1, - } }, - }, [EM2883_BOARD_KWORLD_HYBRID_A316] = { .name = "Kworld PlusTV HD Hybrid 330", .valid = EM28XX_BOARD_NOT_VALIDATED, @@ -1222,13 +1202,13 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x2040, 0x6502), .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ - .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 }, + .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, { USB_DEVICE(0x0438, 0xb002), .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, { USB_DEVICE(0x2001, 0xf112), @@ -1401,10 +1381,9 @@ void em28xx_pre_card_setup(struct em28xx *dev) case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: case EM2860_BOARD_TERRATEC_HYBRID_XS: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2882_BOARD_PINNACLE_HYBRID_PRO: - case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2883_BOARD_KWORLD_HYBRID_A316: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); @@ -1595,7 +1574,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) /* djh - Not sure which demod we need here */ ctl->demod = XC3028_FE_DEFAULT; break; - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: /* FIXME: Better to specify the needed IF */ @@ -1778,7 +1757,7 @@ void em28xx_card_setup(struct em28xx *dev) case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: { struct tveeprom tv; #ifdef CONFIG_MODULES diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index 31475a245716..4b992bc0083c 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c @@ -410,7 +410,7 @@ static int dvb_init(struct em28xx *dev) em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); /* init frontend */ switch (dev->model) { - case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950: + case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: dvb->frontend = dvb_attach(lgdt330x_attach, diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 746a7acaf9d0..dc2019a844ec 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -54,7 +54,7 @@ #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 #define EM2800_BOARD_VGEAR_POCKETTV 15 -#define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 16 +#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 #define EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA 19 @@ -96,8 +96,7 @@ #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 -#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 58 -#define EM2820_BOARD_COMPRO_VIDEO_MATE 59 +#define EM2820_BOARD_COMPRO_VIDEO_MATE 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From fe43ef894c282dbfa963872eef577bab46a178fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 15:00:23 -0300 Subject: V4L/DVB (8542): em28xx: AMD ATI TV Wonder HD 600 entry at cards struct is duplicated Thanks to "Devin Heitmueller" for pointing this issue. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 2064f7203376..6b241cc6c413 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -675,29 +675,6 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { - .name = "AMD ATI TV Wonder HD 600", - .vchannels = 3, - .tda9887_conf = TDA9887_PRESENT, - .tuner_type = TUNER_XC2028, - .mts_firmware = 1, - .has_12mhz_i2s = 1, - .has_dvb = 1, - .decoder = EM28XX_TVP5150, - .input = { { - .type = EM28XX_VMUX_TELEVISION, - .vmux = TVP5150_COMPOSITE0, - .amux = 0, - }, { - .type = EM28XX_VMUX_COMPOSITE1, - .vmux = TVP5150_COMPOSITE1, - .amux = 1, - }, { - .type = EM28XX_VMUX_SVIDEO, - .vmux = TVP5150_SVIDEO, - .amux = 1, - } }, - }, [EM2880_BOARD_TERRATEC_HYBRID_XS] = { .name = "Terratec Hybrid XS", .vchannels = 3, -- cgit v1.2.3 From ee281b856d4e4921da24387ab116bb0855c2efaa Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 16:58:04 -0300 Subject: V4L/DVB (8543): em28xx: Rename #define for Compro VideoMate ForYou/Stereo There are two videomate boards supporded by em28xx. The names are almost identical. This patch renames one of such entries to something else. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/em28xx/em28xx-cards.c | 4 ++-- drivers/media/video/em28xx/em28xx.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 6b241cc6c413..476ae44a62d2 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -1091,7 +1091,7 @@ struct em28xx_board em28xx_boards[] = { .amux = 1, } }, }, - [EM2820_BOARD_COMPRO_VIDEO_MATE] = { + [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { .name = "Compro VideoMate ForYou/Stereo", .vchannels = 2, .tuner_type = TUNER_LG_PAL_NEW_TAPC, @@ -1169,7 +1169,7 @@ struct usb_device_id em28xx_id_table [] = { { USB_DEVICE(0x185b, 0x2870), .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, { USB_DEVICE(0x185b, 0x2041), - .driver_info = EM2820_BOARD_COMPRO_VIDEO_MATE }, + .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU }, { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, { USB_DEVICE(0x2040, 0x4201), diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index dc2019a844ec..9a3310748685 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h @@ -96,7 +96,7 @@ #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 #define EM2883_BOARD_KWORLD_HYBRID_A316 57 -#define EM2820_BOARD_COMPRO_VIDEO_MATE 58 +#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4 -- cgit v1.2.3 From ee56a4d3e39c2baafd06aaf26d975a7c9b05e3a2 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sun, 27 Jul 2008 14:01:59 -0300 Subject: V4L/DVB (8544): gspca: probe/open race. The device is flagged present after it is registered. During that window calls to open() that should work fail with -ENODEV. Reversing the order fixes the race. Signed-off-by: Oliver Neukum Acked-by: Hans de Goede Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/gspca.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index bc301bae0482..3a051c925ff6 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1758,6 +1758,7 @@ int gspca_dev_probe(struct usb_interface *intf, memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops); gspca_dev->vdev.fops = &gspca_dev->fops; gspca_dev->fops.owner = module; /* module protection */ + gspca_dev->present = 1; ret = video_register_device(&gspca_dev->vdev, VFL_TYPE_GRABBER, video_nr); @@ -1766,7 +1767,6 @@ int gspca_dev_probe(struct usb_interface *intf, goto out; } - gspca_dev->present = 1; usb_set_intfdata(intf, gspca_dev); PDEBUG(D_PROBE, "probe ok"); return 0; -- cgit v1.2.3 From 429e90893c9ad2c266d541c94d6ca69a34a7701d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 27 Jul 2008 14:08:54 -0300 Subject: V4L/DVB (8546): saa7146: fix read from uninitialized memory The offset field of the scatterlist entry *after* the last valid scatterlist entry was used instead of the first scatterlist entry (as was the intention of this code). This worked fine until the kzalloc of the sglist was replaced with kmalloc and sg_init_table only zeroed the exact needed length. Apparently kzalloc zeroes a bit more than is strictly necessary so the offset field was always 0 in the past. But now the offset field was suddenly random and this led to broken captures. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/saa7146_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index acaddc15dadc..e8bc7abf2409 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c @@ -656,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu /* if we have a user buffer, the first page may not be aligned to a page boundary. */ - pt1->offset = list->offset; + pt1->offset = dma->sglist->offset; pt2->offset = pt1->offset+o1; pt3->offset = pt1->offset+o2; -- cgit v1.2.3 From 38413fd2d82b0e75ae0492518f1b80a5cfd81956 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 19:02:30 -0300 Subject: V4L/DVB (8548): pwc: Fix compilation Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/pwc/pwc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/media') diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 835db149a3b1..74178754b39b 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From f3409f71a76838b1bc985f753eed787a3f17bc2c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 27 Jul 2008 19:30:46 -0300 Subject: V4L/DVB (8549): mxl5007: Fix an error at include file mxl5007 was forcing for its compilation: In file included from drivers/media/common/tuners/mxl5007t.c:25:drivers/media/common/tuners/mxl5007t.h:80:1: warning: "CONFIG_MEDIA_TUNER_MXL5007T" redefined In file included from :0: ./include/linux/autoconf.h:2782:1: warning: this is the location of the previous definition Probably, some temporary hack for testing. Cc: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mxl5007t.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/media') diff --git a/drivers/media/common/tuners/mxl5007t.h b/drivers/media/common/tuners/mxl5007t.h index a1ee3628b7ff..aa3eea0b5262 100644 --- a/drivers/media/common/tuners/mxl5007t.h +++ b/drivers/media/common/tuners/mxl5007t.h @@ -77,7 +77,6 @@ struct mxl5007t_config { unsigned int clk_out_enable:1; }; -#define CONFIG_MEDIA_TUNER_MXL5007T #if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE)) extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 addr, -- cgit v1.2.3