aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/media/common
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/Kconfig17
-rw-r--r--drivers/media/common/Makefile7
-rw-r--r--drivers/media/common/b2c2/Kconfig23
-rw-r--r--drivers/media/common/b2c2/Makefile8
-rw-r--r--drivers/media/common/b2c2/flexcop-common.h185
-rw-r--r--drivers/media/common/b2c2/flexcop-eeprom.c147
-rw-r--r--drivers/media/common/b2c2/flexcop-fe-tuner.c678
-rw-r--r--drivers/media/common/b2c2/flexcop-hw-filter.c232
-rw-r--r--drivers/media/common/b2c2/flexcop-i2c.c288
-rw-r--r--drivers/media/common/b2c2/flexcop-misc.c86
-rw-r--r--drivers/media/common/b2c2/flexcop-reg.h166
-rw-r--r--drivers/media/common/b2c2/flexcop-sram.c363
-rw-r--r--drivers/media/common/b2c2/flexcop.c325
-rw-r--r--drivers/media/common/b2c2/flexcop.h29
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_be.h455
-rw-r--r--drivers/media/common/b2c2/flexcop_ibi_value_le.h455
-rw-r--r--drivers/media/common/saa7146/Kconfig9
-rw-r--r--drivers/media/common/saa7146/Makefile5
-rw-r--r--drivers/media/common/saa7146/saa7146_core.c592
-rw-r--r--drivers/media/common/saa7146/saa7146_fops.c664
-rw-r--r--drivers/media/common/saa7146/saa7146_hlp.c1048
-rw-r--r--drivers/media/common/saa7146/saa7146_i2c.c423
-rw-r--r--drivers/media/common/saa7146/saa7146_vbi.c498
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c1332
-rw-r--r--drivers/media/common/siano/Kconfig19
-rw-r--r--drivers/media/common/siano/Makefile11
-rw-r--r--drivers/media/common/siano/sms-cards.c311
-rw-r--r--drivers/media/common/siano/sms-cards.h123
-rw-r--r--drivers/media/common/siano/smscoreapi.c1637
-rw-r--r--drivers/media/common/siano/smscoreapi.h775
-rw-r--r--drivers/media/common/siano/smsdvb.c1078
-rw-r--r--drivers/media/common/siano/smsendian.c103
-rw-r--r--drivers/media/common/siano/smsendian.h32
-rw-r--r--drivers/media/common/siano/smsir.c114
-rw-r--r--drivers/media/common/siano/smsir.h64
35 files changed, 14 insertions, 12288 deletions
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index d2a436ce77f..769c6f8142d 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -1,10 +1,9 @@
1# Used by common drivers, when they need to ask questions 1config VIDEO_SAA7146
2config MEDIA_COMMON_OPTIONS 2 tristate
3 bool 3 depends on I2C && PCI
4 4
5comment "common driver options" 5config VIDEO_SAA7146_VV
6 depends on MEDIA_COMMON_OPTIONS 6 tristate
7 7 depends on VIDEO_V4L2
8source "drivers/media/common/b2c2/Kconfig" 8 select VIDEOBUF_DMA_SG
9source "drivers/media/common/saa7146/Kconfig" 9 select VIDEO_SAA7146
10source "drivers/media/common/siano/Kconfig"
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index b8e2e3a33a3..e3ec9639321 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1 +1,6 @@
1obj-y += b2c2/ saa7146/ siano/ 1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3
4obj-y += tuners/
5obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
6obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/b2c2/Kconfig b/drivers/media/common/b2c2/Kconfig
deleted file mode 100644
index a8c6cdfaa2f..00000000000
--- a/drivers/media/common/b2c2/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
1config DVB_B2C2_FLEXCOP
2 tristate
3 depends on DVB_CORE && I2C
4 depends on DVB_B2C2_FLEXCOP_PCI || DVB_B2C2_FLEXCOP_USB
5 default y
6 select DVB_PLL if MEDIA_SUBDRV_AUTOSELECT
7 select DVB_STV0299 if MEDIA_SUBDRV_AUTOSELECT
8 select DVB_MT352 if MEDIA_SUBDRV_AUTOSELECT
9 select DVB_MT312 if MEDIA_SUBDRV_AUTOSELECT
10 select DVB_NXT200X if MEDIA_SUBDRV_AUTOSELECT
11 select DVB_STV0297 if MEDIA_SUBDRV_AUTOSELECT
12 select DVB_BCM3510 if MEDIA_SUBDRV_AUTOSELECT
13 select DVB_LGDT330X if MEDIA_SUBDRV_AUTOSELECT
14 select DVB_S5H1420 if MEDIA_SUBDRV_AUTOSELECT
15 select DVB_TUNER_ITD1000 if MEDIA_SUBDRV_AUTOSELECT
16 select DVB_ISL6421 if MEDIA_SUBDRV_AUTOSELECT
17 select DVB_CX24123 if MEDIA_SUBDRV_AUTOSELECT
18 select MEDIA_TUNER_SIMPLE if MEDIA_SUBDRV_AUTOSELECT
19 select DVB_TUNER_CX24113 if MEDIA_SUBDRV_AUTOSELECT
20
21# Selected via the PCI or USB flexcop drivers
22config DVB_B2C2_FLEXCOP_DEBUG
23 bool
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
deleted file mode 100644
index 24993a5b38b..00000000000
--- a/drivers/media/common/b2c2/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1b2c2-flexcop-objs += flexcop.o flexcop-fe-tuner.o flexcop-i2c.o
2b2c2-flexcop-objs += flexcop-sram.o flexcop-eeprom.o flexcop-misc.o
3b2c2-flexcop-objs += flexcop-hw-filter.o
4obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
5
6ccflags-y += -Idrivers/media/dvb-core/
7ccflags-y += -Idrivers/media/dvb-frontends/
8ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
deleted file mode 100644
index 437912e4982..00000000000
--- a/drivers/media/common/b2c2/flexcop-common.h
+++ /dev/null
@@ -1,185 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-common.h - common header file for device-specific source files
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_COMMON_H__
7#define __FLEXCOP_COMMON_H__
8
9#include <linux/interrupt.h>
10#include <linux/pci.h>
11#include <linux/mutex.h>
12
13#include "flexcop-reg.h"
14
15#include "dmxdev.h"
16#include "dvb_demux.h"
17#include "dvb_filter.h"
18#include "dvb_net.h"
19#include "dvb_frontend.h"
20
21#define FC_MAX_FEED 256
22
23#ifndef FC_LOG_PREFIX
24#warning please define a log prefix for your file, using a default one
25#define FC_LOG_PREFIX "b2c2-undef"
26#endif
27
28/* Steal from usb.h */
29#undef err
30#define err(format, arg...) \
31 printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
32#undef info
33#define info(format, arg...) \
34 printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
35#undef warn
36#define warn(format, arg...) \
37 printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
38
39struct flexcop_dma {
40 struct pci_dev *pdev;
41
42 u8 *cpu_addr0;
43 dma_addr_t dma_addr0;
44 u8 *cpu_addr1;
45 dma_addr_t dma_addr1;
46 u32 size; /* size of each address in bytes */
47};
48
49struct flexcop_i2c_adapter {
50 struct flexcop_device *fc;
51 struct i2c_adapter i2c_adap;
52
53 u8 no_base_addr;
54 flexcop_i2c_port_t port;
55};
56
57/* Control structure for data definitions that are common to
58 * the B2C2-based PCI and USB devices.
59 */
60struct flexcop_device {
61 /* general */
62 struct device *dev; /* for firmware_class */
63
64#define FC_STATE_DVB_INIT 0x01
65#define FC_STATE_I2C_INIT 0x02
66#define FC_STATE_FE_INIT 0x04
67 int init_state;
68
69 /* device information */
70 int has_32_hw_pid_filter;
71 flexcop_revision_t rev;
72 flexcop_device_type_t dev_type;
73 flexcop_bus_t bus_type;
74
75 /* dvb stuff */
76 struct dvb_adapter dvb_adapter;
77 struct dvb_frontend *fe;
78 struct dvb_net dvbnet;
79 struct dvb_demux demux;
80 struct dmxdev dmxdev;
81 struct dmx_frontend hw_frontend;
82 struct dmx_frontend mem_frontend;
83 int (*fe_sleep) (struct dvb_frontend *);
84
85 struct flexcop_i2c_adapter fc_i2c_adap[3];
86 struct mutex i2c_mutex;
87 struct module *owner;
88
89 /* options and status */
90 int extra_feedcount;
91 int feedcount;
92 int pid_filtering;
93 int fullts_streaming_state;
94
95 /* bus specific callbacks */
96 flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
97 flexcop_ibi_register);
98 int (*write_ibi_reg) (struct flexcop_device *,
99 flexcop_ibi_register, flexcop_ibi_value);
100 int (*i2c_request) (struct flexcop_i2c_adapter *,
101 flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
102 int (*stream_control) (struct flexcop_device *, int);
103 int (*get_mac_addr) (struct flexcop_device *fc, int extended);
104 void *bus_specific;
105};
106
107/* exported prototypes */
108
109/* from flexcop.c */
110void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
111void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
112
113struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
114void flexcop_device_kfree(struct flexcop_device *);
115
116int flexcop_device_initialize(struct flexcop_device *);
117void flexcop_device_exit(struct flexcop_device *fc);
118void flexcop_reset_block_300(struct flexcop_device *fc);
119
120/* from flexcop-dma.c */
121int flexcop_dma_allocate(struct pci_dev *pdev,
122 struct flexcop_dma *dma, u32 size);
123void flexcop_dma_free(struct flexcop_dma *dma);
124
125int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
126 flexcop_dma_index_t no, int onoff);
127int flexcop_dma_control_size_irq(struct flexcop_device *fc,
128 flexcop_dma_index_t no, int onoff);
129int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
130 flexcop_dma_index_t dma_idx);
131int flexcop_dma_xfer_control(struct flexcop_device *fc,
132 flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
133 int onoff);
134int flexcop_dma_config_timer(struct flexcop_device *fc,
135 flexcop_dma_index_t dma_idx, u8 cycles);
136
137/* from flexcop-eeprom.c */
138/* the PCI part uses this call to get the MAC address, the USB part has its own */
139int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended);
140
141/* from flexcop-i2c.c */
142/* the PCI part uses this a i2c_request callback, whereas the usb part has its own
143 * one. We have it in flexcop-i2c.c, because it is going via the actual
144 * I2C-channel of the flexcop.
145 */
146int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
147 u8 chipaddr, u8 addr, u8 *buf, u16 len);
148
149/* from flexcop-sram.c */
150int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
151 flexcop_sram_dest_target_t target);
152void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
153void flexcop_sram_ctrl(struct flexcop_device *fc,
154 int usb_wan, int sramdma, int maximumfill);
155
156/* global prototypes for the flexcop-chip */
157/* from flexcop-fe-tuner.c */
158int flexcop_frontend_init(struct flexcop_device *fc);
159void flexcop_frontend_exit(struct flexcop_device *fc);
160
161/* from flexcop-i2c.c */
162int flexcop_i2c_init(struct flexcop_device *fc);
163void flexcop_i2c_exit(struct flexcop_device *fc);
164
165/* from flexcop-sram.c */
166int flexcop_sram_init(struct flexcop_device *fc);
167
168/* from flexcop-misc.c */
169void flexcop_determine_revision(struct flexcop_device *fc);
170void flexcop_device_name(struct flexcop_device *fc,
171 const char *prefix, const char *suffix);
172void flexcop_dump_reg(struct flexcop_device *fc,
173 flexcop_ibi_register reg, int num);
174
175/* from flexcop-hw-filter.c */
176int flexcop_pid_feed_control(struct flexcop_device *fc,
177 struct dvb_demux_feed *dvbdmxfeed, int onoff);
178void flexcop_hw_filter_init(struct flexcop_device *fc);
179
180void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
181
182void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]);
183void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff);
184
185#endif
diff --git a/drivers/media/common/b2c2/flexcop-eeprom.c b/drivers/media/common/b2c2/flexcop-eeprom.c
deleted file mode 100644
index a25373a9bd8..00000000000
--- a/drivers/media/common/b2c2/flexcop-eeprom.c
+++ /dev/null
@@ -1,147 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8#if 0
9/*EEPROM (Skystar2 has one "24LC08B" chip on board) */
10static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
11{
12 return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
13}
14
15static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
16 u32 len, u8 *wbuf, u8 *rbuf, int retries)
17{
18int i;
19
20for (i = 0; i < retries; i++) {
21 if (eeprom_write(adapter, addr, wbuf, len) == len) {
22 if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
23 return 1;
24 }
25 }
26 return 0;
27}
28
29/* These functions could be used to unlock SkyStar2 cards. */
30
31static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
32{
33 u8 rbuf[20];
34 u8 wbuf[20];
35
36 if (len != 16)
37 return 0;
38
39 memcpy(wbuf, key, len);
40 wbuf[16] = 0;
41 wbuf[17] = 0;
42 wbuf[18] = 0;
43 wbuf[19] = calc_lrc(wbuf, 19);
44 return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
45}
46
47static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
48{
49 u8 buf[20];
50
51 if (len != 16)
52 return 0;
53
54 if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
55 return 0;
56
57 memcpy(key, buf, len);
58 return 1;
59}
60
61static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
62{
63 u8 tmp[8];
64
65 if (type != 0) {
66 tmp[0] = mac[0];
67 tmp[1] = mac[1];
68 tmp[2] = mac[2];
69 tmp[3] = mac[5];
70 tmp[4] = mac[6];
71 tmp[5] = mac[7];
72 } else {
73 tmp[0] = mac[0];
74 tmp[1] = mac[1];
75 tmp[2] = mac[2];
76 tmp[3] = mac[3];
77 tmp[4] = mac[4];
78 tmp[5] = mac[5];
79 }
80
81 tmp[6] = 0;
82 tmp[7] = calc_lrc(tmp, 7);
83
84 if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
85 return 1;
86 return 0;
87}
88
89static int flexcop_eeprom_read(struct flexcop_device *fc,
90 u16 addr, u8 *buf, u16 len)
91{
92 return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
93}
94
95#endif
96
97static u8 calc_lrc(u8 *buf, int len)
98{
99 int i;
100 u8 sum = 0;
101 for (i = 0; i < len; i++)
102 sum = sum ^ buf[i];
103 return sum;
104}
105
106static int flexcop_eeprom_request(struct flexcop_device *fc,
107 flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
108{
109 int i,ret = 0;
110 u8 chipaddr = 0x50 | ((addr >> 8) & 3);
111 for (i = 0; i < retries; i++) {
112 ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr,
113 addr & 0xff, buf, len);
114 if (ret == 0)
115 break;
116 }
117 return ret;
118}
119
120static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
121 u8 *buf, u16 len, int retries)
122{
123 int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
124 if (ret == 0)
125 if (calc_lrc(buf, len - 1) != buf[len - 1])
126 ret = -EINVAL;
127 return ret;
128}
129
130/* JJ's comment about extended == 1: it is not presently used anywhere but was
131 * added to the low-level functions for possible support of EUI64 */
132int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
133{
134 u8 buf[8];
135 int ret = 0;
136
137 if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
138 if (extended != 0) {
139 err("TODO: extended (EUI64) MAC addresses aren't "
140 "completely supported yet");
141 ret = -EINVAL;
142 } else
143 memcpy(fc->dvb_adapter.proposed_mac,buf,6);
144 }
145 return ret;
146}
147EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr);
diff --git a/drivers/media/common/b2c2/flexcop-fe-tuner.c b/drivers/media/common/b2c2/flexcop-fe-tuner.c
deleted file mode 100644
index 850a6c60675..00000000000
--- a/drivers/media/common/b2c2/flexcop-fe-tuner.c
+++ /dev/null
@@ -1,678 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-fe-tuner.c - methods for frontend attachment and DiSEqC controlling
4 * see flexcop.c for copyright information
5 */
6#include <media/tuner.h>
7#include "flexcop.h"
8#include "mt312.h"
9#include "stv0299.h"
10#include "s5h1420.h"
11#include "itd1000.h"
12#include "cx24113.h"
13#include "cx24123.h"
14#include "isl6421.h"
15#include "mt352.h"
16#include "bcm3510.h"
17#include "nxt200x.h"
18#include "dvb-pll.h"
19#include "lgdt330x.h"
20#include "tuner-simple.h"
21#include "stv0297.h"
22
23
24/* Can we use the specified front-end? Remember that if we are compiled
25 * into the kernel we can't call code that's in modules. */
26#define FE_SUPPORTED(fe) (defined(CONFIG_DVB_##fe) || \
27 (defined(CONFIG_DVB_##fe##_MODULE) && defined(MODULE)))
28
29/* lnb control */
30#if FE_SUPPORTED(MT312) || FE_SUPPORTED(STV0299)
31static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
32{
33 struct flexcop_device *fc = fe->dvb->priv;
34 flexcop_ibi_value v;
35 deb_tuner("polarity/voltage = %u\n", voltage);
36
37 v = fc->read_ibi_reg(fc, misc_204);
38 switch (voltage) {
39 case SEC_VOLTAGE_OFF:
40 v.misc_204.ACPI1_sig = 1;
41 break;
42 case SEC_VOLTAGE_13:
43 v.misc_204.ACPI1_sig = 0;
44 v.misc_204.LNB_L_H_sig = 0;
45 break;
46 case SEC_VOLTAGE_18:
47 v.misc_204.ACPI1_sig = 0;
48 v.misc_204.LNB_L_H_sig = 1;
49 break;
50 default:
51 err("unknown SEC_VOLTAGE value");
52 return -EINVAL;
53 }
54 return fc->write_ibi_reg(fc, misc_204, v);
55}
56#endif
57
58#if FE_SUPPORTED(S5H1420) || FE_SUPPORTED(STV0299) || FE_SUPPORTED(MT312)
59static int flexcop_sleep(struct dvb_frontend* fe)
60{
61 struct flexcop_device *fc = fe->dvb->priv;
62 if (fc->fe_sleep)
63 return fc->fe_sleep(fe);
64 return 0;
65}
66#endif
67
68/* SkyStar2 DVB-S rev 2.3 */
69#if FE_SUPPORTED(MT312) && FE_SUPPORTED(PLL)
70static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
71{
72/* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */
73 struct flexcop_device *fc = fe->dvb->priv;
74 flexcop_ibi_value v;
75 u16 ax;
76 v.raw = 0;
77 deb_tuner("tone = %u\n",tone);
78
79 switch (tone) {
80 case SEC_TONE_ON:
81 ax = 0x01ff;
82 break;
83 case SEC_TONE_OFF:
84 ax = 0;
85 break;
86 default:
87 err("unknown SEC_TONE value");
88 return -EINVAL;
89 }
90
91 v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */
92 v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax;
93 v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax;
94 return fc->write_ibi_reg(fc,lnb_switch_freq_200,v);
95}
96
97static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data)
98{
99 flexcop_set_tone(fe, SEC_TONE_ON);
100 udelay(data ? 500 : 1000);
101 flexcop_set_tone(fe, SEC_TONE_OFF);
102 udelay(data ? 1000 : 500);
103}
104
105static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data)
106{
107 int i, par = 1, d;
108 for (i = 7; i >= 0; i--) {
109 d = (data >> i) & 1;
110 par ^= d;
111 flexcop_diseqc_send_bit(fe, d);
112 }
113 flexcop_diseqc_send_bit(fe, par);
114}
115
116static int flexcop_send_diseqc_msg(struct dvb_frontend *fe,
117 int len, u8 *msg, unsigned long burst)
118{
119 int i;
120
121 flexcop_set_tone(fe, SEC_TONE_OFF);
122 mdelay(16);
123
124 for (i = 0; i < len; i++)
125 flexcop_diseqc_send_byte(fe,msg[i]);
126 mdelay(16);
127
128 if (burst != -1) {
129 if (burst)
130 flexcop_diseqc_send_byte(fe, 0xff);
131 else {
132 flexcop_set_tone(fe, SEC_TONE_ON);
133 mdelay(12);
134 udelay(500);
135 flexcop_set_tone(fe, SEC_TONE_OFF);
136 }
137 msleep(20);
138 }
139 return 0;
140}
141
142static int flexcop_diseqc_send_master_cmd(struct dvb_frontend *fe,
143 struct dvb_diseqc_master_cmd *cmd)
144{
145 return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0);
146}
147
148static int flexcop_diseqc_send_burst(struct dvb_frontend *fe,
149 fe_sec_mini_cmd_t minicmd)
150{
151 return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd);
152}
153
154static struct mt312_config skystar23_samsung_tbdu18132_config = {
155 .demod_address = 0x0e,
156};
157
158static int skystar2_rev23_attach(struct flexcop_device *fc,
159 struct i2c_adapter *i2c)
160{
161 struct dvb_frontend_ops *ops;
162
163 fc->fe = dvb_attach(mt312_attach, &skystar23_samsung_tbdu18132_config, i2c);
164 if (!fc->fe)
165 return 0;
166
167 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
168 DVB_PLL_SAMSUNG_TBDU18132))
169 return 0;
170
171 ops = &fc->fe->ops;
172 ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
173 ops->diseqc_send_burst = flexcop_diseqc_send_burst;
174 ops->set_tone = flexcop_set_tone;
175 ops->set_voltage = flexcop_set_voltage;
176 fc->fe_sleep = ops->sleep;
177 ops->sleep = flexcop_sleep;
178 return 1;
179}
180#else
181#define skystar2_rev23_attach NULL
182#endif
183
184/* SkyStar2 DVB-S rev 2.6 */
185#if FE_SUPPORTED(STV0299) && FE_SUPPORTED(PLL)
186static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend *fe,
187 u32 srate, u32 ratio)
188{
189 u8 aclk = 0;
190 u8 bclk = 0;
191
192 if (srate < 1500000) {
193 aclk = 0xb7; bclk = 0x47;
194 } else if (srate < 3000000) {
195 aclk = 0xb7; bclk = 0x4b;
196 } else if (srate < 7000000) {
197 aclk = 0xb7; bclk = 0x4f;
198 } else if (srate < 14000000) {
199 aclk = 0xb7; bclk = 0x53;
200 } else if (srate < 30000000) {
201 aclk = 0xb6; bclk = 0x53;
202 } else if (srate < 45000000) {
203 aclk = 0xb4; bclk = 0x51;
204 }
205
206 stv0299_writereg(fe, 0x13, aclk);
207 stv0299_writereg(fe, 0x14, bclk);
208 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
209 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
210 stv0299_writereg(fe, 0x21, ratio & 0xf0);
211 return 0;
212}
213
214static u8 samsung_tbmu24112_inittab[] = {
215 0x01, 0x15,
216 0x02, 0x30,
217 0x03, 0x00,
218 0x04, 0x7D,
219 0x05, 0x35,
220 0x06, 0x02,
221 0x07, 0x00,
222 0x08, 0xC3,
223 0x0C, 0x00,
224 0x0D, 0x81,
225 0x0E, 0x23,
226 0x0F, 0x12,
227 0x10, 0x7E,
228 0x11, 0x84,
229 0x12, 0xB9,
230 0x13, 0x88,
231 0x14, 0x89,
232 0x15, 0xC9,
233 0x16, 0x00,
234 0x17, 0x5C,
235 0x18, 0x00,
236 0x19, 0x00,
237 0x1A, 0x00,
238 0x1C, 0x00,
239 0x1D, 0x00,
240 0x1E, 0x00,
241 0x1F, 0x3A,
242 0x20, 0x2E,
243 0x21, 0x80,
244 0x22, 0xFF,
245 0x23, 0xC1,
246 0x28, 0x00,
247 0x29, 0x1E,
248 0x2A, 0x14,
249 0x2B, 0x0F,
250 0x2C, 0x09,
251 0x2D, 0x05,
252 0x31, 0x1F,
253 0x32, 0x19,
254 0x33, 0xFE,
255 0x34, 0x93,
256 0xff, 0xff,
257};
258
259static struct stv0299_config samsung_tbmu24112_config = {
260 .demod_address = 0x68,
261 .inittab = samsung_tbmu24112_inittab,
262 .mclk = 88000000UL,
263 .invert = 0,
264 .skip_reinit = 0,
265 .lock_output = STV0299_LOCKOUTPUT_LK,
266 .volt13_op0_op1 = STV0299_VOLT13_OP1,
267 .min_delay_ms = 100,
268 .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
269};
270
271static int skystar2_rev26_attach(struct flexcop_device *fc,
272 struct i2c_adapter *i2c)
273{
274 fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c);
275 if (!fc->fe)
276 return 0;
277
278 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61, i2c,
279 DVB_PLL_SAMSUNG_TBMU24112))
280 return 0;
281
282 fc->fe->ops.set_voltage = flexcop_set_voltage;
283 fc->fe_sleep = fc->fe->ops.sleep;
284 fc->fe->ops.sleep = flexcop_sleep;
285 return 1;
286
287}
288#else
289#define skystar2_rev26_attach NULL
290#endif
291
292/* SkyStar2 DVB-S rev 2.7 */
293#if FE_SUPPORTED(S5H1420) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_ITD1000)
294static struct s5h1420_config skystar2_rev2_7_s5h1420_config = {
295 .demod_address = 0x53,
296 .invert = 1,
297 .repeated_start_workaround = 1,
298 .serial_mpeg = 1,
299};
300
301static struct itd1000_config skystar2_rev2_7_itd1000_config = {
302 .i2c_address = 0x61,
303};
304
305static int skystar2_rev27_attach(struct flexcop_device *fc,
306 struct i2c_adapter *i2c)
307{
308 flexcop_ibi_value r108;
309 struct i2c_adapter *i2c_tuner;
310
311 /* enable no_base_addr - no repeated start when reading */
312 fc->fc_i2c_adap[0].no_base_addr = 1;
313 fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config,
314 i2c);
315 if (!fc->fe)
316 goto fail;
317
318 i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe);
319 if (!i2c_tuner)
320 goto fail;
321
322 fc->fe_sleep = fc->fe->ops.sleep;
323 fc->fe->ops.sleep = flexcop_sleep;
324
325 /* enable no_base_addr - no repeated start when reading */
326 fc->fc_i2c_adap[2].no_base_addr = 1;
327 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
328 0x08, 1, 1)) {
329 err("ISL6421 could NOT be attached");
330 goto fail_isl;
331 }
332 info("ISL6421 successfully attached");
333
334 /* the ITD1000 requires a lower i2c clock - is it a problem ? */
335 r108.raw = 0x00000506;
336 fc->write_ibi_reg(fc, tw_sm_c_108, r108);
337 if (!dvb_attach(itd1000_attach, fc->fe, i2c_tuner,
338 &skystar2_rev2_7_itd1000_config)) {
339 err("ITD1000 could NOT be attached");
340 /* Should i2c clock be restored? */
341 goto fail_isl;
342 }
343 info("ITD1000 successfully attached");
344
345 return 1;
346
347fail_isl:
348 fc->fc_i2c_adap[2].no_base_addr = 0;
349fail:
350 /* for the next devices we need it again */
351 fc->fc_i2c_adap[0].no_base_addr = 0;
352 return 0;
353}
354#else
355#define skystar2_rev27_attach NULL
356#endif
357
358/* SkyStar2 rev 2.8 */
359#if FE_SUPPORTED(CX24123) && FE_SUPPORTED(ISL6421) && FE_SUPPORTED(TUNER_CX24113)
360static struct cx24123_config skystar2_rev2_8_cx24123_config = {
361 .demod_address = 0x55,
362 .dont_use_pll = 1,
363 .agc_callback = cx24113_agc_callback,
364};
365
366static const struct cx24113_config skystar2_rev2_8_cx24113_config = {
367 .i2c_addr = 0x54,
368 .xtal_khz = 10111,
369};
370
371static int skystar2_rev28_attach(struct flexcop_device *fc,
372 struct i2c_adapter *i2c)
373{
374 struct i2c_adapter *i2c_tuner;
375
376 fc->fe = dvb_attach(cx24123_attach, &skystar2_rev2_8_cx24123_config,
377 i2c);
378 if (!fc->fe)
379 return 0;
380
381 i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe);
382 if (!i2c_tuner)
383 return 0;
384
385 if (!dvb_attach(cx24113_attach, fc->fe, &skystar2_rev2_8_cx24113_config,
386 i2c_tuner)) {
387 err("CX24113 could NOT be attached");
388 return 0;
389 }
390 info("CX24113 successfully attached");
391
392 fc->fc_i2c_adap[2].no_base_addr = 1;
393 if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
394 0x08, 0, 0)) {
395 err("ISL6421 could NOT be attached");
396 fc->fc_i2c_adap[2].no_base_addr = 0;
397 return 0;
398 }
399 info("ISL6421 successfully attached");
400 /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an
401 * IR-receiver (PIC16F818) - but the card has no input for that ??? */
402 return 1;
403}
404#else
405#define skystar2_rev28_attach NULL
406#endif
407
408/* AirStar DVB-T */
409#if FE_SUPPORTED(MT352) && FE_SUPPORTED(PLL)
410static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend *fe)
411{
412 static u8 mt352_clock_config[] = { 0x89, 0x18, 0x2d };
413 static u8 mt352_reset[] = { 0x50, 0x80 };
414 static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 };
415 static u8 mt352_agc_cfg[] = { 0x67, 0x28, 0xa1 };
416 static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
417
418 mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
419 udelay(2000);
420 mt352_write(fe, mt352_reset, sizeof(mt352_reset));
421 mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
422 mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
423 mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
424 return 0;
425}
426
427static struct mt352_config samsung_tdtc9251dh0_config = {
428 .demod_address = 0x0f,
429 .demod_init = samsung_tdtc9251dh0_demod_init,
430};
431
432static int airstar_dvbt_attach(struct flexcop_device *fc,
433 struct i2c_adapter *i2c)
434{
435 fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
436 if (!fc->fe)
437 return 0;
438
439 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
440 DVB_PLL_SAMSUNG_TDTC9251DH0);
441}
442#else
443#define airstar_dvbt_attach NULL
444#endif
445
446/* AirStar ATSC 1st generation */
447#if FE_SUPPORTED(BCM3510)
448static int flexcop_fe_request_firmware(struct dvb_frontend *fe,
449 const struct firmware **fw, char* name)
450{
451 struct flexcop_device *fc = fe->dvb->priv;
452 return request_firmware(fw, name, fc->dev);
453}
454
455static struct bcm3510_config air2pc_atsc_first_gen_config = {
456 .demod_address = 0x0f,
457 .request_firmware = flexcop_fe_request_firmware,
458};
459
460static int airstar_atsc1_attach(struct flexcop_device *fc,
461 struct i2c_adapter *i2c)
462{
463 fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c);
464 return fc->fe != NULL;
465}
466#else
467#define airstar_atsc1_attach NULL
468#endif
469
470/* AirStar ATSC 2nd generation */
471#if FE_SUPPORTED(NXT200X) && FE_SUPPORTED(PLL)
472static struct nxt200x_config samsung_tbmv_config = {
473 .demod_address = 0x0a,
474};
475
476static int airstar_atsc2_attach(struct flexcop_device *fc,
477 struct i2c_adapter *i2c)
478{
479 fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c);
480 if (!fc->fe)
481 return 0;
482
483 return !!dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL,
484 DVB_PLL_SAMSUNG_TBMV);
485}
486#else
487#define airstar_atsc2_attach NULL
488#endif
489
490/* AirStar ATSC 3rd generation */
491#if FE_SUPPORTED(LGDT330X)
492static struct lgdt330x_config air2pc_atsc_hd5000_config = {
493 .demod_address = 0x59,
494 .demod_chip = LGDT3303,
495 .serial_mpeg = 0x04,
496 .clock_polarity_flip = 1,
497};
498
499static int airstar_atsc3_attach(struct flexcop_device *fc,
500 struct i2c_adapter *i2c)
501{
502 fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c);
503 if (!fc->fe)
504 return 0;
505
506 return !!dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61,
507 TUNER_LG_TDVS_H06XF);
508}
509#else
510#define airstar_atsc3_attach NULL
511#endif
512
513/* CableStar2 DVB-C */
514#if FE_SUPPORTED(STV0297) && FE_SUPPORTED(PLL)
515static u8 alps_tdee4_stv0297_inittab[] = {
516 0x80, 0x01,
517 0x80, 0x00,
518 0x81, 0x01,
519 0x81, 0x00,
520 0x00, 0x48,
521 0x01, 0x58,
522 0x03, 0x00,
523 0x04, 0x00,
524 0x07, 0x00,
525 0x08, 0x00,
526 0x30, 0xff,
527 0x31, 0x9d,
528 0x32, 0xff,
529 0x33, 0x00,
530 0x34, 0x29,
531 0x35, 0x55,
532 0x36, 0x80,
533 0x37, 0x6e,
534 0x38, 0x9c,
535 0x40, 0x1a,
536 0x41, 0xfe,
537 0x42, 0x33,
538 0x43, 0x00,
539 0x44, 0xff,
540 0x45, 0x00,
541 0x46, 0x00,
542 0x49, 0x04,
543 0x4a, 0x51,
544 0x4b, 0xf8,
545 0x52, 0x30,
546 0x53, 0x06,
547 0x59, 0x06,
548 0x5a, 0x5e,
549 0x5b, 0x04,
550 0x61, 0x49,
551 0x62, 0x0a,
552 0x70, 0xff,
553 0x71, 0x04,
554 0x72, 0x00,
555 0x73, 0x00,
556 0x74, 0x0c,
557 0x80, 0x20,
558 0x81, 0x00,
559 0x82, 0x30,
560 0x83, 0x00,
561 0x84, 0x04,
562 0x85, 0x22,
563 0x86, 0x08,
564 0x87, 0x1b,
565 0x88, 0x00,
566 0x89, 0x00,
567 0x90, 0x00,
568 0x91, 0x04,
569 0xa0, 0x86,
570 0xa1, 0x00,
571 0xa2, 0x00,
572 0xb0, 0x91,
573 0xb1, 0x0b,
574 0xc0, 0x5b,
575 0xc1, 0x10,
576 0xc2, 0x12,
577 0xd0, 0x02,
578 0xd1, 0x00,
579 0xd2, 0x00,
580 0xd3, 0x00,
581 0xd4, 0x02,
582 0xd5, 0x00,
583 0xde, 0x00,
584 0xdf, 0x01,
585 0xff, 0xff,
586};
587
588static struct stv0297_config alps_tdee4_stv0297_config = {
589 .demod_address = 0x1c,
590 .inittab = alps_tdee4_stv0297_inittab,
591};
592
593static int cablestar2_attach(struct flexcop_device *fc,
594 struct i2c_adapter *i2c)
595{
596 fc->fc_i2c_adap[0].no_base_addr = 1;
597 fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c);
598 if (!fc->fe)
599 goto fail;
600
601 /* This tuner doesn't use the stv0297's I2C gate, but instead the
602 * tuner is connected to a different flexcop I2C adapter. */
603 if (fc->fe->ops.i2c_gate_ctrl)
604 fc->fe->ops.i2c_gate_ctrl(fc->fe, 0);
605 fc->fe->ops.i2c_gate_ctrl = NULL;
606
607 if (!dvb_attach(dvb_pll_attach, fc->fe, 0x61,
608 &fc->fc_i2c_adap[2].i2c_adap, DVB_PLL_TDEE4))
609 goto fail;
610
611 return 1;
612
613fail:
614 /* Reset for next frontend to try */
615 fc->fc_i2c_adap[0].no_base_addr = 0;
616 return 0;
617}
618#else
619#define cablestar2_attach NULL
620#endif
621
622static struct {
623 flexcop_device_type_t type;
624 int (*attach)(struct flexcop_device *, struct i2c_adapter *);
625} flexcop_frontends[] = {
626 { FC_SKY_REV27, skystar2_rev27_attach },
627 { FC_SKY_REV28, skystar2_rev28_attach },
628 { FC_SKY_REV26, skystar2_rev26_attach },
629 { FC_AIR_DVBT, airstar_dvbt_attach },
630 { FC_AIR_ATSC2, airstar_atsc2_attach },
631 { FC_AIR_ATSC3, airstar_atsc3_attach },
632 { FC_AIR_ATSC1, airstar_atsc1_attach },
633 { FC_CABLE, cablestar2_attach },
634 { FC_SKY_REV23, skystar2_rev23_attach },
635};
636
637/* try to figure out the frontend */
638int flexcop_frontend_init(struct flexcop_device *fc)
639{
640 int i;
641 for (i = 0; i < ARRAY_SIZE(flexcop_frontends); i++) {
642 if (!flexcop_frontends[i].attach)
643 continue;
644 /* type needs to be set before, because of some workarounds
645 * done based on the probed card type */
646 fc->dev_type = flexcop_frontends[i].type;
647 if (flexcop_frontends[i].attach(fc, &fc->fc_i2c_adap[0].i2c_adap))
648 goto fe_found;
649 /* Clean up partially attached frontend */
650 if (fc->fe) {
651 dvb_frontend_detach(fc->fe);
652 fc->fe = NULL;
653 }
654 }
655 fc->dev_type = FC_UNK;
656 err("no frontend driver found for this B2C2/FlexCop adapter");
657 return -ENODEV;
658
659fe_found:
660 info("found '%s' .", fc->fe->ops.info.name);
661 if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) {
662 err("frontend registration failed!");
663 dvb_frontend_detach(fc->fe);
664 fc->fe = NULL;
665 return -EINVAL;
666 }
667 fc->init_state |= FC_STATE_FE_INIT;
668 return 0;
669}
670
671void flexcop_frontend_exit(struct flexcop_device *fc)
672{
673 if (fc->init_state & FC_STATE_FE_INIT) {
674 dvb_unregister_frontend(fc->fe);
675 dvb_frontend_detach(fc->fe);
676 }
677 fc->init_state &= ~FC_STATE_FE_INIT;
678}
diff --git a/drivers/media/common/b2c2/flexcop-hw-filter.c b/drivers/media/common/b2c2/flexcop-hw-filter.c
deleted file mode 100644
index 77e45475f4c..00000000000
--- a/drivers/media/common/b2c2/flexcop-hw-filter.c
+++ /dev/null
@@ -1,232 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-hw-filter.c - pid and mac address filtering and control functions
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
9{
10 flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
11 deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
12}
13
14void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
15{
16 flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
17}
18
19static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
20{
21 flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
22}
23
24void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
25{
26 flexcop_ibi_value v418, v41c;
27 v41c = fc->read_ibi_reg(fc, mac_address_41c);
28
29 v418.mac_address_418.MAC1 = mac[0];
30 v418.mac_address_418.MAC2 = mac[1];
31 v418.mac_address_418.MAC3 = mac[2];
32 v418.mac_address_418.MAC6 = mac[3];
33 v41c.mac_address_41c.MAC7 = mac[4];
34 v41c.mac_address_41c.MAC8 = mac[5];
35
36 fc->write_ibi_reg(fc, mac_address_418, v418);
37 fc->write_ibi_reg(fc, mac_address_41c, v41c);
38}
39
40void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
41{
42 flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
43}
44
45static void flexcop_pid_group_filter(struct flexcop_device *fc,
46 u16 pid, u16 mask)
47{
48 /* index_reg_310.extra_index_reg need to 0 or 7 to work */
49 flexcop_ibi_value v30c;
50 v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
51 v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
52 fc->write_ibi_reg(fc, pid_filter_30c, v30c);
53}
54
55static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
56{
57 flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
58}
59
60/* this fancy define reduces the code size of the quite similar PID controlling of
61 * the first 6 PIDs
62 */
63
64#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
65 flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
66v208 = fc->read_ibi_reg(fc, ctrl_208); \
67vpid.vregname.field = onoff ? pid : 0x1fff; \
68vpid.vregname.trans_field = transval; \
69v208.ctrl_208.enablefield = onoff; \
70fc->write_ibi_reg(fc, vregname, vpid); \
71fc->write_ibi_reg(fc, ctrl_208, v208);
72
73static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
74 u16 pid, int onoff)
75{
76 pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
77 Stream1_trans, 0);
78}
79
80static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
81 u16 pid, int onoff)
82{
83 pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
84 Stream2_trans, 0);
85}
86
87static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
88 u16 pid, int onoff)
89{
90 pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
91}
92
93static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
94 u16 pid, int onoff)
95{
96 pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
97}
98
99static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
100 u16 pid, int onoff)
101{
102 pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
103}
104
105static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
106 u16 pid, int onoff)
107{
108 pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
109}
110
111static void flexcop_pid_control(struct flexcop_device *fc,
112 int index, u16 pid, int onoff)
113{
114 if (pid == 0x2000)
115 return;
116
117 deb_ts("setting pid: %5d %04x at index %d '%s'\n",
118 pid, pid, index, onoff ? "on" : "off");
119
120 /* We could use bit magic here to reduce source code size.
121 * I decided against it, but to use the real register names */
122 switch (index) {
123 case 0:
124 flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
125 break;
126 case 1:
127 flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
128 break;
129 case 2:
130 flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
131 break;
132 case 3:
133 flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
134 break;
135 case 4:
136 flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
137 break;
138 case 5:
139 flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
140 break;
141 default:
142 if (fc->has_32_hw_pid_filter && index < 38) {
143 flexcop_ibi_value vpid, vid;
144
145 /* set the index */
146 vid = fc->read_ibi_reg(fc, index_reg_310);
147 vid.index_reg_310.index_reg = index - 6;
148 fc->write_ibi_reg(fc, index_reg_310, vid);
149
150 vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
151 vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
152 vpid.pid_n_reg_314.PID_enable_bit = onoff;
153 fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
154 }
155 break;
156 }
157}
158
159static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
160{
161 if (fc->fullts_streaming_state != onoff) {
162 deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
163 flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
164 flexcop_pid_group_filter_ctrl(fc, onoff);
165 fc->fullts_streaming_state = onoff;
166 }
167 return 0;
168}
169
170int flexcop_pid_feed_control(struct flexcop_device *fc,
171 struct dvb_demux_feed *dvbdmxfeed, int onoff)
172{
173 int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
174
175 fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
176 if (dvbdmxfeed->index >= max_pid_filter)
177 fc->extra_feedcount += onoff ? 1 : -1;
178
179 /* toggle complete-TS-streaming when:
180 * - pid_filtering is not enabled and it is the first or last feed requested
181 * - pid_filtering is enabled,
182 * - but the number of requested feeds is exceeded
183 * - or the requested pid is 0x2000 */
184
185 if (!fc->pid_filtering && fc->feedcount == onoff)
186 flexcop_toggle_fullts_streaming(fc, onoff);
187
188 if (fc->pid_filtering) {
189 flexcop_pid_control \
190 (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
191
192 if (fc->extra_feedcount > 0)
193 flexcop_toggle_fullts_streaming(fc, 1);
194 else if (dvbdmxfeed->pid == 0x2000)
195 flexcop_toggle_fullts_streaming(fc, onoff);
196 else
197 flexcop_toggle_fullts_streaming(fc, 0);
198 }
199
200 /* if it was the first or last feed request change the stream-status */
201 if (fc->feedcount == onoff) {
202 flexcop_rcv_data_ctrl(fc, onoff);
203 if (fc->stream_control) /* device specific stream control */
204 fc->stream_control(fc, onoff);
205
206 /* feeding stopped -> reset the flexcop filter*/
207 if (onoff == 0) {
208 flexcop_reset_block_300(fc);
209 flexcop_hw_filter_init(fc);
210 }
211 }
212 return 0;
213}
214EXPORT_SYMBOL(flexcop_pid_feed_control);
215
216void flexcop_hw_filter_init(struct flexcop_device *fc)
217{
218 int i;
219 flexcop_ibi_value v;
220 for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
221 flexcop_pid_control(fc, i, 0x1fff, 0);
222
223 flexcop_pid_group_filter(fc, 0, 0x1fe0);
224 flexcop_pid_group_filter_ctrl(fc, 0);
225
226 v = fc->read_ibi_reg(fc, pid_filter_308);
227 v.pid_filter_308.EMM_filter_4 = 1;
228 v.pid_filter_308.EMM_filter_6 = 0;
229 fc->write_ibi_reg(fc, pid_filter_308, v);
230
231 flexcop_null_filter_ctrl(fc, 1);
232}
diff --git a/drivers/media/common/b2c2/flexcop-i2c.c b/drivers/media/common/b2c2/flexcop-i2c.c
deleted file mode 100644
index 965d5eb3375..00000000000
--- a/drivers/media/common/b2c2/flexcop-i2c.c
+++ /dev/null
@@ -1,288 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8#define FC_MAX_I2C_RETRIES 100000
9
10static int flexcop_i2c_operation(struct flexcop_device *fc,
11 flexcop_ibi_value *r100)
12{
13 int i;
14 flexcop_ibi_value r;
15
16 r100->tw_sm_c_100.working_start = 1;
17 deb_i2c("r100 before: %08x\n",r100->raw);
18
19 fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero);
20 fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */
21
22 for (i = 0; i < FC_MAX_I2C_RETRIES; i++) {
23 r = fc->read_ibi_reg(fc, tw_sm_c_100);
24
25 if (!r.tw_sm_c_100.no_base_addr_ack_error) {
26 if (r.tw_sm_c_100.st_done) {
27 *r100 = r;
28 deb_i2c("i2c success\n");
29 return 0;
30 }
31 } else {
32 deb_i2c("suffering from an i2c ack_error\n");
33 return -EREMOTEIO;
34 }
35 }
36 deb_i2c("tried %d times i2c operation, "
37 "never finished or too many ack errors.\n", i);
38 return -EREMOTEIO;
39}
40
41static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
42 flexcop_ibi_value r100, u8 *buf)
43{
44 flexcop_ibi_value r104;
45 int len = r100.tw_sm_c_100.total_bytes,
46 /* remember total_bytes is buflen-1 */
47 ret;
48
49 /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
50 * correctly:
51 *
52 * the ITD1000 is behind an i2c-gate which closes automatically
53 * after an i2c-transaction the STV0297 needs 2 consecutive reads
54 * one with no_base_addr = 0 and one with 1
55 *
56 * those two work-arounds are conflictin: we check for the card
57 * type, it is set when probing the ITD1000 */
58 if (i2c->fc->dev_type == FC_SKY_REV27)
59 r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
60
61 ret = flexcop_i2c_operation(i2c->fc, &r100);
62 if (ret != 0) {
63 deb_i2c("Retrying operation\n");
64 r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
65 ret = flexcop_i2c_operation(i2c->fc, &r100);
66 }
67 if (ret != 0) {
68 deb_i2c("read failed. %d\n", ret);
69 return ret;
70 }
71
72 buf[0] = r100.tw_sm_c_100.data1_reg;
73
74 if (len > 0) {
75 r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104);
76 deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
77
78 /* there is at least one more byte, otherwise we wouldn't be here */
79 buf[1] = r104.tw_sm_c_104.data2_reg;
80 if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
81 if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
82 }
83 return 0;
84}
85
86static int flexcop_i2c_write4(struct flexcop_device *fc,
87 flexcop_ibi_value r100, u8 *buf)
88{
89 flexcop_ibi_value r104;
90 int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
91 r104.raw = 0;
92
93 /* there is at least one byte, otherwise we wouldn't be here */
94 r100.tw_sm_c_100.data1_reg = buf[0];
95 r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
96 r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
97 r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
98
99 deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw);
100
101 /* write the additional i2c data before doing the actual i2c operation */
102 fc->write_ibi_reg(fc, tw_sm_c_104, r104);
103 return flexcop_i2c_operation(fc, &r100);
104}
105
106int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
107 flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
108{
109 int ret;
110
111#ifdef DUMP_I2C_MESSAGES
112 int i;
113#endif
114
115 u16 bytes_to_transfer;
116 flexcop_ibi_value r100;
117
118 deb_i2c("op = %d\n",op);
119 r100.raw = 0;
120 r100.tw_sm_c_100.chipaddr = chipaddr;
121 r100.tw_sm_c_100.twoWS_rw = op;
122 r100.tw_sm_c_100.twoWS_port_reg = i2c->port;
123
124#ifdef DUMP_I2C_MESSAGES
125 printk(KERN_DEBUG "%d ", i2c->port);
126 if (op == FC_READ)
127 printk("rd(");
128 else
129 printk("wr(");
130 printk("%02x): %02x ", chipaddr, addr);
131#endif
132
133 /* in that case addr is the only value ->
134 * we write it twice as baseaddr and val0
135 * BBTI is doing it like that for ISL6421 at least */
136 if (i2c->no_base_addr && len == 0 && op == FC_WRITE) {
137 buf = &addr;
138 len = 1;
139 }
140
141 while (len != 0) {
142 bytes_to_transfer = len > 4 ? 4 : len;
143
144 r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1;
145 r100.tw_sm_c_100.baseaddr = addr;
146
147 if (op == FC_READ)
148 ret = flexcop_i2c_read4(i2c, r100, buf);
149 else
150 ret = flexcop_i2c_write4(i2c->fc, r100, buf);
151
152#ifdef DUMP_I2C_MESSAGES
153 for (i = 0; i < bytes_to_transfer; i++)
154 printk("%02x ", buf[i]);
155#endif
156
157 if (ret < 0)
158 return ret;
159
160 buf += bytes_to_transfer;
161 addr += bytes_to_transfer;
162 len -= bytes_to_transfer;
163 }
164
165#ifdef DUMP_I2C_MESSAGES
166 printk("\n");
167#endif
168
169 return 0;
170}
171/* exported for PCI i2c */
172EXPORT_SYMBOL(flexcop_i2c_request);
173
174/* master xfer callback for demodulator */
175static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
176 struct i2c_msg msgs[], int num)
177{
178 struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
179 int i, ret = 0;
180
181 /* Some drivers use 1 byte or 0 byte reads as probes, which this
182 * driver doesn't support. These probes will always fail, so this
183 * hack makes them always succeed. If one knew how, it would of
184 * course be better to actually do the read. */
185 if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1)
186 return 1;
187
188 if (mutex_lock_interruptible(&i2c->fc->i2c_mutex))
189 return -ERESTARTSYS;
190
191 for (i = 0; i < num; i++) {
192 /* reading */
193 if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
194 ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
195 msgs[i].buf[0], msgs[i+1].buf,
196 msgs[i+1].len);
197 i++; /* skip the following message */
198 } else /* writing */
199 ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
200 msgs[i].buf[0], &msgs[i].buf[1],
201 msgs[i].len - 1);
202 if (ret < 0) {
203 deb_i2c("i2c master_xfer failed");
204 break;
205 }
206 }
207
208 mutex_unlock(&i2c->fc->i2c_mutex);
209
210 if (ret == 0)
211 ret = num;
212 return ret;
213}
214
215static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
216{
217 return I2C_FUNC_I2C;
218}
219
220static struct i2c_algorithm flexcop_algo = {
221 .master_xfer = flexcop_master_xfer,
222 .functionality = flexcop_i2c_func,
223};
224
225int flexcop_i2c_init(struct flexcop_device *fc)
226{
227 int ret;
228 mutex_init(&fc->i2c_mutex);
229
230 fc->fc_i2c_adap[0].fc = fc;
231 fc->fc_i2c_adap[1].fc = fc;
232 fc->fc_i2c_adap[2].fc = fc;
233 fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
234 fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
235 fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
236
237 strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
238 sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
239 strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
240 sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
241 strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
242 sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
243
244 i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
245 i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
246 i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]);
247
248 fc->fc_i2c_adap[0].i2c_adap.algo =
249 fc->fc_i2c_adap[1].i2c_adap.algo =
250 fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo;
251 fc->fc_i2c_adap[0].i2c_adap.algo_data =
252 fc->fc_i2c_adap[1].i2c_adap.algo_data =
253 fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL;
254 fc->fc_i2c_adap[0].i2c_adap.dev.parent =
255 fc->fc_i2c_adap[1].i2c_adap.dev.parent =
256 fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev;
257
258 ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap);
259 if (ret < 0)
260 return ret;
261
262 ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap);
263 if (ret < 0)
264 goto adap_1_failed;
265
266 ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap);
267 if (ret < 0)
268 goto adap_2_failed;
269
270 fc->init_state |= FC_STATE_I2C_INIT;
271 return 0;
272
273adap_2_failed:
274 i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
275adap_1_failed:
276 i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
277 return ret;
278}
279
280void flexcop_i2c_exit(struct flexcop_device *fc)
281{
282 if (fc->init_state & FC_STATE_I2C_INIT) {
283 i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap);
284 i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
285 i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
286 }
287 fc->init_state &= ~FC_STATE_I2C_INIT;
288}
diff --git a/drivers/media/common/b2c2/flexcop-misc.c b/drivers/media/common/b2c2/flexcop-misc.c
deleted file mode 100644
index f06f3a9070f..00000000000
--- a/drivers/media/common/b2c2/flexcop-misc.c
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-misc.c - miscellaneous functions
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8void flexcop_determine_revision(struct flexcop_device *fc)
9{
10 flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
11
12 switch (v.misc_204.Rev_N_sig_revision_hi) {
13 case 0x2:
14 deb_info("found a FlexCopII.\n");
15 fc->rev = FLEXCOP_II;
16 break;
17 case 0x3:
18 deb_info("found a FlexCopIIb.\n");
19 fc->rev = FLEXCOP_IIB;
20 break;
21 case 0x0:
22 deb_info("found a FlexCopIII.\n");
23 fc->rev = FLEXCOP_III;
24 break;
25 default:
26 err("unknown FlexCop Revision: %x. Please report this to "
27 "linux-dvb@linuxtv.org.",
28 v.misc_204.Rev_N_sig_revision_hi);
29 break;
30 }
31
32 if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
33 deb_info("this FlexCop has "
34 "the additional 32 hardware pid filter.\n");
35 else
36 deb_info("this FlexCop has "
37 "the 6 basic main hardware pid filter.\n");
38 /* bus parts have to decide if hw pid filtering is used or not. */
39}
40
41static const char *flexcop_revision_names[] = {
42 "Unknown chip",
43 "FlexCopII",
44 "FlexCopIIb",
45 "FlexCopIII",
46};
47
48static const char *flexcop_device_names[] = {
49 [FC_UNK] = "Unknown device",
50 [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C",
51 [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T",
52 [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation",
53 [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation",
54 [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
55 [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)",
56 [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6",
57 [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u",
58 [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8",
59};
60
61static const char *flexcop_bus_names[] = {
62 "USB",
63 "PCI",
64};
65
66void flexcop_device_name(struct flexcop_device *fc,
67 const char *prefix, const char *suffix)
68{
69 info("%s '%s' at the '%s' bus controlled by a '%s' %s",
70 prefix, flexcop_device_names[fc->dev_type],
71 flexcop_bus_names[fc->bus_type],
72 flexcop_revision_names[fc->rev], suffix);
73}
74
75void flexcop_dump_reg(struct flexcop_device *fc,
76 flexcop_ibi_register reg, int num)
77{
78 flexcop_ibi_value v;
79 int i;
80 for (i = 0; i < num; i++) {
81 v = fc->read_ibi_reg(fc, reg+4*i);
82 deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
83 }
84 deb_rdump("\n");
85}
86EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/common/b2c2/flexcop-reg.h b/drivers/media/common/b2c2/flexcop-reg.h
deleted file mode 100644
index dc4528dcbb9..00000000000
--- a/drivers/media/common/b2c2/flexcop-reg.h
+++ /dev/null
@@ -1,166 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_REG_H__
7#define __FLEXCOP_REG_H__
8
9typedef enum {
10 FLEXCOP_UNK = 0,
11 FLEXCOP_II,
12 FLEXCOP_IIB,
13 FLEXCOP_III,
14} flexcop_revision_t;
15
16typedef enum {
17 FC_UNK = 0,
18 FC_CABLE,
19 FC_AIR_DVBT,
20 FC_AIR_ATSC1,
21 FC_AIR_ATSC2,
22 FC_AIR_ATSC3,
23 FC_SKY_REV23,
24 FC_SKY_REV26,
25 FC_SKY_REV27,
26 FC_SKY_REV28,
27} flexcop_device_type_t;
28
29typedef enum {
30 FC_USB = 0,
31 FC_PCI,
32} flexcop_bus_t;
33
34/* FlexCop IBI Registers */
35#if defined(__LITTLE_ENDIAN)
36#include "flexcop_ibi_value_le.h"
37#else
38#if defined(__BIG_ENDIAN)
39#include "flexcop_ibi_value_be.h"
40#else
41#error no endian defined
42#endif
43#endif
44
45#define fc_data_Tag_ID_DVB 0x3e
46#define fc_data_Tag_ID_ATSC 0x3f
47#define fc_data_Tag_ID_IDSB 0x8b
48
49#define fc_key_code_default 0x1
50#define fc_key_code_even 0x2
51#define fc_key_code_odd 0x3
52
53extern flexcop_ibi_value ibi_zero;
54
55typedef enum {
56 FC_I2C_PORT_DEMOD = 1,
57 FC_I2C_PORT_EEPROM = 2,
58 FC_I2C_PORT_TUNER = 3,
59} flexcop_i2c_port_t;
60
61typedef enum {
62 FC_WRITE = 0,
63 FC_READ = 1,
64} flexcop_access_op_t;
65
66typedef enum {
67 FC_SRAM_DEST_NET = 1,
68 FC_SRAM_DEST_CAI = 2,
69 FC_SRAM_DEST_CAO = 4,
70 FC_SRAM_DEST_MEDIA = 8
71} flexcop_sram_dest_t;
72
73typedef enum {
74 FC_SRAM_DEST_TARGET_WAN_USB = 0,
75 FC_SRAM_DEST_TARGET_DMA1 = 1,
76 FC_SRAM_DEST_TARGET_DMA2 = 2,
77 FC_SRAM_DEST_TARGET_FC3_CA = 3
78} flexcop_sram_dest_target_t;
79
80typedef enum {
81 FC_SRAM_2_32KB = 0, /* 64KB */
82 FC_SRAM_1_32KB = 1, /* 32KB - default fow FCII */
83 FC_SRAM_1_128KB = 2, /* 128KB */
84 FC_SRAM_1_48KB = 3, /* 48KB - default for FCIII */
85} flexcop_sram_type_t;
86
87typedef enum {
88 FC_WAN_SPEED_4MBITS = 0,
89 FC_WAN_SPEED_8MBITS = 1,
90 FC_WAN_SPEED_12MBITS = 2,
91 FC_WAN_SPEED_16MBITS = 3,
92} flexcop_wan_speed_t;
93
94typedef enum {
95 FC_DMA_1 = 1,
96 FC_DMA_2 = 2,
97} flexcop_dma_index_t;
98
99typedef enum {
100 FC_DMA_SUBADDR_0 = 1,
101 FC_DMA_SUBADDR_1 = 2,
102} flexcop_dma_addr_index_t;
103
104/* names of the particular registers */
105typedef enum {
106 dma1_000 = 0x000,
107 dma1_004 = 0x004,
108 dma1_008 = 0x008,
109 dma1_00c = 0x00c,
110 dma2_010 = 0x010,
111 dma2_014 = 0x014,
112 dma2_018 = 0x018,
113 dma2_01c = 0x01c,
114
115 tw_sm_c_100 = 0x100,
116 tw_sm_c_104 = 0x104,
117 tw_sm_c_108 = 0x108,
118 tw_sm_c_10c = 0x10c,
119 tw_sm_c_110 = 0x110,
120
121 lnb_switch_freq_200 = 0x200,
122 misc_204 = 0x204,
123 ctrl_208 = 0x208,
124 irq_20c = 0x20c,
125 sw_reset_210 = 0x210,
126 misc_214 = 0x214,
127 mbox_v8_to_host_218 = 0x218,
128 mbox_host_to_v8_21c = 0x21c,
129
130 pid_filter_300 = 0x300,
131 pid_filter_304 = 0x304,
132 pid_filter_308 = 0x308,
133 pid_filter_30c = 0x30c,
134 index_reg_310 = 0x310,
135 pid_n_reg_314 = 0x314,
136 mac_low_reg_318 = 0x318,
137 mac_high_reg_31c = 0x31c,
138
139 data_tag_400 = 0x400,
140 card_id_408 = 0x408,
141 card_id_40c = 0x40c,
142 mac_address_418 = 0x418,
143 mac_address_41c = 0x41c,
144
145 ci_600 = 0x600,
146 pi_604 = 0x604,
147 pi_608 = 0x608,
148 dvb_reg_60c = 0x60c,
149
150 sram_ctrl_reg_700 = 0x700,
151 net_buf_reg_704 = 0x704,
152 cai_buf_reg_708 = 0x708,
153 cao_buf_reg_70c = 0x70c,
154 media_buf_reg_710 = 0x710,
155 sram_dest_reg_714 = 0x714,
156 net_buf_reg_718 = 0x718,
157 wan_ctrl_reg_71c = 0x71c,
158} flexcop_ibi_register;
159
160#define flexcop_set_ibi_value(reg,attr,val) { \
161 flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \
162 v.reg.attr = val; \
163 fc->write_ibi_reg(fc,reg,v); \
164}
165
166#endif
diff --git a/drivers/media/common/b2c2/flexcop-sram.c b/drivers/media/common/b2c2/flexcop-sram.c
deleted file mode 100644
index f2199e43e80..00000000000
--- a/drivers/media/common/b2c2/flexcop-sram.c
+++ /dev/null
@@ -1,363 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-sram.c - functions for controlling the SRAM
4 * see flexcop.c for copyright information
5 */
6#include "flexcop.h"
7
8static void flexcop_sram_set_chip(struct flexcop_device *fc,
9 flexcop_sram_type_t type)
10{
11 flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
12}
13
14int flexcop_sram_init(struct flexcop_device *fc)
15{
16 switch (fc->rev) {
17 case FLEXCOP_II:
18 case FLEXCOP_IIB:
19 flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
20 break;
21 case FLEXCOP_III:
22 flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
23 break;
24 default:
25 return -EINVAL;
26 }
27 return 0;
28}
29
30int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
31 flexcop_sram_dest_target_t target)
32{
33 flexcop_ibi_value v;
34 v = fc->read_ibi_reg(fc, sram_dest_reg_714);
35
36 if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
37 err("SRAM destination target to available on FlexCopII(b)\n");
38 return -EINVAL;
39 }
40 deb_sram("sram dest: %x target: %x\n", dest, target);
41
42 if (dest & FC_SRAM_DEST_NET)
43 v.sram_dest_reg_714.NET_Dest = target;
44 if (dest & FC_SRAM_DEST_CAI)
45 v.sram_dest_reg_714.CAI_Dest = target;
46 if (dest & FC_SRAM_DEST_CAO)
47 v.sram_dest_reg_714.CAO_Dest = target;
48 if (dest & FC_SRAM_DEST_MEDIA)
49 v.sram_dest_reg_714.MEDIA_Dest = target;
50
51 fc->write_ibi_reg(fc,sram_dest_reg_714,v);
52 udelay(1000); /* TODO delay really necessary */
53
54 return 0;
55}
56EXPORT_SYMBOL(flexcop_sram_set_dest);
57
58void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s)
59{
60 flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s);
61}
62EXPORT_SYMBOL(flexcop_wan_set_speed);
63
64void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill)
65{
66 flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
67 v.sram_dest_reg_714.ctrl_usb_wan = usb_wan;
68 v.sram_dest_reg_714.ctrl_sramdma = sramdma;
69 v.sram_dest_reg_714.ctrl_maximumfill = maximumfill;
70 fc->write_ibi_reg(fc,sram_dest_reg_714,v);
71}
72EXPORT_SYMBOL(flexcop_sram_ctrl);
73
74#if 0
75static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
76{
77 int i, retries;
78 u32 command;
79
80 for (i = 0; i < len; i++) {
81 command = bank | addr | 0x04000000 | (*buf << 0x10);
82
83 retries = 2;
84
85 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
86 mdelay(1);
87 retries--;
88 };
89
90 if (retries == 0)
91 printk("%s: SRAM timeout\n", __func__);
92
93 write_reg_dw(adapter, 0x700, command);
94
95 buf++;
96 addr++;
97 }
98}
99
100static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
101{
102 int i, retries;
103 u32 command, value;
104
105 for (i = 0; i < len; i++) {
106 command = bank | addr | 0x04008000;
107
108 retries = 10000;
109
110 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
111 mdelay(1);
112 retries--;
113 };
114
115 if (retries == 0)
116 printk("%s: SRAM timeout\n", __func__);
117
118 write_reg_dw(adapter, 0x700, command);
119
120 retries = 10000;
121
122 while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
123 mdelay(1);
124 retries--;
125 };
126
127 if (retries == 0)
128 printk("%s: SRAM timeout\n", __func__);
129
130 value = read_reg_dw(adapter, 0x700) >> 0x10;
131
132 *buf = (value & 0xff);
133
134 addr++;
135 buf++;
136 }
137}
138
139static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
140{
141 u32 bank;
142
143 bank = 0;
144
145 if (adapter->dw_sram_type == 0x20000) {
146 bank = (addr & 0x18000) << 0x0d;
147 }
148
149 if (adapter->dw_sram_type == 0x00000) {
150 if ((addr >> 0x0f) == 0)
151 bank = 0x20000000;
152 else
153 bank = 0x10000000;
154 }
155 flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
156}
157
158static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
159{
160 u32 bank;
161 bank = 0;
162
163 if (adapter->dw_sram_type == 0x20000) {
164 bank = (addr & 0x18000) << 0x0d;
165 }
166
167 if (adapter->dw_sram_type == 0x00000) {
168 if ((addr >> 0x0f) == 0)
169 bank = 0x20000000;
170 else
171 bank = 0x10000000;
172 }
173 flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
174}
175
176static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
177{
178 u32 length;
179 while (len != 0) {
180 length = len;
181 /* check if the address range belongs to the same
182 * 32K memory chip. If not, the data is read
183 * from one chip at a time */
184 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
185 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
186 }
187
188 sram_read_chunk(adapter, addr, buf, length);
189 addr = addr + length;
190 buf = buf + length;
191 len = len - length;
192 }
193}
194
195static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
196{
197 u32 length;
198 while (len != 0) {
199 length = len;
200
201 /* check if the address range belongs to the same
202 * 32K memory chip. If not, the data is
203 * written to one chip at a time */
204 if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
205 length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
206 }
207
208 sram_write_chunk(adapter, addr, buf, length);
209 addr = addr + length;
210 buf = buf + length;
211 len = len - length;
212 }
213}
214
215static void sram_set_size(struct adapter *adapter, u32 mask)
216{
217 write_reg_dw(adapter, 0x71c,
218 (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
219}
220
221static void sram_init(struct adapter *adapter)
222{
223 u32 tmp;
224 tmp = read_reg_dw(adapter, 0x71c);
225 write_reg_dw(adapter, 0x71c, 1);
226
227 if (read_reg_dw(adapter, 0x71c) != 0) {
228 write_reg_dw(adapter, 0x71c, tmp);
229 adapter->dw_sram_type = tmp & 0x30000;
230 ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
231 } else {
232 adapter->dw_sram_type = 0x10000;
233 ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
234 }
235}
236
237static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
238{
239 u8 tmp1, tmp2;
240 dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
241
242 sram_set_size(adapter, mask);
243 sram_init(adapter);
244
245 tmp2 = 0xa5;
246 tmp1 = 0x4f;
247
248 sram_write(adapter, addr, &tmp2, 1);
249 sram_write(adapter, addr + 4, &tmp1, 1);
250
251 tmp2 = 0;
252 mdelay(20);
253
254 sram_read(adapter, addr, &tmp2, 1);
255 sram_read(adapter, addr, &tmp2, 1);
256
257 dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2);
258
259 if (tmp2 != 0xa5)
260 return 0;
261
262 tmp2 = 0x5a;
263 tmp1 = 0xf4;
264
265 sram_write(adapter, addr, &tmp2, 1);
266 sram_write(adapter, addr + 4, &tmp1, 1);
267
268 tmp2 = 0;
269 mdelay(20);
270
271 sram_read(adapter, addr, &tmp2, 1);
272 sram_read(adapter, addr, &tmp2, 1);
273
274 dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2);
275
276 if (tmp2 != 0x5a)
277 return 0;
278 return 1;
279}
280
281static u32 sram_length(struct adapter *adapter)
282{
283 if (adapter->dw_sram_type == 0x10000)
284 return 32768; /* 32K */
285 if (adapter->dw_sram_type == 0x00000)
286 return 65536; /* 64K */
287 if (adapter->dw_sram_type == 0x20000)
288 return 131072; /* 128K */
289 return 32768; /* 32K */
290}
291
292/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
293 - for 128K there are 4x32K chips at bank 0,1,2,3.
294 - for 64K there are 2x32K chips at bank 1,2.
295 - for 32K there is one 32K chip at bank 0.
296
297 FlexCop works only with one bank at a time. The bank is selected
298 by bits 28-29 of the 0x700 register.
299
300 bank 0 covers addresses 0x00000-0x07fff
301 bank 1 covers addresses 0x08000-0x0ffff
302 bank 2 covers addresses 0x10000-0x17fff
303 bank 3 covers addresses 0x18000-0x1ffff */
304
305static int flexcop_sram_detect(struct flexcop_device *fc)
306{
307 flexcop_ibi_value r208, r71c_0, vr71c_1;
308 r208 = fc->read_ibi_reg(fc, ctrl_208);
309 fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
310
311 r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
312 write_reg_dw(adapter, 0x71c, 1);
313 tmp3 = read_reg_dw(adapter, 0x71c);
314 dprintk("%s: tmp3 = %x\n", __func__, tmp3);
315 write_reg_dw(adapter, 0x71c, tmp2);
316
317 // check for internal SRAM ???
318 tmp3--;
319 if (tmp3 != 0) {
320 sram_set_size(adapter, 0x10000);
321 sram_init(adapter);
322 write_reg_dw(adapter, 0x208, tmp);
323 dprintk("%s: sram size = 32K\n", __func__);
324 return 32;
325 }
326
327 if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
328 sram_set_size(adapter, 0x20000);
329 sram_init(adapter);
330 write_reg_dw(adapter, 0x208, tmp);
331 dprintk("%s: sram size = 128K\n", __func__);
332 return 128;
333 }
334
335 if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
336 sram_set_size(adapter, 0x00000);
337 sram_init(adapter);
338 write_reg_dw(adapter, 0x208, tmp);
339 dprintk("%s: sram size = 64K\n", __func__);
340 return 64;
341 }
342
343 if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
344 sram_set_size(adapter, 0x10000);
345 sram_init(adapter);
346 write_reg_dw(adapter, 0x208, tmp);
347 dprintk("%s: sram size = 32K\n", __func__);
348 return 32;
349 }
350
351 sram_set_size(adapter, 0x10000);
352 sram_init(adapter);
353 write_reg_dw(adapter, 0x208, tmp);
354 dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
355 return 0;
356}
357
358static void sll_detect_sram_size(struct adapter *adapter)
359{
360 sram_detect_for_flex2(adapter);
361}
362
363#endif
diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c
deleted file mode 100644
index 412c5daf2b4..00000000000
--- a/drivers/media/common/b2c2/flexcop.c
+++ /dev/null
@@ -1,325 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop.c - main module part
4 * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
5 * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
6 *
7 * Acknowledgements:
8 * John Jurrius from BBTI, Inc. for extensive support
9 * with code examples and data books
10 * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
11 *
12 * Contributions to the skystar2-driver have been done by
13 * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
14 * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
15 * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
16 * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
17 * filtering)
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU Lesser General Public License
21 * as published by the Free Software Foundation; either version 2.1
22 * of the License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU Lesser General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 */
33
34#include "flexcop.h"
35
36#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip"
37#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de"
38
39#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
40#define DEBSTATUS ""
41#else
42#define DEBSTATUS " (debugging is not enabled)"
43#endif
44
45int b2c2_flexcop_debug;
46EXPORT_SYMBOL_GPL(b2c2_flexcop_debug);
47module_param_named(debug, b2c2_flexcop_debug, int, 0644);
48MODULE_PARM_DESC(debug,
49 "set debug level (1=info,2=tuner,4=i2c,8=ts,"
50 "16=sram,32=reg (|-able))."
51 DEBSTATUS);
52#undef DEBSTATUS
53
54DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
55
56/* global zero for ibi values */
57flexcop_ibi_value ibi_zero;
58
59static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
60{
61 struct flexcop_device *fc = dvbdmxfeed->demux->priv;
62 return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
63}
64
65static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
66{
67 struct flexcop_device *fc = dvbdmxfeed->demux->priv;
68 return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
69}
70
71static int flexcop_dvb_init(struct flexcop_device *fc)
72{
73 int ret = dvb_register_adapter(&fc->dvb_adapter,
74 "FlexCop Digital TV device", fc->owner,
75 fc->dev, adapter_nr);
76 if (ret < 0) {
77 err("error registering DVB adapter");
78 return ret;
79 }
80 fc->dvb_adapter.priv = fc;
81
82 fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
83 | DMX_MEMORY_BASED_FILTERING);
84 fc->demux.priv = fc;
85 fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
86 fc->demux.start_feed = flexcop_dvb_start_feed;
87 fc->demux.stop_feed = flexcop_dvb_stop_feed;
88 fc->demux.write_to_decoder = NULL;
89
90 ret = dvb_dmx_init(&fc->demux);
91 if (ret < 0) {
92 err("dvb_dmx failed: error %d", ret);
93 goto err_dmx;
94 }
95
96 fc->hw_frontend.source = DMX_FRONTEND_0;
97
98 fc->dmxdev.filternum = fc->demux.feednum;
99 fc->dmxdev.demux = &fc->demux.dmx;
100 fc->dmxdev.capabilities = 0;
101 ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter);
102 if (ret < 0) {
103 err("dvb_dmxdev_init failed: error %d", ret);
104 goto err_dmx_dev;
105 }
106
107 ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend);
108 if (ret < 0) {
109 err("adding hw_frontend to dmx failed: error %d", ret);
110 goto err_dmx_add_hw_frontend;
111 }
112
113 fc->mem_frontend.source = DMX_MEMORY_FE;
114 ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend);
115 if (ret < 0) {
116 err("adding mem_frontend to dmx failed: error %d", ret);
117 goto err_dmx_add_mem_frontend;
118 }
119
120 ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend);
121 if (ret < 0) {
122 err("connect frontend failed: error %d", ret);
123 goto err_connect_frontend;
124 }
125
126 ret = dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx);
127 if (ret < 0) {
128 err("dvb_net_init failed: error %d", ret);
129 goto err_net;
130 }
131
132 fc->init_state |= FC_STATE_DVB_INIT;
133 return 0;
134
135err_net:
136 fc->demux.dmx.disconnect_frontend(&fc->demux.dmx);
137err_connect_frontend:
138 fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
139err_dmx_add_mem_frontend:
140 fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
141err_dmx_add_hw_frontend:
142 dvb_dmxdev_release(&fc->dmxdev);
143err_dmx_dev:
144 dvb_dmx_release(&fc->demux);
145err_dmx:
146 dvb_unregister_adapter(&fc->dvb_adapter);
147 return ret;
148}
149
150static void flexcop_dvb_exit(struct flexcop_device *fc)
151{
152 if (fc->init_state & FC_STATE_DVB_INIT) {
153 dvb_net_release(&fc->dvbnet);
154
155 fc->demux.dmx.close(&fc->demux.dmx);
156 fc->demux.dmx.remove_frontend(&fc->demux.dmx,
157 &fc->mem_frontend);
158 fc->demux.dmx.remove_frontend(&fc->demux.dmx,
159 &fc->hw_frontend);
160 dvb_dmxdev_release(&fc->dmxdev);
161 dvb_dmx_release(&fc->demux);
162 dvb_unregister_adapter(&fc->dvb_adapter);
163 deb_info("deinitialized dvb stuff\n");
164 }
165 fc->init_state &= ~FC_STATE_DVB_INIT;
166}
167
168/* these methods are necessary to achieve the long-term-goal of hiding the
169 * struct flexcop_device from the bus-parts */
170void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len)
171{
172 dvb_dmx_swfilter(&fc->demux, buf, len);
173}
174EXPORT_SYMBOL(flexcop_pass_dmx_data);
175
176void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no)
177{
178 dvb_dmx_swfilter_packets(&fc->demux, buf, no);
179}
180EXPORT_SYMBOL(flexcop_pass_dmx_packets);
181
182static void flexcop_reset(struct flexcop_device *fc)
183{
184 flexcop_ibi_value v210, v204;
185
186 /* reset the flexcop itself */
187 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
188
189 v210.raw = 0;
190 v210.sw_reset_210.reset_block_000 = 1;
191 v210.sw_reset_210.reset_block_100 = 1;
192 v210.sw_reset_210.reset_block_200 = 1;
193 v210.sw_reset_210.reset_block_300 = 1;
194 v210.sw_reset_210.reset_block_400 = 1;
195 v210.sw_reset_210.reset_block_500 = 1;
196 v210.sw_reset_210.reset_block_600 = 1;
197 v210.sw_reset_210.reset_block_700 = 1;
198 v210.sw_reset_210.Block_reset_enable = 0xb2;
199 v210.sw_reset_210.Special_controls = 0xc259;
200 fc->write_ibi_reg(fc,sw_reset_210,v210);
201 msleep(1);
202
203 /* reset the periphical devices */
204
205 v204 = fc->read_ibi_reg(fc,misc_204);
206 v204.misc_204.Per_reset_sig = 0;
207 fc->write_ibi_reg(fc,misc_204,v204);
208 msleep(1);
209 v204.misc_204.Per_reset_sig = 1;
210 fc->write_ibi_reg(fc,misc_204,v204);
211}
212
213void flexcop_reset_block_300(struct flexcop_device *fc)
214{
215 flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
216 v210 = fc->read_ibi_reg(fc, sw_reset_210);
217
218 deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
219 fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
220
221 v210.sw_reset_210.reset_block_300 = 1;
222 v210.sw_reset_210.Block_reset_enable = 0xb2;
223
224 fc->write_ibi_reg(fc,sw_reset_210,v210);
225 fc->write_ibi_reg(fc,ctrl_208,v208_save);
226}
227
228struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
229{
230 void *bus;
231 struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
232 GFP_KERNEL);
233 if (!fc) {
234 err("no memory");
235 return NULL;
236 }
237
238 bus = kzalloc(bus_specific_len, GFP_KERNEL);
239 if (!bus) {
240 err("no memory");
241 kfree(fc);
242 return NULL;
243 }
244
245 fc->bus_specific = bus;
246
247 return fc;
248}
249EXPORT_SYMBOL(flexcop_device_kmalloc);
250
251void flexcop_device_kfree(struct flexcop_device *fc)
252{
253 kfree(fc->bus_specific);
254 kfree(fc);
255}
256EXPORT_SYMBOL(flexcop_device_kfree);
257
258int flexcop_device_initialize(struct flexcop_device *fc)
259{
260 int ret;
261 ibi_zero.raw = 0;
262
263 flexcop_reset(fc);
264 flexcop_determine_revision(fc);
265 flexcop_sram_init(fc);
266 flexcop_hw_filter_init(fc);
267 flexcop_smc_ctrl(fc, 0);
268
269 ret = flexcop_dvb_init(fc);
270 if (ret)
271 goto error;
272
273 /* i2c has to be done before doing EEProm stuff -
274 * because the EEProm is accessed via i2c */
275 ret = flexcop_i2c_init(fc);
276 if (ret)
277 goto error;
278
279 /* do the MAC address reading after initializing the dvb_adapter */
280 if (fc->get_mac_addr(fc, 0) == 0) {
281 u8 *b = fc->dvb_adapter.proposed_mac;
282 info("MAC address = %pM", b);
283 flexcop_set_mac_filter(fc,b);
284 flexcop_mac_filter_ctrl(fc,1);
285 } else
286 warn("reading of MAC address failed.\n");
287
288 ret = flexcop_frontend_init(fc);
289 if (ret)
290 goto error;
291
292 flexcop_device_name(fc,"initialization of","complete");
293 return 0;
294
295error:
296 flexcop_device_exit(fc);
297 return ret;
298}
299EXPORT_SYMBOL(flexcop_device_initialize);
300
301void flexcop_device_exit(struct flexcop_device *fc)
302{
303 flexcop_frontend_exit(fc);
304 flexcop_i2c_exit(fc);
305 flexcop_dvb_exit(fc);
306}
307EXPORT_SYMBOL(flexcop_device_exit);
308
309static int flexcop_module_init(void)
310{
311 info(DRIVER_NAME " loaded successfully");
312 return 0;
313}
314
315static void flexcop_module_cleanup(void)
316{
317 info(DRIVER_NAME " unloaded successfully");
318}
319
320module_init(flexcop_module_init);
321module_exit(flexcop_module_cleanup);
322
323MODULE_AUTHOR(DRIVER_AUTHOR);
324MODULE_DESCRIPTION(DRIVER_NAME);
325MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/b2c2/flexcop.h b/drivers/media/common/b2c2/flexcop.h
deleted file mode 100644
index 897b10c85ad..00000000000
--- a/drivers/media/common/b2c2/flexcop.h
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop.h - private header file for all flexcop-chip-source files
4 * see flexcop.c for copyright information
5 */
6#ifndef __FLEXCOP_H__
7#define __FLEXCOP_H___
8
9#define FC_LOG_PREFIX "b2c2-flexcop"
10#include "flexcop-common.h"
11
12extern int b2c2_flexcop_debug;
13
14/* debug */
15#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
16#define dprintk(level,args...) \
17 do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0)
18#else
19#define dprintk(level,args...)
20#endif
21
22#define deb_info(args...) dprintk(0x01, args)
23#define deb_tuner(args...) dprintk(0x02, args)
24#define deb_i2c(args...) dprintk(0x04, args)
25#define deb_ts(args...) dprintk(0x08, args)
26#define deb_sram(args...) dprintk(0x10, args)
27#define deb_rdump(args...) dprintk(0x20, args)
28
29#endif
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_be.h b/drivers/media/common/b2c2/flexcop_ibi_value_be.h
deleted file mode 100644
index 8f64bdbd72b..00000000000
--- a/drivers/media/common/b2c2/flexcop_ibi_value_be.h
+++ /dev/null
@@ -1,455 +0,0 @@
1/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 * register descriptions
3 * see flexcop.c for copyright information
4 */
5/* This file is automatically generated, do not edit things here. */
6#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
7#define __FLEXCOP_IBI_VALUE_INCLUDED__
8
9typedef union {
10 u32 raw;
11
12 struct {
13 u32 dma_address0 :30;
14 u32 dma_0No_update : 1;
15 u32 dma_0start : 1;
16 } dma_0x0;
17
18 struct {
19 u32 dma_addr_size :24;
20 u32 DMA_maxpackets : 8;
21 } dma_0x4_remap;
22
23 struct {
24 u32 dma_addr_size :24;
25 u32 unused : 1;
26 u32 dma1timer : 7;
27 } dma_0x4_read;
28
29 struct {
30 u32 dma_addr_size :24;
31 u32 dmatimer : 7;
32 u32 unused : 1;
33 } dma_0x4_write;
34
35 struct {
36 u32 dma_cur_addr :30;
37 u32 unused : 2;
38 } dma_0x8;
39
40 struct {
41 u32 dma_address1 :30;
42 u32 remap_enable : 1;
43 u32 dma_1start : 1;
44 } dma_0xc;
45
46 struct {
47 u32 st_done : 1;
48 u32 no_base_addr_ack_error : 1;
49 u32 twoWS_port_reg : 2;
50 u32 total_bytes : 2;
51 u32 twoWS_rw : 1;
52 u32 working_start : 1;
53 u32 data1_reg : 8;
54 u32 baseaddr : 8;
55 u32 reserved1 : 1;
56 u32 chipaddr : 7;
57 } tw_sm_c_100;
58
59 struct {
60 u32 unused : 6;
61 u32 force_stop : 1;
62 u32 exlicit_stops : 1;
63 u32 data4_reg : 8;
64 u32 data3_reg : 8;
65 u32 data2_reg : 8;
66 } tw_sm_c_104;
67
68 struct {
69 u32 reserved2 :19;
70 u32 tlo1 : 5;
71 u32 reserved1 : 2;
72 u32 thi1 : 6;
73 } tw_sm_c_108;
74
75 struct {
76 u32 reserved2 :19;
77 u32 tlo1 : 5;
78 u32 reserved1 : 2;
79 u32 thi1 : 6;
80 } tw_sm_c_10c;
81
82 struct {
83 u32 reserved2 :19;
84 u32 tlo1 : 5;
85 u32 reserved1 : 2;
86 u32 thi1 : 6;
87 } tw_sm_c_110;
88
89 struct {
90 u32 LNB_CTLPrescaler_sig : 2;
91 u32 LNB_CTLLowCount_sig :15;
92 u32 LNB_CTLHighCount_sig :15;
93 } lnb_switch_freq_200;
94
95 struct {
96 u32 Rev_N_sig_reserved2 : 1;
97 u32 Rev_N_sig_caps : 1;
98 u32 Rev_N_sig_reserved1 : 2;
99 u32 Rev_N_sig_revision_hi : 4;
100 u32 reserved :20;
101 u32 Per_reset_sig : 1;
102 u32 LNB_L_H_sig : 1;
103 u32 ACPI3_sig : 1;
104 u32 ACPI1_sig : 1;
105 } misc_204;
106
107 struct {
108 u32 unused : 9;
109 u32 Mailbox_from_V8_Enable_sig : 1;
110 u32 DMA2_Size_IRQ_Enable_sig : 1;
111 u32 DMA1_Size_IRQ_Enable_sig : 1;
112 u32 DMA2_Timer_Enable_sig : 1;
113 u32 DMA2_IRQ_Enable_sig : 1;
114 u32 DMA1_Timer_Enable_sig : 1;
115 u32 DMA1_IRQ_Enable_sig : 1;
116 u32 Rcv_Data_sig : 1;
117 u32 MAC_filter_Mode_sig : 1;
118 u32 Multi2_Enable_sig : 1;
119 u32 Per_CA_Enable_sig : 1;
120 u32 SMC_Enable_sig : 1;
121 u32 CA_Enable_sig : 1;
122 u32 WAN_CA_Enable_sig : 1;
123 u32 WAN_Enable_sig : 1;
124 u32 Mask_filter_sig : 1;
125 u32 Null_filter_sig : 1;
126 u32 ECM_filter_sig : 1;
127 u32 EMM_filter_sig : 1;
128 u32 PMT_filter_sig : 1;
129 u32 PCR_filter_sig : 1;
130 u32 Stream2_filter_sig : 1;
131 u32 Stream1_filter_sig : 1;
132 } ctrl_208;
133
134 struct {
135 u32 reserved :21;
136 u32 Transport_Error : 1;
137 u32 LLC_SNAP_FLAG_set : 1;
138 u32 Continuity_error_flag : 1;
139 u32 Data_receiver_error : 1;
140 u32 Mailbox_from_V8_Status_sig : 1;
141 u32 DMA2_Size_IRQ_Status : 1;
142 u32 DMA1_Size_IRQ_Status : 1;
143 u32 DMA2_Timer_Status : 1;
144 u32 DMA2_IRQ_Status : 1;
145 u32 DMA1_Timer_Status : 1;
146 u32 DMA1_IRQ_Status : 1;
147 } irq_20c;
148
149 struct {
150 u32 Special_controls :16;
151 u32 Block_reset_enable : 8;
152 u32 reset_block_700 : 1;
153 u32 reset_block_600 : 1;
154 u32 reset_block_500 : 1;
155 u32 reset_block_400 : 1;
156 u32 reset_block_300 : 1;
157 u32 reset_block_200 : 1;
158 u32 reset_block_100 : 1;
159 u32 reset_block_000 : 1;
160 } sw_reset_210;
161
162 struct {
163 u32 unused2 :20;
164 u32 polarity_PS_ERR_sig : 1;
165 u32 polarity_PS_SYNC_sig : 1;
166 u32 polarity_PS_VALID_sig : 1;
167 u32 polarity_PS_CLK_sig : 1;
168 u32 unused1 : 3;
169 u32 s2p_sel_sig : 1;
170 u32 section_pkg_enable_sig : 1;
171 u32 halt_V8_sig : 1;
172 u32 v2WS_oe_sig : 1;
173 u32 vuart_oe_sig : 1;
174 } misc_214;
175
176 struct {
177 u32 Mailbox_from_V8 :32;
178 } mbox_v8_to_host_218;
179
180 struct {
181 u32 sysramaccess_busmuster : 1;
182 u32 sysramaccess_write : 1;
183 u32 unused : 7;
184 u32 sysramaccess_addr :15;
185 u32 sysramaccess_data : 8;
186 } mbox_host_to_v8_21c;
187
188 struct {
189 u32 debug_fifo_problem : 1;
190 u32 debug_flag_write_status00 : 1;
191 u32 Stream2_trans : 1;
192 u32 Stream2_PID :13;
193 u32 debug_flag_pid_saved : 1;
194 u32 MAC_Multicast_filter : 1;
195 u32 Stream1_trans : 1;
196 u32 Stream1_PID :13;
197 } pid_filter_300;
198
199 struct {
200 u32 reserved : 2;
201 u32 PMT_trans : 1;
202 u32 PMT_PID :13;
203 u32 debug_overrun2 : 1;
204 u32 debug_overrun3 : 1;
205 u32 PCR_trans : 1;
206 u32 PCR_PID :13;
207 } pid_filter_304;
208
209 struct {
210 u32 reserved : 2;
211 u32 ECM_trans : 1;
212 u32 ECM_PID :13;
213 u32 EMM_filter_6 : 1;
214 u32 EMM_filter_4 : 1;
215 u32 EMM_trans : 1;
216 u32 EMM_PID :13;
217 } pid_filter_308;
218
219 struct {
220 u32 unused2 : 3;
221 u32 Group_mask :13;
222 u32 unused1 : 2;
223 u32 Group_trans : 1;
224 u32 Group_PID :13;
225 } pid_filter_30c_ext_ind_0_7;
226
227 struct {
228 u32 unused :15;
229 u32 net_master_read :17;
230 } pid_filter_30c_ext_ind_1;
231
232 struct {
233 u32 unused :15;
234 u32 net_master_write :17;
235 } pid_filter_30c_ext_ind_2;
236
237 struct {
238 u32 unused :15;
239 u32 next_net_master_write :17;
240 } pid_filter_30c_ext_ind_3;
241
242 struct {
243 u32 reserved2 : 5;
244 u32 stack_read :10;
245 u32 reserved1 : 6;
246 u32 state_write :10;
247 u32 unused1 : 1;
248 } pid_filter_30c_ext_ind_4;
249
250 struct {
251 u32 unused :22;
252 u32 stack_cnt :10;
253 } pid_filter_30c_ext_ind_5;
254
255 struct {
256 u32 unused : 4;
257 u32 data_size_reg :12;
258 u32 write_status4 : 2;
259 u32 write_status1 : 2;
260 u32 pid_fsm_save_reg300 : 2;
261 u32 pid_fsm_save_reg4 : 2;
262 u32 pid_fsm_save_reg3 : 2;
263 u32 pid_fsm_save_reg2 : 2;
264 u32 pid_fsm_save_reg1 : 2;
265 u32 pid_fsm_save_reg0 : 2;
266 } pid_filter_30c_ext_ind_6;
267
268 struct {
269 u32 unused :22;
270 u32 pass_alltables : 1;
271 u32 AB_select : 1;
272 u32 extra_index_reg : 3;
273 u32 index_reg : 5;
274 } index_reg_310;
275
276 struct {
277 u32 reserved :17;
278 u32 PID_enable_bit : 1;
279 u32 PID_trans : 1;
280 u32 PID :13;
281 } pid_n_reg_314;
282
283 struct {
284 u32 reserved : 6;
285 u32 HighAB_bit : 1;
286 u32 Enable_bit : 1;
287 u32 A6_byte : 8;
288 u32 A5_byte : 8;
289 u32 A4_byte : 8;
290 } mac_low_reg_318;
291
292 struct {
293 u32 reserved : 8;
294 u32 A3_byte : 8;
295 u32 A2_byte : 8;
296 u32 A1_byte : 8;
297 } mac_high_reg_31c;
298
299 struct {
300 u32 data_Tag_ID :16;
301 u32 reserved :16;
302 } data_tag_400;
303
304 struct {
305 u32 Card_IDbyte3 : 8;
306 u32 Card_IDbyte4 : 8;
307 u32 Card_IDbyte5 : 8;
308 u32 Card_IDbyte6 : 8;
309 } card_id_408;
310
311 struct {
312 u32 Card_IDbyte1 : 8;
313 u32 Card_IDbyte2 : 8;
314 } card_id_40c;
315
316 struct {
317 u32 MAC6 : 8;
318 u32 MAC3 : 8;
319 u32 MAC2 : 8;
320 u32 MAC1 : 8;
321 } mac_address_418;
322
323 struct {
324 u32 reserved :16;
325 u32 MAC8 : 8;
326 u32 MAC7 : 8;
327 } mac_address_41c;
328
329 struct {
330 u32 reserved :21;
331 u32 txbuffempty : 1;
332 u32 ReceiveByteFrameError : 1;
333 u32 ReceiveDataReady : 1;
334 u32 transmitter_data_byte : 8;
335 } ci_600;
336
337 struct {
338 u32 pi_component_reg : 3;
339 u32 pi_rw : 1;
340 u32 pi_ha :20;
341 u32 pi_d : 8;
342 } pi_604;
343
344 struct {
345 u32 pi_busy_n : 1;
346 u32 pi_wait_n : 1;
347 u32 pi_timeout_status : 1;
348 u32 pi_CiMax_IRQ_n : 1;
349 u32 config_cclk : 1;
350 u32 config_cs_n : 1;
351 u32 config_wr_n : 1;
352 u32 config_Prog_n : 1;
353 u32 config_Init_stat : 1;
354 u32 config_Done_stat : 1;
355 u32 pcmcia_b_mod_pwr_n : 1;
356 u32 pcmcia_a_mod_pwr_n : 1;
357 u32 reserved : 3;
358 u32 Timer_addr : 5;
359 u32 unused : 1;
360 u32 timer_data : 7;
361 u32 Timer_Load_req : 1;
362 u32 Timer_Read_req : 1;
363 u32 oncecycle_read : 1;
364 u32 serialReset : 1;
365 } pi_608;
366
367 struct {
368 u32 reserved : 6;
369 u32 rw_flag : 1;
370 u32 dvb_en : 1;
371 u32 key_array_row : 5;
372 u32 key_array_col : 3;
373 u32 key_code : 2;
374 u32 key_enable : 1;
375 u32 PID :13;
376 } dvb_reg_60c;
377
378 struct {
379 u32 start_sram_ibi : 1;
380 u32 reserved2 : 1;
381 u32 ce_pin_reg : 1;
382 u32 oe_pin_reg : 1;
383 u32 reserved1 : 3;
384 u32 sc_xfer_bit : 1;
385 u32 sram_data : 8;
386 u32 sram_rw : 1;
387 u32 sram_addr :15;
388 } sram_ctrl_reg_700;
389
390 struct {
391 u32 net_addr_write :16;
392 u32 net_addr_read :16;
393 } net_buf_reg_704;
394
395 struct {
396 u32 cai_cnt : 4;
397 u32 reserved2 : 6;
398 u32 cai_write :11;
399 u32 reserved1 : 5;
400 u32 cai_read :11;
401 } cai_buf_reg_708;
402
403 struct {
404 u32 cao_cnt : 4;
405 u32 reserved2 : 6;
406 u32 cap_write :11;
407 u32 reserved1 : 5;
408 u32 cao_read :11;
409 } cao_buf_reg_70c;
410
411 struct {
412 u32 media_cnt : 4;
413 u32 reserved2 : 6;
414 u32 media_write :11;
415 u32 reserved1 : 5;
416 u32 media_read :11;
417 } media_buf_reg_710;
418
419 struct {
420 u32 reserved :17;
421 u32 ctrl_maximumfill : 1;
422 u32 ctrl_sramdma : 1;
423 u32 ctrl_usb_wan : 1;
424 u32 cao_ovflow_error : 1;
425 u32 cai_ovflow_error : 1;
426 u32 media_ovflow_error : 1;
427 u32 net_ovflow_error : 1;
428 u32 MEDIA_Dest : 2;
429 u32 CAO_Dest : 2;
430 u32 CAI_Dest : 2;
431 u32 NET_Dest : 2;
432 } sram_dest_reg_714;
433
434 struct {
435 u32 reserved3 :11;
436 u32 net_addr_write : 1;
437 u32 reserved2 : 3;
438 u32 net_addr_read : 1;
439 u32 reserved1 : 4;
440 u32 net_cnt :12;
441 } net_buf_reg_718;
442
443 struct {
444 u32 reserved3 : 4;
445 u32 wan_pkt_frame : 4;
446 u32 reserved2 : 4;
447 u32 sram_memmap : 2;
448 u32 sram_chip : 2;
449 u32 wan_wait_state : 8;
450 u32 reserved1 : 6;
451 u32 wan_speed_sig : 2;
452 } wan_ctrl_reg_71c;
453} flexcop_ibi_value;
454
455#endif
diff --git a/drivers/media/common/b2c2/flexcop_ibi_value_le.h b/drivers/media/common/b2c2/flexcop_ibi_value_le.h
deleted file mode 100644
index c75830d7d94..00000000000
--- a/drivers/media/common/b2c2/flexcop_ibi_value_le.h
+++ /dev/null
@@ -1,455 +0,0 @@
1/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
2 * register descriptions
3 * see flexcop.c for copyright information
4 */
5/* This file is automatically generated, do not edit things here. */
6#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
7#define __FLEXCOP_IBI_VALUE_INCLUDED__
8
9typedef union {
10 u32 raw;
11
12 struct {
13 u32 dma_0start : 1;
14 u32 dma_0No_update : 1;
15 u32 dma_address0 :30;
16 } dma_0x0;
17
18 struct {
19 u32 DMA_maxpackets : 8;
20 u32 dma_addr_size :24;
21 } dma_0x4_remap;
22
23 struct {
24 u32 dma1timer : 7;
25 u32 unused : 1;
26 u32 dma_addr_size :24;
27 } dma_0x4_read;
28
29 struct {
30 u32 unused : 1;
31 u32 dmatimer : 7;
32 u32 dma_addr_size :24;
33 } dma_0x4_write;
34
35 struct {
36 u32 unused : 2;
37 u32 dma_cur_addr :30;
38 } dma_0x8;
39
40 struct {
41 u32 dma_1start : 1;
42 u32 remap_enable : 1;
43 u32 dma_address1 :30;
44 } dma_0xc;
45
46 struct {
47 u32 chipaddr : 7;
48 u32 reserved1 : 1;
49 u32 baseaddr : 8;
50 u32 data1_reg : 8;
51 u32 working_start : 1;
52 u32 twoWS_rw : 1;
53 u32 total_bytes : 2;
54 u32 twoWS_port_reg : 2;
55 u32 no_base_addr_ack_error : 1;
56 u32 st_done : 1;
57 } tw_sm_c_100;
58
59 struct {
60 u32 data2_reg : 8;
61 u32 data3_reg : 8;
62 u32 data4_reg : 8;
63 u32 exlicit_stops : 1;
64 u32 force_stop : 1;
65 u32 unused : 6;
66 } tw_sm_c_104;
67
68 struct {
69 u32 thi1 : 6;
70 u32 reserved1 : 2;
71 u32 tlo1 : 5;
72 u32 reserved2 :19;
73 } tw_sm_c_108;
74
75 struct {
76 u32 thi1 : 6;
77 u32 reserved1 : 2;
78 u32 tlo1 : 5;
79 u32 reserved2 :19;
80 } tw_sm_c_10c;
81
82 struct {
83 u32 thi1 : 6;
84 u32 reserved1 : 2;
85 u32 tlo1 : 5;
86 u32 reserved2 :19;
87 } tw_sm_c_110;
88
89 struct {
90 u32 LNB_CTLHighCount_sig :15;
91 u32 LNB_CTLLowCount_sig :15;
92 u32 LNB_CTLPrescaler_sig : 2;
93 } lnb_switch_freq_200;
94
95 struct {
96 u32 ACPI1_sig : 1;
97 u32 ACPI3_sig : 1;
98 u32 LNB_L_H_sig : 1;
99 u32 Per_reset_sig : 1;
100 u32 reserved :20;
101 u32 Rev_N_sig_revision_hi : 4;
102 u32 Rev_N_sig_reserved1 : 2;
103 u32 Rev_N_sig_caps : 1;
104 u32 Rev_N_sig_reserved2 : 1;
105 } misc_204;
106
107 struct {
108 u32 Stream1_filter_sig : 1;
109 u32 Stream2_filter_sig : 1;
110 u32 PCR_filter_sig : 1;
111 u32 PMT_filter_sig : 1;
112 u32 EMM_filter_sig : 1;
113 u32 ECM_filter_sig : 1;
114 u32 Null_filter_sig : 1;
115 u32 Mask_filter_sig : 1;
116 u32 WAN_Enable_sig : 1;
117 u32 WAN_CA_Enable_sig : 1;
118 u32 CA_Enable_sig : 1;
119 u32 SMC_Enable_sig : 1;
120 u32 Per_CA_Enable_sig : 1;
121 u32 Multi2_Enable_sig : 1;
122 u32 MAC_filter_Mode_sig : 1;
123 u32 Rcv_Data_sig : 1;
124 u32 DMA1_IRQ_Enable_sig : 1;
125 u32 DMA1_Timer_Enable_sig : 1;
126 u32 DMA2_IRQ_Enable_sig : 1;
127 u32 DMA2_Timer_Enable_sig : 1;
128 u32 DMA1_Size_IRQ_Enable_sig : 1;
129 u32 DMA2_Size_IRQ_Enable_sig : 1;
130 u32 Mailbox_from_V8_Enable_sig : 1;
131 u32 unused : 9;
132 } ctrl_208;
133
134 struct {
135 u32 DMA1_IRQ_Status : 1;
136 u32 DMA1_Timer_Status : 1;
137 u32 DMA2_IRQ_Status : 1;
138 u32 DMA2_Timer_Status : 1;
139 u32 DMA1_Size_IRQ_Status : 1;
140 u32 DMA2_Size_IRQ_Status : 1;
141 u32 Mailbox_from_V8_Status_sig : 1;
142 u32 Data_receiver_error : 1;
143 u32 Continuity_error_flag : 1;
144 u32 LLC_SNAP_FLAG_set : 1;
145 u32 Transport_Error : 1;
146 u32 reserved :21;
147 } irq_20c;
148
149 struct {
150 u32 reset_block_000 : 1;
151 u32 reset_block_100 : 1;
152 u32 reset_block_200 : 1;
153 u32 reset_block_300 : 1;
154 u32 reset_block_400 : 1;
155 u32 reset_block_500 : 1;
156 u32 reset_block_600 : 1;
157 u32 reset_block_700 : 1;
158 u32 Block_reset_enable : 8;
159 u32 Special_controls :16;
160 } sw_reset_210;
161
162 struct {
163 u32 vuart_oe_sig : 1;
164 u32 v2WS_oe_sig : 1;
165 u32 halt_V8_sig : 1;
166 u32 section_pkg_enable_sig : 1;
167 u32 s2p_sel_sig : 1;
168 u32 unused1 : 3;
169 u32 polarity_PS_CLK_sig : 1;
170 u32 polarity_PS_VALID_sig : 1;
171 u32 polarity_PS_SYNC_sig : 1;
172 u32 polarity_PS_ERR_sig : 1;
173 u32 unused2 :20;
174 } misc_214;
175
176 struct {
177 u32 Mailbox_from_V8 :32;
178 } mbox_v8_to_host_218;
179
180 struct {
181 u32 sysramaccess_data : 8;
182 u32 sysramaccess_addr :15;
183 u32 unused : 7;
184 u32 sysramaccess_write : 1;
185 u32 sysramaccess_busmuster : 1;
186 } mbox_host_to_v8_21c;
187
188 struct {
189 u32 Stream1_PID :13;
190 u32 Stream1_trans : 1;
191 u32 MAC_Multicast_filter : 1;
192 u32 debug_flag_pid_saved : 1;
193 u32 Stream2_PID :13;
194 u32 Stream2_trans : 1;
195 u32 debug_flag_write_status00 : 1;
196 u32 debug_fifo_problem : 1;
197 } pid_filter_300;
198
199 struct {
200 u32 PCR_PID :13;
201 u32 PCR_trans : 1;
202 u32 debug_overrun3 : 1;
203 u32 debug_overrun2 : 1;
204 u32 PMT_PID :13;
205 u32 PMT_trans : 1;
206 u32 reserved : 2;
207 } pid_filter_304;
208
209 struct {
210 u32 EMM_PID :13;
211 u32 EMM_trans : 1;
212 u32 EMM_filter_4 : 1;
213 u32 EMM_filter_6 : 1;
214 u32 ECM_PID :13;
215 u32 ECM_trans : 1;
216 u32 reserved : 2;
217 } pid_filter_308;
218
219 struct {
220 u32 Group_PID :13;
221 u32 Group_trans : 1;
222 u32 unused1 : 2;
223 u32 Group_mask :13;
224 u32 unused2 : 3;
225 } pid_filter_30c_ext_ind_0_7;
226
227 struct {
228 u32 net_master_read :17;
229 u32 unused :15;
230 } pid_filter_30c_ext_ind_1;
231
232 struct {
233 u32 net_master_write :17;
234 u32 unused :15;
235 } pid_filter_30c_ext_ind_2;
236
237 struct {
238 u32 next_net_master_write :17;
239 u32 unused :15;
240 } pid_filter_30c_ext_ind_3;
241
242 struct {
243 u32 unused1 : 1;
244 u32 state_write :10;
245 u32 reserved1 : 6;
246 u32 stack_read :10;
247 u32 reserved2 : 5;
248 } pid_filter_30c_ext_ind_4;
249
250 struct {
251 u32 stack_cnt :10;
252 u32 unused :22;
253 } pid_filter_30c_ext_ind_5;
254
255 struct {
256 u32 pid_fsm_save_reg0 : 2;
257 u32 pid_fsm_save_reg1 : 2;
258 u32 pid_fsm_save_reg2 : 2;
259 u32 pid_fsm_save_reg3 : 2;
260 u32 pid_fsm_save_reg4 : 2;
261 u32 pid_fsm_save_reg300 : 2;
262 u32 write_status1 : 2;
263 u32 write_status4 : 2;
264 u32 data_size_reg :12;
265 u32 unused : 4;
266 } pid_filter_30c_ext_ind_6;
267
268 struct {
269 u32 index_reg : 5;
270 u32 extra_index_reg : 3;
271 u32 AB_select : 1;
272 u32 pass_alltables : 1;
273 u32 unused :22;
274 } index_reg_310;
275
276 struct {
277 u32 PID :13;
278 u32 PID_trans : 1;
279 u32 PID_enable_bit : 1;
280 u32 reserved :17;
281 } pid_n_reg_314;
282
283 struct {
284 u32 A4_byte : 8;
285 u32 A5_byte : 8;
286 u32 A6_byte : 8;
287 u32 Enable_bit : 1;
288 u32 HighAB_bit : 1;
289 u32 reserved : 6;
290 } mac_low_reg_318;
291
292 struct {
293 u32 A1_byte : 8;
294 u32 A2_byte : 8;
295 u32 A3_byte : 8;
296 u32 reserved : 8;
297 } mac_high_reg_31c;
298
299 struct {
300 u32 reserved :16;
301 u32 data_Tag_ID :16;
302 } data_tag_400;
303
304 struct {
305 u32 Card_IDbyte6 : 8;
306 u32 Card_IDbyte5 : 8;
307 u32 Card_IDbyte4 : 8;
308 u32 Card_IDbyte3 : 8;
309 } card_id_408;
310
311 struct {
312 u32 Card_IDbyte2 : 8;
313 u32 Card_IDbyte1 : 8;
314 } card_id_40c;
315
316 struct {
317 u32 MAC1 : 8;
318 u32 MAC2 : 8;
319 u32 MAC3 : 8;
320 u32 MAC6 : 8;
321 } mac_address_418;
322
323 struct {
324 u32 MAC7 : 8;
325 u32 MAC8 : 8;
326 u32 reserved :16;
327 } mac_address_41c;
328
329 struct {
330 u32 transmitter_data_byte : 8;
331 u32 ReceiveDataReady : 1;
332 u32 ReceiveByteFrameError : 1;
333 u32 txbuffempty : 1;
334 u32 reserved :21;
335 } ci_600;
336
337 struct {
338 u32 pi_d : 8;
339 u32 pi_ha :20;
340 u32 pi_rw : 1;
341 u32 pi_component_reg : 3;
342 } pi_604;
343
344 struct {
345 u32 serialReset : 1;
346 u32 oncecycle_read : 1;
347 u32 Timer_Read_req : 1;
348 u32 Timer_Load_req : 1;
349 u32 timer_data : 7;
350 u32 unused : 1;
351 u32 Timer_addr : 5;
352 u32 reserved : 3;
353 u32 pcmcia_a_mod_pwr_n : 1;
354 u32 pcmcia_b_mod_pwr_n : 1;
355 u32 config_Done_stat : 1;
356 u32 config_Init_stat : 1;
357 u32 config_Prog_n : 1;
358 u32 config_wr_n : 1;
359 u32 config_cs_n : 1;
360 u32 config_cclk : 1;
361 u32 pi_CiMax_IRQ_n : 1;
362 u32 pi_timeout_status : 1;
363 u32 pi_wait_n : 1;
364 u32 pi_busy_n : 1;
365 } pi_608;
366
367 struct {
368 u32 PID :13;
369 u32 key_enable : 1;
370 u32 key_code : 2;
371 u32 key_array_col : 3;
372 u32 key_array_row : 5;
373 u32 dvb_en : 1;
374 u32 rw_flag : 1;
375 u32 reserved : 6;
376 } dvb_reg_60c;
377
378 struct {
379 u32 sram_addr :15;
380 u32 sram_rw : 1;
381 u32 sram_data : 8;
382 u32 sc_xfer_bit : 1;
383 u32 reserved1 : 3;
384 u32 oe_pin_reg : 1;
385 u32 ce_pin_reg : 1;
386 u32 reserved2 : 1;
387 u32 start_sram_ibi : 1;
388 } sram_ctrl_reg_700;
389
390 struct {
391 u32 net_addr_read :16;
392 u32 net_addr_write :16;
393 } net_buf_reg_704;
394
395 struct {
396 u32 cai_read :11;
397 u32 reserved1 : 5;
398 u32 cai_write :11;
399 u32 reserved2 : 6;
400 u32 cai_cnt : 4;
401 } cai_buf_reg_708;
402
403 struct {
404 u32 cao_read :11;
405 u32 reserved1 : 5;
406 u32 cap_write :11;
407 u32 reserved2 : 6;
408 u32 cao_cnt : 4;
409 } cao_buf_reg_70c;
410
411 struct {
412 u32 media_read :11;
413 u32 reserved1 : 5;
414 u32 media_write :11;
415 u32 reserved2 : 6;
416 u32 media_cnt : 4;
417 } media_buf_reg_710;
418
419 struct {
420 u32 NET_Dest : 2;
421 u32 CAI_Dest : 2;
422 u32 CAO_Dest : 2;
423 u32 MEDIA_Dest : 2;
424 u32 net_ovflow_error : 1;
425 u32 media_ovflow_error : 1;
426 u32 cai_ovflow_error : 1;
427 u32 cao_ovflow_error : 1;
428 u32 ctrl_usb_wan : 1;
429 u32 ctrl_sramdma : 1;
430 u32 ctrl_maximumfill : 1;
431 u32 reserved :17;
432 } sram_dest_reg_714;
433
434 struct {
435 u32 net_cnt :12;
436 u32 reserved1 : 4;
437 u32 net_addr_read : 1;
438 u32 reserved2 : 3;
439 u32 net_addr_write : 1;
440 u32 reserved3 :11;
441 } net_buf_reg_718;
442
443 struct {
444 u32 wan_speed_sig : 2;
445 u32 reserved1 : 6;
446 u32 wan_wait_state : 8;
447 u32 sram_chip : 2;
448 u32 sram_memmap : 2;
449 u32 reserved2 : 4;
450 u32 wan_pkt_frame : 4;
451 u32 reserved3 : 4;
452 } wan_ctrl_reg_71c;
453} flexcop_ibi_value;
454
455#endif
diff --git a/drivers/media/common/saa7146/Kconfig b/drivers/media/common/saa7146/Kconfig
deleted file mode 100644
index 769c6f8142d..00000000000
--- a/drivers/media/common/saa7146/Kconfig
+++ /dev/null
@@ -1,9 +0,0 @@
1config VIDEO_SAA7146
2 tristate
3 depends on I2C && PCI
4
5config VIDEO_SAA7146_VV
6 tristate
7 depends on VIDEO_V4L2
8 select VIDEOBUF_DMA_SG
9 select VIDEO_SAA7146
diff --git a/drivers/media/common/saa7146/Makefile b/drivers/media/common/saa7146/Makefile
deleted file mode 100644
index 3219b00a877..00000000000
--- a/drivers/media/common/saa7146/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3
4obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
5obj-$(CONFIG_VIDEO_SAA7146_VV) += saa7146_vv.o
diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c
deleted file mode 100644
index bb6ee5191eb..00000000000
--- a/drivers/media/common/saa7146/saa7146_core.c
+++ /dev/null
@@ -1,592 +0,0 @@
1/*
2 saa7146.o - driver for generic saa7146-based hardware
3
4 Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <media/saa7146.h>
24#include <linux/module.h>
25
26static int saa7146_num;
27
28unsigned int saa7146_debug;
29
30module_param(saa7146_debug, uint, 0644);
31MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");
32
33#if 0
34static void dump_registers(struct saa7146_dev* dev)
35{
36 int i = 0;
37
38 pr_info(" @ %li jiffies:\n", jiffies);
39 for (i = 0; i <= 0x148; i += 4)
40 pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i));
41}
42#endif
43
44/****************************************************************************
45 * gpio and debi helper functions
46 ****************************************************************************/
47
48void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
49{
50 u32 value = 0;
51
52 BUG_ON(port > 3);
53
54 value = saa7146_read(dev, GPIO_CTRL);
55 value &= ~(0xff << (8*port));
56 value |= (data << (8*port));
57 saa7146_write(dev, GPIO_CTRL, value);
58}
59
60/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
61static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
62 unsigned long us1, unsigned long us2)
63{
64 unsigned long timeout;
65 int err;
66
67 /* wait for registers to be programmed */
68 timeout = jiffies + usecs_to_jiffies(us1);
69 while (1) {
70 err = time_after(jiffies, timeout);
71 if (saa7146_read(dev, MC2) & 2)
72 break;
73 if (err) {
74 pr_err("%s: %s timed out while waiting for registers getting programmed\n",
75 dev->name, __func__);
76 return -ETIMEDOUT;
77 }
78 msleep(1);
79 }
80
81 /* wait for transfer to complete */
82 timeout = jiffies + usecs_to_jiffies(us2);
83 while (1) {
84 err = time_after(jiffies, timeout);
85 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
86 break;
87 saa7146_read(dev, MC2);
88 if (err) {
89 DEB_S("%s: %s timed out while waiting for transfer completion\n",
90 dev->name, __func__);
91 return -ETIMEDOUT;
92 }
93 msleep(1);
94 }
95
96 return 0;
97}
98
99static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
100 unsigned long us1, unsigned long us2)
101{
102 unsigned long loops;
103
104 /* wait for registers to be programmed */
105 loops = us1;
106 while (1) {
107 if (saa7146_read(dev, MC2) & 2)
108 break;
109 if (!loops--) {
110 pr_err("%s: %s timed out while waiting for registers getting programmed\n",
111 dev->name, __func__);
112 return -ETIMEDOUT;
113 }
114 udelay(1);
115 }
116
117 /* wait for transfer to complete */
118 loops = us2 / 5;
119 while (1) {
120 if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
121 break;
122 saa7146_read(dev, MC2);
123 if (!loops--) {
124 DEB_S("%s: %s timed out while waiting for transfer completion\n",
125 dev->name, __func__);
126 return -ETIMEDOUT;
127 }
128 udelay(5);
129 }
130
131 return 0;
132}
133
134int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
135{
136 if (nobusyloop)
137 return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
138 else
139 return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
140}
141
142/****************************************************************************
143 * general helper functions
144 ****************************************************************************/
145
146/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
147 make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
148 may be triggered on highmem machines */
149static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
150{
151 struct scatterlist *sglist;
152 struct page *pg;
153 int i;
154
155 sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
156 if (NULL == sglist)
157 return NULL;
158 sg_init_table(sglist, nr_pages);
159 for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
160 pg = vmalloc_to_page(virt);
161 if (NULL == pg)
162 goto err;
163 BUG_ON(PageHighMem(pg));
164 sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
165 }
166 return sglist;
167
168 err:
169 kfree(sglist);
170 return NULL;
171}
172
173/********************************************************************************/
174/* common page table functions */
175
176void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
177{
178 int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
179 void *mem = vmalloc_32(length);
180 int slen = 0;
181
182 if (NULL == mem)
183 goto err_null;
184
185 if (!(pt->slist = vmalloc_to_sg(mem, pages)))
186 goto err_free_mem;
187
188 if (saa7146_pgtable_alloc(pci, pt))
189 goto err_free_slist;
190
191 pt->nents = pages;
192 slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
193 if (0 == slen)
194 goto err_free_pgtable;
195
196 if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
197 goto err_unmap_sg;
198
199 return mem;
200
201err_unmap_sg:
202 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
203err_free_pgtable:
204 saa7146_pgtable_free(pci, pt);
205err_free_slist:
206 kfree(pt->slist);
207 pt->slist = NULL;
208err_free_mem:
209 vfree(mem);
210err_null:
211 return NULL;
212}
213
214void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt)
215{
216 pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
217 saa7146_pgtable_free(pci, pt);
218 kfree(pt->slist);
219 pt->slist = NULL;
220 vfree(mem);
221}
222
223void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
224{
225 if (NULL == pt->cpu)
226 return;
227 pci_free_consistent(pci, pt->size, pt->cpu, pt->dma);
228 pt->cpu = NULL;
229}
230
231int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
232{
233 __le32 *cpu;
234 dma_addr_t dma_addr = 0;
235
236 cpu = pci_alloc_consistent(pci, PAGE_SIZE, &dma_addr);
237 if (NULL == cpu) {
238 return -ENOMEM;
239 }
240 pt->size = PAGE_SIZE;
241 pt->cpu = cpu;
242 pt->dma = dma_addr;
243
244 return 0;
245}
246
247int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
248 struct scatterlist *list, int sglen )
249{
250 __le32 *ptr, fill;
251 int nr_pages = 0;
252 int i,p;
253
254 BUG_ON(0 == sglen);
255 BUG_ON(list->offset > PAGE_SIZE);
256
257 /* if we have a user buffer, the first page may not be
258 aligned to a page boundary. */
259 pt->offset = list->offset;
260
261 ptr = pt->cpu;
262 for (i = 0; i < sglen; i++, list++) {
263/*
264 pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n",
265 i, sg_dma_address(list), sg_dma_len(list),
266 list->offset);
267*/
268 for (p = 0; p * 4096 < list->length; p++, ptr++) {
269 *ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
270 nr_pages++;
271 }
272 }
273
274
275 /* safety; fill the page table up with the last valid page */
276 fill = *(ptr-1);
277 for(i=nr_pages;i<1024;i++) {
278 *ptr++ = fill;
279 }
280
281/*
282 ptr = pt->cpu;
283 pr_debug("offset: %d\n", pt->offset);
284 for(i=0;i<5;i++) {
285 pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]);
286 }
287*/
288 return 0;
289}
290
291/********************************************************************************/
292/* interrupt handler */
293static irqreturn_t interrupt_hw(int irq, void *dev_id)
294{
295 struct saa7146_dev *dev = dev_id;
296 u32 isr;
297 u32 ack_isr;
298
299 /* read out the interrupt status register */
300 ack_isr = isr = saa7146_read(dev, ISR);
301
302 /* is this our interrupt? */
303 if ( 0 == isr ) {
304 /* nope, some other device */
305 return IRQ_NONE;
306 }
307
308 if (dev->ext) {
309 if (dev->ext->irq_mask & isr) {
310 if (dev->ext->irq_func)
311 dev->ext->irq_func(dev, &isr);
312 isr &= ~dev->ext->irq_mask;
313 }
314 }
315 if (0 != (isr & (MASK_27))) {
316 DEB_INT("irq: RPS0 (0x%08x)\n", isr);
317 if (dev->vv_data && dev->vv_callback)
318 dev->vv_callback(dev,isr);
319 isr &= ~MASK_27;
320 }
321 if (0 != (isr & (MASK_28))) {
322 if (dev->vv_data && dev->vv_callback)
323 dev->vv_callback(dev,isr);
324 isr &= ~MASK_28;
325 }
326 if (0 != (isr & (MASK_16|MASK_17))) {
327 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
328 /* only wake up if we expect something */
329 if (0 != dev->i2c_op) {
330 dev->i2c_op = 0;
331 wake_up(&dev->i2c_wq);
332 } else {
333 u32 psr = saa7146_read(dev, PSR);
334 u32 ssr = saa7146_read(dev, SSR);
335 pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
336 dev->name, isr, psr, ssr);
337 }
338 isr &= ~(MASK_16|MASK_17);
339 }
340 if( 0 != isr ) {
341 ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n",
342 isr);
343 ERR("disabling interrupt source(s)!\n");
344 SAA7146_IER_DISABLE(dev,isr);
345 }
346 saa7146_write(dev, ISR, ack_isr);
347 return IRQ_HANDLED;
348}
349
350/*********************************************************************************/
351/* configuration-functions */
352
353static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
354{
355 struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
356 struct saa7146_extension *ext = pci_ext->ext;
357 struct saa7146_dev *dev;
358 int err = -ENOMEM;
359
360 /* clear out mem for sure */
361 dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL);
362 if (!dev) {
363 ERR("out of memory\n");
364 goto out;
365 }
366
367 DEB_EE("pci:%p\n", pci);
368
369 err = pci_enable_device(pci);
370 if (err < 0) {
371 ERR("pci_enable_device() failed\n");
372 goto err_free;
373 }
374
375 /* enable bus-mastering */
376 pci_set_master(pci);
377
378 dev->pci = pci;
379
380 /* get chip-revision; this is needed to enable bug-fixes */
381 dev->revision = pci->revision;
382
383 /* remap the memory from virtual to physical address */
384
385 err = pci_request_region(pci, 0, "saa7146");
386 if (err < 0)
387 goto err_disable;
388
389 dev->mem = ioremap(pci_resource_start(pci, 0),
390 pci_resource_len(pci, 0));
391 if (!dev->mem) {
392 ERR("ioremap() failed\n");
393 err = -ENODEV;
394 goto err_release;
395 }
396
397 /* we don't do a master reset here anymore, it screws up
398 some boards that don't have an i2c-eeprom for configuration
399 values */
400/*
401 saa7146_write(dev, MC1, MASK_31);
402*/
403
404 /* disable all irqs */
405 saa7146_write(dev, IER, 0);
406
407 /* shut down all dma transfers and rps tasks */
408 saa7146_write(dev, MC1, 0x30ff0000);
409
410 /* clear out any rps-signals pending */
411 saa7146_write(dev, MC2, 0xf8000000);
412
413 /* request an interrupt for the saa7146 */
414 err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED | IRQF_DISABLED,
415 dev->name, dev);
416 if (err < 0) {
417 ERR("request_irq() failed\n");
418 goto err_unmap;
419 }
420
421 err = -ENOMEM;
422
423 /* get memory for various stuff */
424 dev->d_rps0.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
425 &dev->d_rps0.dma_handle);
426 if (!dev->d_rps0.cpu_addr)
427 goto err_free_irq;
428 memset(dev->d_rps0.cpu_addr, 0x0, SAA7146_RPS_MEM);
429
430 dev->d_rps1.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
431 &dev->d_rps1.dma_handle);
432 if (!dev->d_rps1.cpu_addr)
433 goto err_free_rps0;
434 memset(dev->d_rps1.cpu_addr, 0x0, SAA7146_RPS_MEM);
435
436 dev->d_i2c.cpu_addr = pci_alloc_consistent(pci, SAA7146_RPS_MEM,
437 &dev->d_i2c.dma_handle);
438 if (!dev->d_i2c.cpu_addr)
439 goto err_free_rps1;
440 memset(dev->d_i2c.cpu_addr, 0x0, SAA7146_RPS_MEM);
441
442 /* the rest + print status message */
443
444 /* create a nice device name */
445 sprintf(dev->name, "saa7146 (%d)", saa7146_num);
446
447 pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n",
448 dev->mem, dev->revision, pci->irq,
449 pci->subsystem_vendor, pci->subsystem_device);
450 dev->ext = ext;
451
452 mutex_init(&dev->v4l2_lock);
453 spin_lock_init(&dev->int_slock);
454 spin_lock_init(&dev->slock);
455
456 mutex_init(&dev->i2c_lock);
457
458 dev->module = THIS_MODULE;
459 init_waitqueue_head(&dev->i2c_wq);
460
461 /* set some sane pci arbitrition values */
462 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
463
464 /* TODO: use the status code of the callback */
465
466 err = -ENODEV;
467
468 if (ext->probe && ext->probe(dev)) {
469 DEB_D("ext->probe() failed for %p. skipping device.\n", dev);
470 goto err_free_i2c;
471 }
472
473 if (ext->attach(dev, pci_ext)) {
474 DEB_D("ext->attach() failed for %p. skipping device.\n", dev);
475 goto err_free_i2c;
476 }
477 /* V4L extensions will set the pci drvdata to the v4l2_device in the
478 attach() above. So for those cards that do not use V4L we have to
479 set it explicitly. */
480 pci_set_drvdata(pci, &dev->v4l2_dev);
481
482 saa7146_num++;
483
484 err = 0;
485out:
486 return err;
487
488err_free_i2c:
489 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
490 dev->d_i2c.dma_handle);
491err_free_rps1:
492 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr,
493 dev->d_rps1.dma_handle);
494err_free_rps0:
495 pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr,
496 dev->d_rps0.dma_handle);
497err_free_irq:
498 free_irq(pci->irq, (void *)dev);
499err_unmap:
500 iounmap(dev->mem);
501err_release:
502 pci_release_region(pci, 0);
503err_disable:
504 pci_disable_device(pci);
505err_free:
506 kfree(dev);
507 goto out;
508}
509
510static void saa7146_remove_one(struct pci_dev *pdev)
511{
512 struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
513 struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
514 struct {
515 void *addr;
516 dma_addr_t dma;
517 } dev_map[] = {
518 { dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle },
519 { dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle },
520 { dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle },
521 { NULL, 0 }
522 }, *p;
523
524 DEB_EE("dev:%p\n", dev);
525
526 dev->ext->detach(dev);
527 /* Zero the PCI drvdata after use. */
528 pci_set_drvdata(pdev, NULL);
529
530 /* shut down all video dma transfers */
531 saa7146_write(dev, MC1, 0x00ff0000);
532
533 /* disable all irqs, release irq-routine */
534 saa7146_write(dev, IER, 0);
535
536 free_irq(pdev->irq, dev);
537
538 for (p = dev_map; p->addr; p++)
539 pci_free_consistent(pdev, SAA7146_RPS_MEM, p->addr, p->dma);
540
541 iounmap(dev->mem);
542 pci_release_region(pdev, 0);
543 pci_disable_device(pdev);
544 kfree(dev);
545
546 saa7146_num--;
547}
548
549/*********************************************************************************/
550/* extension handling functions */
551
552int saa7146_register_extension(struct saa7146_extension* ext)
553{
554 DEB_EE("ext:%p\n", ext);
555
556 ext->driver.name = ext->name;
557 ext->driver.id_table = ext->pci_tbl;
558 ext->driver.probe = saa7146_init_one;
559 ext->driver.remove = saa7146_remove_one;
560
561 pr_info("register extension '%s'\n", ext->name);
562 return pci_register_driver(&ext->driver);
563}
564
565int saa7146_unregister_extension(struct saa7146_extension* ext)
566{
567 DEB_EE("ext:%p\n", ext);
568 pr_info("unregister extension '%s'\n", ext->name);
569 pci_unregister_driver(&ext->driver);
570 return 0;
571}
572
573EXPORT_SYMBOL_GPL(saa7146_register_extension);
574EXPORT_SYMBOL_GPL(saa7146_unregister_extension);
575
576/* misc functions used by extension modules */
577EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
578EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
579EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
580EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
581EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
582EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);
583
584EXPORT_SYMBOL_GPL(saa7146_setgpio);
585
586EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);
587
588EXPORT_SYMBOL_GPL(saa7146_debug);
589
590MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
591MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
592MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c
deleted file mode 100644
index b3890bd49df..00000000000
--- a/drivers/media/common/saa7146/saa7146_fops.c
+++ /dev/null
@@ -1,664 +0,0 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
3#include <media/saa7146_vv.h>
4#include <linux/module.h>
5
6/****************************************************************************/
7/* resource management functions, shamelessly stolen from saa7134 driver */
8
9int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
10{
11 struct saa7146_dev *dev = fh->dev;
12 struct saa7146_vv *vv = dev->vv_data;
13
14 if (fh->resources & bit) {
15 DEB_D("already allocated! want: 0x%02x, cur:0x%02x\n",
16 bit, vv->resources);
17 /* have it already allocated */
18 return 1;
19 }
20
21 /* is it free? */
22 if (vv->resources & bit) {
23 DEB_D("locked! vv->resources:0x%02x, we want:0x%02x\n",
24 vv->resources, bit);
25 /* no, someone else uses it */
26 return 0;
27 }
28 /* it's free, grab it */
29 fh->resources |= bit;
30 vv->resources |= bit;
31 DEB_D("res: get 0x%02x, cur:0x%02x\n", bit, vv->resources);
32 return 1;
33}
34
35void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
36{
37 struct saa7146_dev *dev = fh->dev;
38 struct saa7146_vv *vv = dev->vv_data;
39
40 BUG_ON((fh->resources & bits) != bits);
41
42 fh->resources &= ~bits;
43 vv->resources &= ~bits;
44 DEB_D("res: put 0x%02x, cur:0x%02x\n", bits, vv->resources);
45}
46
47
48/********************************************************************************/
49/* common dma functions */
50
51void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
52 struct saa7146_buf *buf)
53{
54 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
55 DEB_EE("dev:%p, buf:%p\n", dev, buf);
56
57 BUG_ON(in_interrupt());
58
59 videobuf_waiton(q, &buf->vb, 0, 0);
60 videobuf_dma_unmap(q->dev, dma);
61 videobuf_dma_free(dma);
62 buf->vb.state = VIDEOBUF_NEEDS_INIT;
63}
64
65
66/********************************************************************************/
67/* common buffer functions */
68
69int saa7146_buffer_queue(struct saa7146_dev *dev,
70 struct saa7146_dmaqueue *q,
71 struct saa7146_buf *buf)
72{
73 assert_spin_locked(&dev->slock);
74 DEB_EE("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf);
75
76 BUG_ON(!q);
77
78 if (NULL == q->curr) {
79 q->curr = buf;
80 DEB_D("immediately activating buffer %p\n", buf);
81 buf->activate(dev,buf,NULL);
82 } else {
83 list_add_tail(&buf->vb.queue,&q->queue);
84 buf->vb.state = VIDEOBUF_QUEUED;
85 DEB_D("adding buffer %p to queue. (active buffer present)\n",
86 buf);
87 }
88 return 0;
89}
90
91void saa7146_buffer_finish(struct saa7146_dev *dev,
92 struct saa7146_dmaqueue *q,
93 int state)
94{
95 assert_spin_locked(&dev->slock);
96 DEB_EE("dev:%p, dmaq:%p, state:%d\n", dev, q, state);
97 DEB_EE("q->curr:%p\n", q->curr);
98
99 BUG_ON(!q->curr);
100
101 /* finish current buffer */
102 if (NULL == q->curr) {
103 DEB_D("aiii. no current buffer\n");
104 return;
105 }
106
107 q->curr->vb.state = state;
108 do_gettimeofday(&q->curr->vb.ts);
109 wake_up(&q->curr->vb.done);
110
111 q->curr = NULL;
112}
113
114void saa7146_buffer_next(struct saa7146_dev *dev,
115 struct saa7146_dmaqueue *q, int vbi)
116{
117 struct saa7146_buf *buf,*next = NULL;
118
119 BUG_ON(!q);
120
121 DEB_INT("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi);
122
123 assert_spin_locked(&dev->slock);
124 if (!list_empty(&q->queue)) {
125 /* activate next one from queue */
126 buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
127 list_del(&buf->vb.queue);
128 if (!list_empty(&q->queue))
129 next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
130 q->curr = buf;
131 DEB_INT("next buffer: buf:%p, prev:%p, next:%p\n",
132 buf, q->queue.prev, q->queue.next);
133 buf->activate(dev,buf,next);
134 } else {
135 DEB_INT("no next buffer. stopping.\n");
136 if( 0 != vbi ) {
137 /* turn off video-dma3 */
138 saa7146_write(dev,MC1, MASK_20);
139 } else {
140 /* nothing to do -- just prevent next video-dma1 transfer
141 by lowering the protection address */
142
143 // fixme: fix this for vflip != 0
144
145 saa7146_write(dev, PROT_ADDR1, 0);
146 saa7146_write(dev, MC2, (MASK_02|MASK_18));
147
148 /* write the address of the rps-program */
149 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
150 /* turn on rps */
151 saa7146_write(dev, MC1, (MASK_12 | MASK_28));
152
153/*
154 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
155 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
156 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
157 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
158 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
159 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
160*/
161 }
162 del_timer(&q->timeout);
163 }
164}
165
166void saa7146_buffer_timeout(unsigned long data)
167{
168 struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
169 struct saa7146_dev *dev = q->dev;
170 unsigned long flags;
171
172 DEB_EE("dev:%p, dmaq:%p\n", dev, q);
173
174 spin_lock_irqsave(&dev->slock,flags);
175 if (q->curr) {
176 DEB_D("timeout on %p\n", q->curr);
177 saa7146_buffer_finish(dev,q,VIDEOBUF_ERROR);
178 }
179
180 /* we don't restart the transfer here like other drivers do. when
181 a streaming capture is disabled, the timeout function will be
182 called for the current buffer. if we activate the next buffer now,
183 we mess up our capture logic. if a timeout occurs on another buffer,
184 then something is seriously broken before, so no need to buffer the
185 next capture IMHO... */
186/*
187 saa7146_buffer_next(dev,q);
188*/
189 spin_unlock_irqrestore(&dev->slock,flags);
190}
191
192/********************************************************************************/
193/* file operations */
194
195static int fops_open(struct file *file)
196{
197 struct video_device *vdev = video_devdata(file);
198 struct saa7146_dev *dev = video_drvdata(file);
199 struct saa7146_fh *fh = NULL;
200 int result = 0;
201
202 DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev));
203
204 if (mutex_lock_interruptible(vdev->lock))
205 return -ERESTARTSYS;
206
207 DEB_D("using: %p\n", dev);
208
209 /* check if an extension is registered */
210 if( NULL == dev->ext ) {
211 DEB_S("no extension registered for this device\n");
212 result = -ENODEV;
213 goto out;
214 }
215
216 /* allocate per open data */
217 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
218 if (NULL == fh) {
219 DEB_S("cannot allocate memory for per open data\n");
220 result = -ENOMEM;
221 goto out;
222 }
223
224 v4l2_fh_init(&fh->fh, vdev);
225
226 file->private_data = &fh->fh;
227 fh->dev = dev;
228
229 if (vdev->vfl_type == VFL_TYPE_VBI) {
230 DEB_S("initializing vbi...\n");
231 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
232 result = saa7146_vbi_uops.open(dev,file);
233 if (dev->ext_vv_data->vbi_fops.open)
234 dev->ext_vv_data->vbi_fops.open(file);
235 } else {
236 DEB_S("initializing video...\n");
237 result = saa7146_video_uops.open(dev,file);
238 }
239
240 if (0 != result) {
241 goto out;
242 }
243
244 if( 0 == try_module_get(dev->ext->module)) {
245 result = -EINVAL;
246 goto out;
247 }
248
249 result = 0;
250 v4l2_fh_add(&fh->fh);
251out:
252 if (fh && result != 0) {
253 kfree(fh);
254 file->private_data = NULL;
255 }
256 mutex_unlock(vdev->lock);
257 return result;
258}
259
260static int fops_release(struct file *file)
261{
262 struct video_device *vdev = video_devdata(file);
263 struct saa7146_fh *fh = file->private_data;
264 struct saa7146_dev *dev = fh->dev;
265
266 DEB_EE("file:%p\n", file);
267
268 if (mutex_lock_interruptible(vdev->lock))
269 return -ERESTARTSYS;
270
271 if (vdev->vfl_type == VFL_TYPE_VBI) {
272 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
273 saa7146_vbi_uops.release(dev,file);
274 if (dev->ext_vv_data->vbi_fops.release)
275 dev->ext_vv_data->vbi_fops.release(file);
276 } else {
277 saa7146_video_uops.release(dev,file);
278 }
279
280 v4l2_fh_del(&fh->fh);
281 v4l2_fh_exit(&fh->fh);
282 module_put(dev->ext->module);
283 file->private_data = NULL;
284 kfree(fh);
285
286 mutex_unlock(vdev->lock);
287
288 return 0;
289}
290
291static int fops_mmap(struct file *file, struct vm_area_struct * vma)
292{
293 struct video_device *vdev = video_devdata(file);
294 struct saa7146_fh *fh = file->private_data;
295 struct videobuf_queue *q;
296 int res;
297
298 switch (vdev->vfl_type) {
299 case VFL_TYPE_GRABBER: {
300 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",
301 file, vma);
302 q = &fh->video_q;
303 break;
304 }
305 case VFL_TYPE_VBI: {
306 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",
307 file, vma);
308 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
309 return -ENODEV;
310 q = &fh->vbi_q;
311 break;
312 }
313 default:
314 BUG();
315 return 0;
316 }
317
318 if (mutex_lock_interruptible(vdev->lock))
319 return -ERESTARTSYS;
320 res = videobuf_mmap_mapper(q, vma);
321 mutex_unlock(vdev->lock);
322 return res;
323}
324
325static unsigned int __fops_poll(struct file *file, struct poll_table_struct *wait)
326{
327 struct video_device *vdev = video_devdata(file);
328 struct saa7146_fh *fh = file->private_data;
329 struct videobuf_buffer *buf = NULL;
330 struct videobuf_queue *q;
331 unsigned int res = v4l2_ctrl_poll(file, wait);
332
333 DEB_EE("file:%p, poll:%p\n", file, wait);
334
335 if (vdev->vfl_type == VFL_TYPE_VBI) {
336 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_SLICED_VBI_OUTPUT)
337 return res | POLLOUT | POLLWRNORM;
338 if( 0 == fh->vbi_q.streaming )
339 return res | videobuf_poll_stream(file, &fh->vbi_q, wait);
340 q = &fh->vbi_q;
341 } else {
342 DEB_D("using video queue\n");
343 q = &fh->video_q;
344 }
345
346 if (!list_empty(&q->stream))
347 buf = list_entry(q->stream.next, struct videobuf_buffer, stream);
348
349 if (!buf) {
350 DEB_D("buf == NULL!\n");
351 return res | POLLERR;
352 }
353
354 poll_wait(file, &buf->done, wait);
355 if (buf->state == VIDEOBUF_DONE || buf->state == VIDEOBUF_ERROR) {
356 DEB_D("poll succeeded!\n");
357 return res | POLLIN | POLLRDNORM;
358 }
359
360 DEB_D("nothing to poll for, buf->state:%d\n", buf->state);
361 return res;
362}
363
364static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
365{
366 struct video_device *vdev = video_devdata(file);
367 unsigned int res;
368
369 mutex_lock(vdev->lock);
370 res = __fops_poll(file, wait);
371 mutex_unlock(vdev->lock);
372 return res;
373}
374
375static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
376{
377 struct video_device *vdev = video_devdata(file);
378 struct saa7146_fh *fh = file->private_data;
379 int ret;
380
381 switch (vdev->vfl_type) {
382 case VFL_TYPE_GRABBER:
383/*
384 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun",
385 file, data, (unsigned long)count);
386*/
387 return saa7146_video_uops.read(file,data,count,ppos);
388 case VFL_TYPE_VBI:
389/*
390 DEB_EE("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n",
391 file, data, (unsigned long)count);
392*/
393 if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) {
394 if (mutex_lock_interruptible(vdev->lock))
395 return -ERESTARTSYS;
396 ret = saa7146_vbi_uops.read(file, data, count, ppos);
397 mutex_unlock(vdev->lock);
398 return ret;
399 }
400 return -EINVAL;
401 default:
402 BUG();
403 return 0;
404 }
405}
406
407static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
408{
409 struct video_device *vdev = video_devdata(file);
410 struct saa7146_fh *fh = file->private_data;
411 int ret;
412
413 switch (vdev->vfl_type) {
414 case VFL_TYPE_GRABBER:
415 return -EINVAL;
416 case VFL_TYPE_VBI:
417 if (fh->dev->ext_vv_data->vbi_fops.write) {
418 if (mutex_lock_interruptible(vdev->lock))
419 return -ERESTARTSYS;
420 ret = fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
421 mutex_unlock(vdev->lock);
422 return ret;
423 }
424 return -EINVAL;
425 default:
426 BUG();
427 return -EINVAL;
428 }
429}
430
431static const struct v4l2_file_operations video_fops =
432{
433 .owner = THIS_MODULE,
434 .open = fops_open,
435 .release = fops_release,
436 .read = fops_read,
437 .write = fops_write,
438 .poll = fops_poll,
439 .mmap = fops_mmap,
440 .unlocked_ioctl = video_ioctl2,
441};
442
443static void vv_callback(struct saa7146_dev *dev, unsigned long status)
444{
445 u32 isr = status;
446
447 DEB_INT("dev:%p, isr:0x%08x\n", dev, (u32)status);
448
449 if (0 != (isr & (MASK_27))) {
450 DEB_INT("irq: RPS0 (0x%08x)\n", isr);
451 saa7146_video_uops.irq_done(dev,isr);
452 }
453
454 if (0 != (isr & (MASK_28))) {
455 u32 mc2 = saa7146_read(dev, MC2);
456 if( 0 != (mc2 & MASK_15)) {
457 DEB_INT("irq: RPS1 vbi workaround (0x%08x)\n", isr);
458 wake_up(&dev->vv_data->vbi_wq);
459 saa7146_write(dev,MC2, MASK_31);
460 return;
461 }
462 DEB_INT("irq: RPS1 (0x%08x)\n", isr);
463 saa7146_vbi_uops.irq_done(dev,isr);
464 }
465}
466
467static const struct v4l2_ctrl_ops saa7146_ctrl_ops = {
468 .s_ctrl = saa7146_s_ctrl,
469};
470
471int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
472{
473 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
474 struct v4l2_pix_format *fmt;
475 struct v4l2_vbi_format *vbi;
476 struct saa7146_vv *vv;
477 int err;
478
479 err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
480 if (err)
481 return err;
482
483 v4l2_ctrl_handler_init(hdl, 6);
484 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
485 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
486 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
487 V4L2_CID_CONTRAST, 0, 127, 1, 64);
488 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
489 V4L2_CID_SATURATION, 0, 127, 1, 64);
490 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
491 V4L2_CID_VFLIP, 0, 1, 1, 0);
492 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
493 V4L2_CID_HFLIP, 0, 1, 1, 0);
494 if (hdl->error) {
495 err = hdl->error;
496 v4l2_ctrl_handler_free(hdl);
497 return err;
498 }
499 dev->v4l2_dev.ctrl_handler = hdl;
500
501 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
502 if (vv == NULL) {
503 ERR("out of memory. aborting.\n");
504 v4l2_ctrl_handler_free(hdl);
505 return -ENOMEM;
506 }
507 ext_vv->vid_ops = saa7146_video_ioctl_ops;
508 ext_vv->vbi_ops = saa7146_vbi_ioctl_ops;
509 ext_vv->core_ops = &saa7146_video_ioctl_ops;
510
511 DEB_EE("dev:%p\n", dev);
512
513 /* set default values for video parts of the saa7146 */
514 saa7146_write(dev, BCS_CTRL, 0x80400040);
515
516 /* enable video-port pins */
517 saa7146_write(dev, MC1, (MASK_10 | MASK_26));
518
519 /* save per-device extension data (one extension can
520 handle different devices that might need different
521 configuration data) */
522 dev->ext_vv_data = ext_vv;
523
524 vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);
525 if( NULL == vv->d_clipping.cpu_addr ) {
526 ERR("out of memory. aborting.\n");
527 kfree(vv);
528 v4l2_ctrl_handler_free(hdl);
529 return -1;
530 }
531 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
532
533 saa7146_video_uops.init(dev,vv);
534 if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
535 saa7146_vbi_uops.init(dev,vv);
536
537 fmt = &vv->ov_fb.fmt;
538 fmt->width = vv->standard->h_max_out;
539 fmt->height = vv->standard->v_max_out;
540 fmt->pixelformat = V4L2_PIX_FMT_RGB565;
541 fmt->bytesperline = 2 * fmt->width;
542 fmt->sizeimage = fmt->bytesperline * fmt->height;
543 fmt->colorspace = V4L2_COLORSPACE_SRGB;
544
545 fmt = &vv->video_fmt;
546 fmt->width = 384;
547 fmt->height = 288;
548 fmt->pixelformat = V4L2_PIX_FMT_BGR24;
549 fmt->field = V4L2_FIELD_ANY;
550 fmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
551 fmt->bytesperline = 3 * fmt->width;
552 fmt->sizeimage = fmt->bytesperline * fmt->height;
553
554 vbi = &vv->vbi_fmt;
555 vbi->sampling_rate = 27000000;
556 vbi->offset = 248; /* todo */
557 vbi->samples_per_line = 720 * 2;
558 vbi->sample_format = V4L2_PIX_FMT_GREY;
559
560 /* fixme: this only works for PAL */
561 vbi->start[0] = 5;
562 vbi->count[0] = 16;
563 vbi->start[1] = 312;
564 vbi->count[1] = 16;
565
566 init_timer(&vv->vbi_read_timeout);
567
568 vv->ov_fb.capability = V4L2_FBUF_CAP_LIST_CLIPPING;
569 vv->ov_fb.flags = V4L2_FBUF_FLAG_PRIMARY;
570 dev->vv_data = vv;
571 dev->vv_callback = &vv_callback;
572
573 return 0;
574}
575EXPORT_SYMBOL_GPL(saa7146_vv_init);
576
577int saa7146_vv_release(struct saa7146_dev* dev)
578{
579 struct saa7146_vv *vv = dev->vv_data;
580
581 DEB_EE("dev:%p\n", dev);
582
583 v4l2_device_unregister(&dev->v4l2_dev);
584 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
585 v4l2_ctrl_handler_free(&dev->ctrl_handler);
586 kfree(vv);
587 dev->vv_data = NULL;
588 dev->vv_callback = NULL;
589
590 return 0;
591}
592EXPORT_SYMBOL_GPL(saa7146_vv_release);
593
594int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
595 char *name, int type)
596{
597 struct video_device *vfd;
598 int err;
599 int i;
600
601 DEB_EE("dev:%p, name:'%s', type:%d\n", dev, name, type);
602
603 // released by vfd->release
604 vfd = video_device_alloc();
605 if (vfd == NULL)
606 return -ENOMEM;
607
608 vfd->fops = &video_fops;
609 if (type == VFL_TYPE_GRABBER)
610 vfd->ioctl_ops = &dev->ext_vv_data->vid_ops;
611 else
612 vfd->ioctl_ops = &dev->ext_vv_data->vbi_ops;
613 vfd->release = video_device_release;
614 vfd->lock = &dev->v4l2_lock;
615 vfd->v4l2_dev = &dev->v4l2_dev;
616 vfd->tvnorms = 0;
617 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
618 for (i = 0; i < dev->ext_vv_data->num_stds; i++)
619 vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
620 strlcpy(vfd->name, name, sizeof(vfd->name));
621 video_set_drvdata(vfd, dev);
622
623 err = video_register_device(vfd, type, -1);
624 if (err < 0) {
625 ERR("cannot register v4l2 device. skipping.\n");
626 video_device_release(vfd);
627 return err;
628 }
629
630 pr_info("%s: registered device %s [v4l2]\n",
631 dev->name, video_device_node_name(vfd));
632
633 *vid = vfd;
634 return 0;
635}
636EXPORT_SYMBOL_GPL(saa7146_register_device);
637
638int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
639{
640 DEB_EE("dev:%p\n", dev);
641
642 video_unregister_device(*vid);
643 *vid = NULL;
644
645 return 0;
646}
647EXPORT_SYMBOL_GPL(saa7146_unregister_device);
648
649static int __init saa7146_vv_init_module(void)
650{
651 return 0;
652}
653
654
655static void __exit saa7146_vv_cleanup_module(void)
656{
657}
658
659module_init(saa7146_vv_init_module);
660module_exit(saa7146_vv_cleanup_module);
661
662MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
663MODULE_DESCRIPTION("video4linux driver for saa7146-based hardware");
664MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/saa7146/saa7146_hlp.c b/drivers/media/common/saa7146/saa7146_hlp.c
deleted file mode 100644
index be746d1aee9..00000000000
--- a/drivers/media/common/saa7146/saa7146_hlp.c
+++ /dev/null
@@ -1,1048 +0,0 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
3#include <linux/kernel.h>
4#include <linux/export.h>
5#include <media/saa7146_vv.h>
6
7static void calculate_output_format_register(struct saa7146_dev* saa, u32 palette, u32* clip_format)
8{
9 /* clear out the necessary bits */
10 *clip_format &= 0x0000ffff;
11 /* set these bits new */
12 *clip_format |= (( ((palette&0xf00)>>8) << 30) | ((palette&0x00f) << 24) | (((palette&0x0f0)>>4) << 16));
13}
14
15static void calculate_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync, u32* hps_ctrl)
16{
17 *hps_ctrl &= ~(MASK_30 | MASK_31 | MASK_28);
18 *hps_ctrl |= (source << 30) | (sync << 28);
19}
20
21static void calculate_hxo_and_hyo(struct saa7146_vv *vv, u32* hps_h_scale, u32* hps_ctrl)
22{
23 int hyo = 0, hxo = 0;
24
25 hyo = vv->standard->v_offset;
26 hxo = vv->standard->h_offset;
27
28 *hps_h_scale &= ~(MASK_B0 | 0xf00);
29 *hps_h_scale |= (hxo << 0);
30
31 *hps_ctrl &= ~(MASK_W0 | MASK_B2);
32 *hps_ctrl |= (hyo << 12);
33}
34
35/* helper functions for the calculation of the horizontal- and vertical
36 scaling registers, clip-format-register etc ...
37 these functions take pointers to the (most-likely read-out
38 original-values) and manipulate them according to the requested
39 changes.
40*/
41
42/* hps_coeff used for CXY and CXUV; scale 1/1 -> scale 1/64 */
43static struct {
44 u16 hps_coeff;
45 u16 weight_sum;
46} hps_h_coeff_tab [] = {
47 {0x00, 2}, {0x02, 4}, {0x00, 4}, {0x06, 8}, {0x02, 8},
48 {0x08, 8}, {0x00, 8}, {0x1E, 16}, {0x0E, 8}, {0x26, 8},
49 {0x06, 8}, {0x42, 8}, {0x02, 8}, {0x80, 8}, {0x00, 8},
50 {0xFE, 16}, {0xFE, 8}, {0x7E, 8}, {0x7E, 8}, {0x3E, 8},
51 {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, {0x0E, 8}, {0x0E, 8},
52 {0x06, 8}, {0x06, 8}, {0x02, 8}, {0x02, 8}, {0x00, 8},
53 {0x00, 8}, {0xFE, 16}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
54 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
55 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8},
56 {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0x7E, 8},
57 {0x7E, 8}, {0x3E, 8}, {0x3E, 8}, {0x1E, 8}, {0x1E, 8},
58 {0x0E, 8}, {0x0E, 8}, {0x06, 8}, {0x06, 8}, {0x02, 8},
59 {0x02, 8}, {0x00, 8}, {0x00, 8}, {0xFE, 16}
60};
61
62/* table of attenuation values for horizontal scaling */
63static u8 h_attenuation[] = { 1, 2, 4, 8, 2, 4, 8, 16, 0};
64
65/* calculate horizontal scale registers */
66static int calculate_h_scale_registers(struct saa7146_dev *dev,
67 int in_x, int out_x, int flip_lr,
68 u32* hps_ctrl, u32* hps_v_gain, u32* hps_h_prescale, u32* hps_h_scale)
69{
70 /* horizontal prescaler */
71 u32 dcgx = 0, xpsc = 0, xacm = 0, cxy = 0, cxuv = 0;
72 /* horizontal scaler */
73 u32 xim = 0, xp = 0, xsci =0;
74 /* vertical scale & gain */
75 u32 pfuv = 0;
76
77 /* helper variables */
78 u32 h_atten = 0, i = 0;
79
80 if ( 0 == out_x ) {
81 return -EINVAL;
82 }
83
84 /* mask out vanity-bit */
85 *hps_ctrl &= ~MASK_29;
86
87 /* calculate prescale-(xspc)-value: [n .. 1/2) : 1
88 [1/2 .. 1/3) : 2
89 [1/3 .. 1/4) : 3
90 ... */
91 if (in_x > out_x) {
92 xpsc = in_x / out_x;
93 }
94 else {
95 /* zooming */
96 xpsc = 1;
97 }
98
99 /* if flip_lr-bit is set, number of pixels after
100 horizontal prescaling must be < 384 */
101 if ( 0 != flip_lr ) {
102
103 /* set vanity bit */
104 *hps_ctrl |= MASK_29;
105
106 while (in_x / xpsc >= 384 )
107 xpsc++;
108 }
109 /* if zooming is wanted, number of pixels after
110 horizontal prescaling must be < 768 */
111 else {
112 while ( in_x / xpsc >= 768 )
113 xpsc++;
114 }
115
116 /* maximum prescale is 64 (p.69) */
117 if ( xpsc > 64 )
118 xpsc = 64;
119
120 /* keep xacm clear*/
121 xacm = 0;
122
123 /* set horizontal filter parameters (CXY = CXUV) */
124 cxy = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].hps_coeff;
125 cxuv = cxy;
126
127 /* calculate and set horizontal fine scale (xsci) */
128
129 /* bypass the horizontal scaler ? */
130 if ( (in_x == out_x) && ( 1 == xpsc ) )
131 xsci = 0x400;
132 else
133 xsci = ( (1024 * in_x) / (out_x * xpsc) ) + xpsc;
134
135 /* set start phase for horizontal fine scale (xp) to 0 */
136 xp = 0;
137
138 /* set xim, if we bypass the horizontal scaler */
139 if ( 0x400 == xsci )
140 xim = 1;
141 else
142 xim = 0;
143
144 /* if the prescaler is bypassed, enable horizontal
145 accumulation mode (xacm) and clear dcgx */
146 if( 1 == xpsc ) {
147 xacm = 1;
148 dcgx = 0;
149 } else {
150 xacm = 0;
151 /* get best match in the table of attenuations
152 for horizontal scaling */
153 h_atten = hps_h_coeff_tab[( (xpsc - 1) < 63 ? (xpsc - 1) : 63 )].weight_sum;
154
155 for (i = 0; h_attenuation[i] != 0; i++) {
156 if (h_attenuation[i] >= h_atten)
157 break;
158 }
159
160 dcgx = i;
161 }
162
163 /* the horizontal scaling increment controls the UV filter
164 to reduce the bandwidth to improve the display quality,
165 so set it ... */
166 if ( xsci == 0x400)
167 pfuv = 0x00;
168 else if ( xsci < 0x600)
169 pfuv = 0x01;
170 else if ( xsci < 0x680)
171 pfuv = 0x11;
172 else if ( xsci < 0x700)
173 pfuv = 0x22;
174 else
175 pfuv = 0x33;
176
177
178 *hps_v_gain &= MASK_W0|MASK_B2;
179 *hps_v_gain |= (pfuv << 24);
180
181 *hps_h_scale &= ~(MASK_W1 | 0xf000);
182 *hps_h_scale |= (xim << 31) | (xp << 24) | (xsci << 12);
183
184 *hps_h_prescale |= (dcgx << 27) | ((xpsc-1) << 18) | (xacm << 17) | (cxy << 8) | (cxuv << 0);
185
186 return 0;
187}
188
189static struct {
190 u16 hps_coeff;
191 u16 weight_sum;
192} hps_v_coeff_tab [] = {
193 {0x0100, 2}, {0x0102, 4}, {0x0300, 4}, {0x0106, 8}, {0x0502, 8},
194 {0x0708, 8}, {0x0F00, 8}, {0x011E, 16}, {0x110E, 16}, {0x1926, 16},
195 {0x3906, 16}, {0x3D42, 16}, {0x7D02, 16}, {0x7F80, 16}, {0xFF00, 16},
196 {0x01FE, 32}, {0x01FE, 32}, {0x817E, 32}, {0x817E, 32}, {0xC13E, 32},
197 {0xC13E, 32}, {0xE11E, 32}, {0xE11E, 32}, {0xF10E, 32}, {0xF10E, 32},
198 {0xF906, 32}, {0xF906, 32}, {0xFD02, 32}, {0xFD02, 32}, {0xFF00, 32},
199 {0xFF00, 32}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
200 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
201 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64},
202 {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x817E, 64},
203 {0x817E, 64}, {0xC13E, 64}, {0xC13E, 64}, {0xE11E, 64}, {0xE11E, 64},
204 {0xF10E, 64}, {0xF10E, 64}, {0xF906, 64}, {0xF906, 64}, {0xFD02, 64},
205 {0xFD02, 64}, {0xFF00, 64}, {0xFF00, 64}, {0x01FE, 128}
206};
207
208/* table of attenuation values for vertical scaling */
209static u16 v_attenuation[] = { 2, 4, 8, 16, 32, 64, 128, 256, 0};
210
211/* calculate vertical scale registers */
212static int calculate_v_scale_registers(struct saa7146_dev *dev, enum v4l2_field field,
213 int in_y, int out_y, u32* hps_v_scale, u32* hps_v_gain)
214{
215 int lpi = 0;
216
217 /* vertical scaling */
218 u32 yacm = 0, ysci = 0, yacl = 0, ypo = 0, ype = 0;
219 /* vertical scale & gain */
220 u32 dcgy = 0, cya_cyb = 0;
221
222 /* helper variables */
223 u32 v_atten = 0, i = 0;
224
225 /* error, if vertical zooming */
226 if ( in_y < out_y ) {
227 return -EINVAL;
228 }
229
230 /* linear phase interpolation may be used
231 if scaling is between 1 and 1/2 (both fields used)
232 or scaling is between 1/2 and 1/4 (if only one field is used) */
233
234 if (V4L2_FIELD_HAS_BOTH(field)) {
235 if( 2*out_y >= in_y) {
236 lpi = 1;
237 }
238 } else if (field == V4L2_FIELD_TOP
239 || field == V4L2_FIELD_ALTERNATE
240 || field == V4L2_FIELD_BOTTOM) {
241 if( 4*out_y >= in_y ) {
242 lpi = 1;
243 }
244 out_y *= 2;
245 }
246 if( 0 != lpi ) {
247
248 yacm = 0;
249 yacl = 0;
250 cya_cyb = 0x00ff;
251
252 /* calculate scaling increment */
253 if ( in_y > out_y )
254 ysci = ((1024 * in_y) / (out_y + 1)) - 1024;
255 else
256 ysci = 0;
257
258 dcgy = 0;
259
260 /* calculate ype and ypo */
261 ype = ysci / 16;
262 ypo = ype + (ysci / 64);
263
264 } else {
265 yacm = 1;
266
267 /* calculate scaling increment */
268 ysci = (((10 * 1024 * (in_y - out_y - 1)) / in_y) + 9) / 10;
269
270 /* calculate ype and ypo */
271 ypo = ype = ((ysci + 15) / 16);
272
273 /* the sequence length interval (yacl) has to be set according
274 to the prescale value, e.g. [n .. 1/2) : 0
275 [1/2 .. 1/3) : 1
276 [1/3 .. 1/4) : 2
277 ... */
278 if ( ysci < 512) {
279 yacl = 0;
280 } else {
281 yacl = ( ysci / (1024 - ysci) );
282 }
283
284 /* get filter coefficients for cya, cyb from table hps_v_coeff_tab */
285 cya_cyb = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].hps_coeff;
286
287 /* get best match in the table of attenuations for vertical scaling */
288 v_atten = hps_v_coeff_tab[ (yacl < 63 ? yacl : 63 ) ].weight_sum;
289
290 for (i = 0; v_attenuation[i] != 0; i++) {
291 if (v_attenuation[i] >= v_atten)
292 break;
293 }
294
295 dcgy = i;
296 }
297
298 /* ypo and ype swapped in spec ? */
299 *hps_v_scale |= (yacm << 31) | (ysci << 21) | (yacl << 15) | (ypo << 8 ) | (ype << 1);
300
301 *hps_v_gain &= ~(MASK_W0|MASK_B2);
302 *hps_v_gain |= (dcgy << 16) | (cya_cyb << 0);
303
304 return 0;
305}
306
307/* simple bubble-sort algorithm with duplicate elimination */
308static int sort_and_eliminate(u32* values, int* count)
309{
310 int low = 0, high = 0, top = 0, temp = 0;
311 int cur = 0, next = 0;
312
313 /* sanity checks */
314 if( (0 > *count) || (NULL == values) ) {
315 return -EINVAL;
316 }
317
318 /* bubble sort the first @count items of the array @values */
319 for( top = *count; top > 0; top--) {
320 for( low = 0, high = 1; high < top; low++, high++) {
321 if( values[low] > values[high] ) {
322 temp = values[low];
323 values[low] = values[high];
324 values[high] = temp;
325 }
326 }
327 }
328
329 /* remove duplicate items */
330 for( cur = 0, next = 1; next < *count; next++) {
331 if( values[cur] != values[next])
332 values[++cur] = values[next];
333 }
334
335 *count = cur + 1;
336
337 return 0;
338}
339
340static void calculate_clipping_registers_rect(struct saa7146_dev *dev, struct saa7146_fh *fh,
341 struct saa7146_video_dma *vdma2, u32* clip_format, u32* arbtr_ctrl, enum v4l2_field field)
342{
343 struct saa7146_vv *vv = dev->vv_data;
344 __le32 *clipping = vv->d_clipping.cpu_addr;
345
346 int width = vv->ov.win.w.width;
347 int height = vv->ov.win.w.height;
348 int clipcount = vv->ov.nclips;
349
350 u32 line_list[32];
351 u32 pixel_list[32];
352 int numdwords = 0;
353
354 int i = 0, j = 0;
355 int cnt_line = 0, cnt_pixel = 0;
356
357 int x[32], y[32], w[32], h[32];
358
359 /* clear out memory */
360 memset(&line_list[0], 0x00, sizeof(u32)*32);
361 memset(&pixel_list[0], 0x00, sizeof(u32)*32);
362 memset(clipping, 0x00, SAA7146_CLIPPING_MEM);
363
364 /* fill the line and pixel-lists */
365 for(i = 0; i < clipcount; i++) {
366 int l = 0, r = 0, t = 0, b = 0;
367
368 x[i] = vv->ov.clips[i].c.left;
369 y[i] = vv->ov.clips[i].c.top;
370 w[i] = vv->ov.clips[i].c.width;
371 h[i] = vv->ov.clips[i].c.height;
372
373 if( w[i] < 0) {
374 x[i] += w[i]; w[i] = -w[i];
375 }
376 if( h[i] < 0) {
377 y[i] += h[i]; h[i] = -h[i];
378 }
379 if( x[i] < 0) {
380 w[i] += x[i]; x[i] = 0;
381 }
382 if( y[i] < 0) {
383 h[i] += y[i]; y[i] = 0;
384 }
385 if( 0 != vv->vflip ) {
386 y[i] = height - y[i] - h[i];
387 }
388
389 l = x[i];
390 r = x[i]+w[i];
391 t = y[i];
392 b = y[i]+h[i];
393
394 /* insert left/right coordinates */
395 pixel_list[ 2*i ] = min_t(int, l, width);
396 pixel_list[(2*i)+1] = min_t(int, r, width);
397 /* insert top/bottom coordinates */
398 line_list[ 2*i ] = min_t(int, t, height);
399 line_list[(2*i)+1] = min_t(int, b, height);
400 }
401
402 /* sort and eliminate lists */
403 cnt_line = cnt_pixel = 2*clipcount;
404 sort_and_eliminate( &pixel_list[0], &cnt_pixel );
405 sort_and_eliminate( &line_list[0], &cnt_line );
406
407 /* calculate the number of used u32s */
408 numdwords = max_t(int, (cnt_line+1), (cnt_pixel+1))*2;
409 numdwords = max_t(int, 4, numdwords);
410 numdwords = min_t(int, 64, numdwords);
411
412 /* fill up cliptable */
413 for(i = 0; i < cnt_pixel; i++) {
414 clipping[2*i] |= cpu_to_le32(pixel_list[i] << 16);
415 }
416 for(i = 0; i < cnt_line; i++) {
417 clipping[(2*i)+1] |= cpu_to_le32(line_list[i] << 16);
418 }
419
420 /* fill up cliptable with the display infos */
421 for(j = 0; j < clipcount; j++) {
422
423 for(i = 0; i < cnt_pixel; i++) {
424
425 if( x[j] < 0)
426 x[j] = 0;
427
428 if( pixel_list[i] < (x[j] + w[j])) {
429
430 if ( pixel_list[i] >= x[j] ) {
431 clipping[2*i] |= cpu_to_le32(1 << j);
432 }
433 }
434 }
435 for(i = 0; i < cnt_line; i++) {
436
437 if( y[j] < 0)
438 y[j] = 0;
439
440 if( line_list[i] < (y[j] + h[j]) ) {
441
442 if( line_list[i] >= y[j] ) {
443 clipping[(2*i)+1] |= cpu_to_le32(1 << j);
444 }
445 }
446 }
447 }
448
449 /* adjust arbitration control register */
450 *arbtr_ctrl &= 0xffff00ff;
451 *arbtr_ctrl |= 0x00001c00;
452
453 vdma2->base_even = vv->d_clipping.dma_handle;
454 vdma2->base_odd = vv->d_clipping.dma_handle;
455 vdma2->prot_addr = vv->d_clipping.dma_handle+((sizeof(u32))*(numdwords));
456 vdma2->base_page = 0x04;
457 vdma2->pitch = 0x00;
458 vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) );
459
460 /* set clipping-mode. this depends on the field(s) used */
461 *clip_format &= 0xfffffff7;
462 if (V4L2_FIELD_HAS_BOTH(field)) {
463 *clip_format |= 0x00000008;
464 } else {
465 *clip_format |= 0x00000000;
466 }
467}
468
469/* disable clipping */
470static void saa7146_disable_clipping(struct saa7146_dev *dev)
471{
472 u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
473
474 /* mask out relevant bits (=lower word)*/
475 clip_format &= MASK_W1;
476
477 /* upload clipping-registers*/
478 saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
479 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
480
481 /* disable video dma2 */
482 saa7146_write(dev, MC1, MASK_21);
483}
484
485static void saa7146_set_clipping_rect(struct saa7146_fh *fh)
486{
487 struct saa7146_dev *dev = fh->dev;
488 struct saa7146_vv *vv = dev->vv_data;
489 enum v4l2_field field = vv->ov.win.field;
490 struct saa7146_video_dma vdma2;
491 u32 clip_format;
492 u32 arbtr_ctrl;
493
494 /* check clipcount, disable clipping if clipcount == 0*/
495 if (vv->ov.nclips == 0) {
496 saa7146_disable_clipping(dev);
497 return;
498 }
499
500 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
501 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
502
503 calculate_clipping_registers_rect(dev, fh, &vdma2, &clip_format, &arbtr_ctrl, field);
504
505 /* set clipping format */
506 clip_format &= 0xffff0008;
507 clip_format |= (SAA7146_CLIPPING_RECT << 4);
508
509 /* prepare video dma2 */
510 saa7146_write(dev, BASE_EVEN2, vdma2.base_even);
511 saa7146_write(dev, BASE_ODD2, vdma2.base_odd);
512 saa7146_write(dev, PROT_ADDR2, vdma2.prot_addr);
513 saa7146_write(dev, BASE_PAGE2, vdma2.base_page);
514 saa7146_write(dev, PITCH2, vdma2.pitch);
515 saa7146_write(dev, NUM_LINE_BYTE2, vdma2.num_line_byte);
516
517 /* prepare the rest */
518 saa7146_write(dev, CLIP_FORMAT_CTRL,clip_format);
519 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
520
521 /* upload clip_control-register, clipping-registers, enable video dma2 */
522 saa7146_write(dev, MC2, (MASK_05 | MASK_21 | MASK_03 | MASK_19));
523 saa7146_write(dev, MC1, (MASK_05 | MASK_21));
524}
525
526static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, enum v4l2_field field)
527{
528 struct saa7146_vv *vv = dev->vv_data;
529
530 int source = vv->current_hps_source;
531 int sync = vv->current_hps_sync;
532
533 u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0;
534
535 /* set vertical scale */
536 hps_v_scale = 0; /* all bits get set by the function-call */
537 hps_v_gain = 0; /* fixme: saa7146_read(dev, HPS_V_GAIN);*/
538 calculate_v_scale_registers(dev, field, vv->standard->v_field*2, height, &hps_v_scale, &hps_v_gain);
539
540 /* set horizontal scale */
541 hps_ctrl = 0;
542 hps_h_prescale = 0; /* all bits get set in the function */
543 hps_h_scale = 0;
544 calculate_h_scale_registers(dev, vv->standard->h_pixels, width, vv->hflip, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale);
545
546 /* set hyo and hxo */
547 calculate_hxo_and_hyo(vv, &hps_h_scale, &hps_ctrl);
548 calculate_hps_source_and_sync(dev, source, sync, &hps_ctrl);
549
550 /* write out new register contents */
551 saa7146_write(dev, HPS_V_SCALE, hps_v_scale);
552 saa7146_write(dev, HPS_V_GAIN, hps_v_gain);
553 saa7146_write(dev, HPS_CTRL, hps_ctrl);
554 saa7146_write(dev, HPS_H_PRESCALE,hps_h_prescale);
555 saa7146_write(dev, HPS_H_SCALE, hps_h_scale);
556
557 /* upload shadow-ram registers */
558 saa7146_write(dev, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) );
559}
560
561/* calculate the new memory offsets for a desired position */
562static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat)
563{
564 struct saa7146_vv *vv = dev->vv_data;
565 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat);
566
567 int b_depth = vv->ov_fmt->depth;
568 int b_bpl = vv->ov_fb.fmt.bytesperline;
569 /* The unsigned long cast is to remove a 64-bit compile warning since
570 it looks like a 64-bit address is cast to a 32-bit value, even
571 though the base pointer is really a 32-bit physical address that
572 goes into a 32-bit DMA register.
573 FIXME: might not work on some 64-bit platforms, but see the FIXME
574 in struct v4l2_framebuffer (videodev2.h) for that.
575 */
576 u32 base = (u32)(unsigned long)vv->ov_fb.base;
577
578 struct saa7146_video_dma vdma1;
579
580 /* calculate memory offsets for picture, look if we shall top-down-flip */
581 vdma1.pitch = 2*b_bpl;
582 if ( 0 == vv->vflip ) {
583 vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
584 vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2);
585 vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2));
586 }
587 else {
588 vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8));
589 vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2);
590 vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2));
591 }
592
593 if (V4L2_FIELD_HAS_BOTH(field)) {
594 } else if (field == V4L2_FIELD_ALTERNATE) {
595 /* fixme */
596 vdma1.base_odd = vdma1.prot_addr;
597 vdma1.pitch /= 2;
598 } else if (field == V4L2_FIELD_TOP) {
599 vdma1.base_odd = vdma1.prot_addr;
600 vdma1.pitch /= 2;
601 } else if (field == V4L2_FIELD_BOTTOM) {
602 vdma1.base_odd = vdma1.base_even;
603 vdma1.base_even = vdma1.prot_addr;
604 vdma1.pitch /= 2;
605 }
606
607 if ( 0 != vv->vflip ) {
608 vdma1.pitch *= -1;
609 }
610
611 vdma1.base_page = sfmt->swap;
612 vdma1.num_line_byte = (vv->standard->v_field<<16)+vv->standard->h_pixels;
613
614 saa7146_write_out_dma(dev, 1, &vdma1);
615}
616
617static void saa7146_set_output_format(struct saa7146_dev *dev, unsigned long palette)
618{
619 u32 clip_format = saa7146_read(dev, CLIP_FORMAT_CTRL);
620
621 /* call helper function */
622 calculate_output_format_register(dev,palette,&clip_format);
623
624 /* update the hps registers */
625 saa7146_write(dev, CLIP_FORMAT_CTRL, clip_format);
626 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
627}
628
629/* select input-source */
630void saa7146_set_hps_source_and_sync(struct saa7146_dev *dev, int source, int sync)
631{
632 struct saa7146_vv *vv = dev->vv_data;
633 u32 hps_ctrl = 0;
634
635 /* read old state */
636 hps_ctrl = saa7146_read(dev, HPS_CTRL);
637
638 hps_ctrl &= ~( MASK_31 | MASK_30 | MASK_28 );
639 hps_ctrl |= (source << 30) | (sync << 28);
640
641 /* write back & upload register */
642 saa7146_write(dev, HPS_CTRL, hps_ctrl);
643 saa7146_write(dev, MC2, (MASK_05 | MASK_21));
644
645 vv->current_hps_source = source;
646 vv->current_hps_sync = sync;
647}
648EXPORT_SYMBOL_GPL(saa7146_set_hps_source_and_sync);
649
650int saa7146_enable_overlay(struct saa7146_fh *fh)
651{
652 struct saa7146_dev *dev = fh->dev;
653 struct saa7146_vv *vv = dev->vv_data;
654
655 saa7146_set_window(dev, vv->ov.win.w.width, vv->ov.win.w.height, vv->ov.win.field);
656 saa7146_set_position(dev, vv->ov.win.w.left, vv->ov.win.w.top, vv->ov.win.w.height, vv->ov.win.field, vv->ov_fmt->pixelformat);
657 saa7146_set_output_format(dev, vv->ov_fmt->trans);
658 saa7146_set_clipping_rect(fh);
659
660 /* enable video dma1 */
661 saa7146_write(dev, MC1, (MASK_06 | MASK_22));
662 return 0;
663}
664
665void saa7146_disable_overlay(struct saa7146_fh *fh)
666{
667 struct saa7146_dev *dev = fh->dev;
668
669 /* disable clipping + video dma1 */
670 saa7146_disable_clipping(dev);
671 saa7146_write(dev, MC1, MASK_22);
672}
673
674void saa7146_write_out_dma(struct saa7146_dev* dev, int which, struct saa7146_video_dma* vdma)
675{
676 int where = 0;
677
678 if( which < 1 || which > 3) {
679 return;
680 }
681
682 /* calculate starting address */
683 where = (which-1)*0x18;
684
685 saa7146_write(dev, where, vdma->base_odd);
686 saa7146_write(dev, where+0x04, vdma->base_even);
687 saa7146_write(dev, where+0x08, vdma->prot_addr);
688 saa7146_write(dev, where+0x0c, vdma->pitch);
689 saa7146_write(dev, where+0x10, vdma->base_page);
690 saa7146_write(dev, where+0x14, vdma->num_line_byte);
691
692 /* upload */
693 saa7146_write(dev, MC2, (MASK_02<<(which-1))|(MASK_18<<(which-1)));
694/*
695 printk("vdma%d.base_even: 0x%08x\n", which,vdma->base_even);
696 printk("vdma%d.base_odd: 0x%08x\n", which,vdma->base_odd);
697 printk("vdma%d.prot_addr: 0x%08x\n", which,vdma->prot_addr);
698 printk("vdma%d.base_page: 0x%08x\n", which,vdma->base_page);
699 printk("vdma%d.pitch: 0x%08x\n", which,vdma->pitch);
700 printk("vdma%d.num_line_byte: 0x%08x\n", which,vdma->num_line_byte);
701*/
702}
703
704static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa7146_buf *buf)
705{
706 struct saa7146_vv *vv = dev->vv_data;
707 struct saa7146_video_dma vdma1;
708
709 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
710
711 int width = buf->fmt->width;
712 int height = buf->fmt->height;
713 int bytesperline = buf->fmt->bytesperline;
714 enum v4l2_field field = buf->fmt->field;
715
716 int depth = sfmt->depth;
717
718 DEB_CAP("[size=%dx%d,fields=%s]\n",
719 width, height, v4l2_field_names[field]);
720
721 if( bytesperline != 0) {
722 vdma1.pitch = bytesperline*2;
723 } else {
724 vdma1.pitch = (width*depth*2)/8;
725 }
726 vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
727 vdma1.base_page = buf->pt[0].dma | ME1 | sfmt->swap;
728
729 if( 0 != vv->vflip ) {
730 vdma1.prot_addr = buf->pt[0].offset;
731 vdma1.base_even = buf->pt[0].offset+(vdma1.pitch/2)*height;
732 vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
733 } else {
734 vdma1.base_even = buf->pt[0].offset;
735 vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2);
736 vdma1.prot_addr = buf->pt[0].offset+(vdma1.pitch/2)*height;
737 }
738
739 if (V4L2_FIELD_HAS_BOTH(field)) {
740 } else if (field == V4L2_FIELD_ALTERNATE) {
741 /* fixme */
742 if ( vv->last_field == V4L2_FIELD_TOP ) {
743 vdma1.base_odd = vdma1.prot_addr;
744 vdma1.pitch /= 2;
745 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
746 vdma1.base_odd = vdma1.base_even;
747 vdma1.base_even = vdma1.prot_addr;
748 vdma1.pitch /= 2;
749 }
750 } else if (field == V4L2_FIELD_TOP) {
751 vdma1.base_odd = vdma1.prot_addr;
752 vdma1.pitch /= 2;
753 } else if (field == V4L2_FIELD_BOTTOM) {
754 vdma1.base_odd = vdma1.base_even;
755 vdma1.base_even = vdma1.prot_addr;
756 vdma1.pitch /= 2;
757 }
758
759 if( 0 != vv->vflip ) {
760 vdma1.pitch *= -1;
761 }
762
763 saa7146_write_out_dma(dev, 1, &vdma1);
764 return 0;
765}
766
767static int calc_planar_422(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
768{
769 int height = buf->fmt->height;
770 int width = buf->fmt->width;
771
772 vdma2->pitch = width;
773 vdma3->pitch = width;
774
775 /* fixme: look at bytesperline! */
776
777 if( 0 != vv->vflip ) {
778 vdma2->prot_addr = buf->pt[1].offset;
779 vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[1].offset;
780 vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2);
781
782 vdma3->prot_addr = buf->pt[2].offset;
783 vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[2].offset;
784 vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2);
785 } else {
786 vdma3->base_even = buf->pt[2].offset;
787 vdma3->base_odd = vdma3->base_even + (vdma3->pitch/2);
788 vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset;
789
790 vdma2->base_even = buf->pt[1].offset;
791 vdma2->base_odd = vdma2->base_even + (vdma2->pitch/2);
792 vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset;
793 }
794
795 return 0;
796}
797
798static int calc_planar_420(struct saa7146_vv *vv, struct saa7146_buf *buf, struct saa7146_video_dma *vdma2, struct saa7146_video_dma *vdma3)
799{
800 int height = buf->fmt->height;
801 int width = buf->fmt->width;
802
803 vdma2->pitch = width/2;
804 vdma3->pitch = width/2;
805
806 if( 0 != vv->vflip ) {
807 vdma2->prot_addr = buf->pt[2].offset;
808 vdma2->base_even = ((vdma2->pitch/2)*height)+buf->pt[2].offset;
809 vdma2->base_odd = vdma2->base_even - (vdma2->pitch/2);
810
811 vdma3->prot_addr = buf->pt[1].offset;
812 vdma3->base_even = ((vdma3->pitch/2)*height)+buf->pt[1].offset;
813 vdma3->base_odd = vdma3->base_even - (vdma3->pitch/2);
814
815 } else {
816 vdma3->base_even = buf->pt[2].offset;
817 vdma3->base_odd = vdma3->base_even + (vdma3->pitch);
818 vdma3->prot_addr = (vdma3->pitch/2)*height+buf->pt[2].offset;
819
820 vdma2->base_even = buf->pt[1].offset;
821 vdma2->base_odd = vdma2->base_even + (vdma2->pitch);
822 vdma2->prot_addr = (vdma2->pitch/2)*height+buf->pt[1].offset;
823 }
824 return 0;
825}
826
827static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa7146_buf *buf)
828{
829 struct saa7146_vv *vv = dev->vv_data;
830 struct saa7146_video_dma vdma1;
831 struct saa7146_video_dma vdma2;
832 struct saa7146_video_dma vdma3;
833
834 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
835
836 int width = buf->fmt->width;
837 int height = buf->fmt->height;
838 enum v4l2_field field = buf->fmt->field;
839
840 BUG_ON(0 == buf->pt[0].dma);
841 BUG_ON(0 == buf->pt[1].dma);
842 BUG_ON(0 == buf->pt[2].dma);
843
844 DEB_CAP("[size=%dx%d,fields=%s]\n",
845 width, height, v4l2_field_names[field]);
846
847 /* fixme: look at bytesperline! */
848
849 /* fixme: what happens for user space buffers here?. The offsets are
850 most likely wrong, this version here only works for page-aligned
851 buffers, modifications to the pagetable-functions are necessary...*/
852
853 vdma1.pitch = width*2;
854 vdma1.num_line_byte = ((vv->standard->v_field<<16) + vv->standard->h_pixels);
855 vdma1.base_page = buf->pt[0].dma | ME1;
856
857 if( 0 != vv->vflip ) {
858 vdma1.prot_addr = buf->pt[0].offset;
859 vdma1.base_even = ((vdma1.pitch/2)*height)+buf->pt[0].offset;
860 vdma1.base_odd = vdma1.base_even - (vdma1.pitch/2);
861 } else {
862 vdma1.base_even = buf->pt[0].offset;
863 vdma1.base_odd = vdma1.base_even + (vdma1.pitch/2);
864 vdma1.prot_addr = (vdma1.pitch/2)*height+buf->pt[0].offset;
865 }
866
867 vdma2.num_line_byte = 0; /* unused */
868 vdma2.base_page = buf->pt[1].dma | ME1;
869
870 vdma3.num_line_byte = 0; /* unused */
871 vdma3.base_page = buf->pt[2].dma | ME1;
872
873 switch( sfmt->depth ) {
874 case 12: {
875 calc_planar_420(vv,buf,&vdma2,&vdma3);
876 break;
877 }
878 case 16: {
879 calc_planar_422(vv,buf,&vdma2,&vdma3);
880 break;
881 }
882 default: {
883 return -1;
884 }
885 }
886
887 if (V4L2_FIELD_HAS_BOTH(field)) {
888 } else if (field == V4L2_FIELD_ALTERNATE) {
889 /* fixme */
890 vdma1.base_odd = vdma1.prot_addr;
891 vdma1.pitch /= 2;
892 vdma2.base_odd = vdma2.prot_addr;
893 vdma2.pitch /= 2;
894 vdma3.base_odd = vdma3.prot_addr;
895 vdma3.pitch /= 2;
896 } else if (field == V4L2_FIELD_TOP) {
897 vdma1.base_odd = vdma1.prot_addr;
898 vdma1.pitch /= 2;
899 vdma2.base_odd = vdma2.prot_addr;
900 vdma2.pitch /= 2;
901 vdma3.base_odd = vdma3.prot_addr;
902 vdma3.pitch /= 2;
903 } else if (field == V4L2_FIELD_BOTTOM) {
904 vdma1.base_odd = vdma1.base_even;
905 vdma1.base_even = vdma1.prot_addr;
906 vdma1.pitch /= 2;
907 vdma2.base_odd = vdma2.base_even;
908 vdma2.base_even = vdma2.prot_addr;
909 vdma2.pitch /= 2;
910 vdma3.base_odd = vdma3.base_even;
911 vdma3.base_even = vdma3.prot_addr;
912 vdma3.pitch /= 2;
913 }
914
915 if( 0 != vv->vflip ) {
916 vdma1.pitch *= -1;
917 vdma2.pitch *= -1;
918 vdma3.pitch *= -1;
919 }
920
921 saa7146_write_out_dma(dev, 1, &vdma1);
922 if( (sfmt->flags & FORMAT_BYTE_SWAP) != 0 ) {
923 saa7146_write_out_dma(dev, 3, &vdma2);
924 saa7146_write_out_dma(dev, 2, &vdma3);
925 } else {
926 saa7146_write_out_dma(dev, 2, &vdma2);
927 saa7146_write_out_dma(dev, 3, &vdma3);
928 }
929 return 0;
930}
931
932static void program_capture_engine(struct saa7146_dev *dev, int planar)
933{
934 struct saa7146_vv *vv = dev->vv_data;
935 int count = 0;
936
937 unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
938 unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
939
940 /* wait for o_fid_a/b / e_fid_a/b toggle only if rps register 0 is not set*/
941 WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | o_wait);
942 WRITE_RPS0(CMD_PAUSE | CMD_OAN | CMD_SIG0 | e_wait);
943
944 /* set rps register 0 */
945 WRITE_RPS0(CMD_WR_REG | (1 << 8) | (MC2/4));
946 WRITE_RPS0(MASK_27 | MASK_11);
947
948 /* turn on video-dma1 */
949 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
950 WRITE_RPS0(MASK_06 | MASK_22); /* => mask */
951 WRITE_RPS0(MASK_06 | MASK_22); /* => values */
952 if( 0 != planar ) {
953 /* turn on video-dma2 */
954 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
955 WRITE_RPS0(MASK_05 | MASK_21); /* => mask */
956 WRITE_RPS0(MASK_05 | MASK_21); /* => values */
957
958 /* turn on video-dma3 */
959 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
960 WRITE_RPS0(MASK_04 | MASK_20); /* => mask */
961 WRITE_RPS0(MASK_04 | MASK_20); /* => values */
962 }
963
964 /* wait for o_fid_a/b / e_fid_a/b toggle */
965 if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
966 WRITE_RPS0(CMD_PAUSE | o_wait);
967 WRITE_RPS0(CMD_PAUSE | e_wait);
968 } else if ( vv->last_field == V4L2_FIELD_TOP ) {
969 WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
970 WRITE_RPS0(CMD_PAUSE | o_wait);
971 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
972 WRITE_RPS0(CMD_PAUSE | (vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? MASK_10 : MASK_09));
973 WRITE_RPS0(CMD_PAUSE | e_wait);
974 }
975
976 /* turn off video-dma1 */
977 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
978 WRITE_RPS0(MASK_22 | MASK_06); /* => mask */
979 WRITE_RPS0(MASK_22); /* => values */
980 if( 0 != planar ) {
981 /* turn off video-dma2 */
982 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
983 WRITE_RPS0(MASK_05 | MASK_21); /* => mask */
984 WRITE_RPS0(MASK_21); /* => values */
985
986 /* turn off video-dma3 */
987 WRITE_RPS0(CMD_WR_REG_MASK | (MC1/4));
988 WRITE_RPS0(MASK_04 | MASK_20); /* => mask */
989 WRITE_RPS0(MASK_20); /* => values */
990 }
991
992 /* generate interrupt */
993 WRITE_RPS0(CMD_INTERRUPT);
994
995 /* stop */
996 WRITE_RPS0(CMD_STOP);
997}
998
999void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
1000{
1001 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1002 struct saa7146_vv *vv = dev->vv_data;
1003 u32 vdma1_prot_addr;
1004
1005 DEB_CAP("buf:%p, next:%p\n", buf, next);
1006
1007 vdma1_prot_addr = saa7146_read(dev, PROT_ADDR1);
1008 if( 0 == vdma1_prot_addr ) {
1009 /* clear out beginning of streaming bit (rps register 0)*/
1010 DEB_CAP("forcing sync to new frame\n");
1011 saa7146_write(dev, MC2, MASK_27 );
1012 }
1013
1014 saa7146_set_window(dev, buf->fmt->width, buf->fmt->height, buf->fmt->field);
1015 saa7146_set_output_format(dev, sfmt->trans);
1016 saa7146_disable_clipping(dev);
1017
1018 if ( vv->last_field == V4L2_FIELD_INTERLACED ) {
1019 } else if ( vv->last_field == V4L2_FIELD_TOP ) {
1020 vv->last_field = V4L2_FIELD_BOTTOM;
1021 } else if ( vv->last_field == V4L2_FIELD_BOTTOM ) {
1022 vv->last_field = V4L2_FIELD_TOP;
1023 }
1024
1025 if( 0 != IS_PLANAR(sfmt->trans)) {
1026 calculate_video_dma_grab_planar(dev, buf);
1027 program_capture_engine(dev,1);
1028 } else {
1029 calculate_video_dma_grab_packed(dev, buf);
1030 program_capture_engine(dev,0);
1031 }
1032
1033/*
1034 printk("vdma%d.base_even: 0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
1035 printk("vdma%d.base_odd: 0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
1036 printk("vdma%d.prot_addr: 0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
1037 printk("vdma%d.base_page: 0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
1038 printk("vdma%d.pitch: 0x%08x\n", 1,saa7146_read(dev,PITCH1));
1039 printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
1040 printk("vdma%d => vptr : 0x%08x\n", 1,saa7146_read(dev,PCI_VDP1));
1041*/
1042
1043 /* write the address of the rps-program */
1044 saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
1045
1046 /* turn on rps */
1047 saa7146_write(dev, MC1, (MASK_12 | MASK_28));
1048}
diff --git a/drivers/media/common/saa7146/saa7146_i2c.c b/drivers/media/common/saa7146/saa7146_i2c.c
deleted file mode 100644
index 22027198129..00000000000
--- a/drivers/media/common/saa7146/saa7146_i2c.c
+++ /dev/null
@@ -1,423 +0,0 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
3#include <media/saa7146_vv.h>
4
5static u32 saa7146_i2c_func(struct i2c_adapter *adapter)
6{
7 /* DEB_I2C("'%s'\n", adapter->name); */
8
9 return I2C_FUNC_I2C
10 | I2C_FUNC_SMBUS_QUICK
11 | I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE
12 | I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
13}
14
15/* this function returns the status-register of our i2c-device */
16static inline u32 saa7146_i2c_status(struct saa7146_dev *dev)
17{
18 u32 iicsta = saa7146_read(dev, I2C_STATUS);
19 /* DEB_I2C("status: 0x%08x\n", iicsta); */
20 return iicsta;
21}
22
23/* this function runs through the i2c-messages and prepares the data to be
24 sent through the saa7146. have a look at the specifications p. 122 ff
25 to understand this. it returns the number of u32s to send, or -1
26 in case of an error. */
27static int saa7146_i2c_msg_prepare(const struct i2c_msg *m, int num, __le32 *op)
28{
29 int h1, h2;
30 int i, j, addr;
31 int mem = 0, op_count = 0;
32
33 /* first determine size of needed memory */
34 for(i = 0; i < num; i++) {
35 mem += m[i].len + 1;
36 }
37
38 /* worst case: we need one u32 for three bytes to be send
39 plus one extra byte to address the device */
40 mem = 1 + ((mem-1) / 3);
41
42 /* we assume that op points to a memory of at least
43 * SAA7146_I2C_MEM bytes size. if we exceed this limit...
44 */
45 if ((4 * mem) > SAA7146_I2C_MEM) {
46 /* DEB_I2C("cannot prepare i2c-message\n"); */
47 return -ENOMEM;
48 }
49
50 /* be careful: clear out the i2c-mem first */
51 memset(op,0,sizeof(__le32)*mem);
52
53 /* loop through all messages */
54 for(i = 0; i < num; i++) {
55
56 /* insert the address of the i2c-slave.
57 note: we get 7 bit i2c-addresses,
58 so we have to perform a translation */
59 addr = (m[i].addr*2) + ( (0 != (m[i].flags & I2C_M_RD)) ? 1 : 0);
60 h1 = op_count/3; h2 = op_count%3;
61 op[h1] |= cpu_to_le32( (u8)addr << ((3-h2)*8));
62 op[h1] |= cpu_to_le32(SAA7146_I2C_START << ((3-h2)*2));
63 op_count++;
64
65 /* loop through all bytes of message i */
66 for(j = 0; j < m[i].len; j++) {
67 /* insert the data bytes */
68 h1 = op_count/3; h2 = op_count%3;
69 op[h1] |= cpu_to_le32( (u32)((u8)m[i].buf[j]) << ((3-h2)*8));
70 op[h1] |= cpu_to_le32( SAA7146_I2C_CONT << ((3-h2)*2));
71 op_count++;
72 }
73
74 }
75
76 /* have a look at the last byte inserted:
77 if it was: ...CONT change it to ...STOP */
78 h1 = (op_count-1)/3; h2 = (op_count-1)%3;
79 if ( SAA7146_I2C_CONT == (0x3 & (le32_to_cpu(op[h1]) >> ((3-h2)*2))) ) {
80 op[h1] &= ~cpu_to_le32(0x2 << ((3-h2)*2));
81 op[h1] |= cpu_to_le32(SAA7146_I2C_STOP << ((3-h2)*2));
82 }
83
84 /* return the number of u32s to send */
85 return mem;
86}
87
88/* this functions loops through all i2c-messages. normally, it should determine
89 which bytes were read through the adapter and write them back to the corresponding
90 i2c-message. but instead, we simply write back all bytes.
91 fixme: this could be improved. */
92static int saa7146_i2c_msg_cleanup(const struct i2c_msg *m, int num, __le32 *op)
93{
94 int i, j;
95 int op_count = 0;
96
97 /* loop through all messages */
98 for(i = 0; i < num; i++) {
99
100 op_count++;
101
102 /* loop through all bytes of message i */
103 for(j = 0; j < m[i].len; j++) {
104 /* write back all bytes that could have been read */
105 m[i].buf[j] = (le32_to_cpu(op[op_count/3]) >> ((3-(op_count%3))*8));
106 op_count++;
107 }
108 }
109
110 return 0;
111}
112
113/* this functions resets the i2c-device and returns 0 if everything was fine, otherwise -1 */
114static int saa7146_i2c_reset(struct saa7146_dev *dev)
115{
116 /* get current status */
117 u32 status = saa7146_i2c_status(dev);
118
119 /* clear registers for sure */
120 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
121 saa7146_write(dev, I2C_TRANSFER, 0);
122
123 /* check if any operation is still in progress */
124 if ( 0 != ( status & SAA7146_I2C_BUSY) ) {
125
126 /* yes, kill ongoing operation */
127 DEB_I2C("busy_state detected\n");
128
129 /* set "ABORT-OPERATION"-bit (bit 7)*/
130 saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
131 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
132 msleep(SAA7146_I2C_DELAY);
133
134 /* clear all error-bits pending; this is needed because p.123, note 1 */
135 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
136 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
137 msleep(SAA7146_I2C_DELAY);
138 }
139
140 /* check if any error is (still) present. (this can be necessary because p.123, note 1) */
141 status = saa7146_i2c_status(dev);
142
143 if ( dev->i2c_bitrate != status ) {
144
145 DEB_I2C("error_state detected. status:0x%08x\n", status);
146
147 /* Repeat the abort operation. This seems to be necessary
148 after serious protocol errors caused by e.g. the SAA7740 */
149 saa7146_write(dev, I2C_STATUS, (dev->i2c_bitrate | MASK_07));
150 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
151 msleep(SAA7146_I2C_DELAY);
152
153 /* clear all error-bits pending */
154 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
155 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
156 msleep(SAA7146_I2C_DELAY);
157
158 /* the data sheet says it might be necessary to clear the status
159 twice after an abort */
160 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
161 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
162 msleep(SAA7146_I2C_DELAY);
163 }
164
165 /* if any error is still present, a fatal error has occurred ... */
166 status = saa7146_i2c_status(dev);
167 if ( dev->i2c_bitrate != status ) {
168 DEB_I2C("fatal error. status:0x%08x\n", status);
169 return -1;
170 }
171
172 return 0;
173}
174
175/* this functions writes out the data-byte 'dword' to the i2c-device.
176 it returns 0 if ok, -1 if the transfer failed, -2 if the transfer
177 failed badly (e.g. address error) */
178static int saa7146_i2c_writeout(struct saa7146_dev *dev, __le32 *dword, int short_delay)
179{
180 u32 status = 0, mc2 = 0;
181 int trial = 0;
182 unsigned long timeout;
183
184 /* write out i2c-command */
185 DEB_I2C("before: 0x%08x (status: 0x%08x), %d\n",
186 *dword, saa7146_read(dev, I2C_STATUS), dev->i2c_op);
187
188 if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
189
190 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
191 saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
192
193 dev->i2c_op = 1;
194 SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
195 SAA7146_IER_ENABLE(dev, MASK_16|MASK_17);
196 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
197
198 timeout = HZ/100 + 1; /* 10ms */
199 timeout = wait_event_interruptible_timeout(dev->i2c_wq, dev->i2c_op == 0, timeout);
200 if (timeout == -ERESTARTSYS || dev->i2c_op) {
201 SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
202 SAA7146_ISR_CLEAR(dev, MASK_16|MASK_17);
203 if (timeout == -ERESTARTSYS)
204 /* a signal arrived */
205 return -ERESTARTSYS;
206
207 pr_warn("%s %s [irq]: timed out waiting for end of xfer\n",
208 dev->name, __func__);
209 return -EIO;
210 }
211 status = saa7146_read(dev, I2C_STATUS);
212 } else {
213 saa7146_write(dev, I2C_STATUS, dev->i2c_bitrate);
214 saa7146_write(dev, I2C_TRANSFER, le32_to_cpu(*dword));
215 saa7146_write(dev, MC2, (MASK_00 | MASK_16));
216
217 /* do not poll for i2c-status before upload is complete */
218 timeout = jiffies + HZ/100 + 1; /* 10ms */
219 while(1) {
220 mc2 = (saa7146_read(dev, MC2) & 0x1);
221 if( 0 != mc2 ) {
222 break;
223 }
224 if (time_after(jiffies,timeout)) {
225 pr_warn("%s %s: timed out waiting for MC2\n",
226 dev->name, __func__);
227 return -EIO;
228 }
229 }
230 /* wait until we get a transfer done or error */
231 timeout = jiffies + HZ/100 + 1; /* 10ms */
232 /* first read usually delivers bogus results... */
233 saa7146_i2c_status(dev);
234 while(1) {
235 status = saa7146_i2c_status(dev);
236 if ((status & 0x3) != 1)
237 break;
238 if (time_after(jiffies,timeout)) {
239 /* this is normal when probing the bus
240 * (no answer from nonexisistant device...)
241 */
242 pr_warn("%s %s [poll]: timed out waiting for end of xfer\n",
243 dev->name, __func__);
244 return -EIO;
245 }
246 if (++trial < 50 && short_delay)
247 udelay(10);
248 else
249 msleep(1);
250 }
251 }
252
253 /* give a detailed status report */
254 if ( 0 != (status & (SAA7146_I2C_SPERR | SAA7146_I2C_APERR |
255 SAA7146_I2C_DTERR | SAA7146_I2C_DRERR |
256 SAA7146_I2C_AL | SAA7146_I2C_ERR |
257 SAA7146_I2C_BUSY)) ) {
258
259 if ( 0 == (status & SAA7146_I2C_ERR) ||
260 0 == (status & SAA7146_I2C_BUSY) ) {
261 /* it may take some time until ERR goes high - ignore */
262 DEB_I2C("unexpected i2c status %04x\n", status);
263 }
264 if( 0 != (status & SAA7146_I2C_SPERR) ) {
265 DEB_I2C("error due to invalid start/stop condition\n");
266 }
267 if( 0 != (status & SAA7146_I2C_DTERR) ) {
268 DEB_I2C("error in data transmission\n");
269 }
270 if( 0 != (status & SAA7146_I2C_DRERR) ) {
271 DEB_I2C("error when receiving data\n");
272 }
273 if( 0 != (status & SAA7146_I2C_AL) ) {
274 DEB_I2C("error because arbitration lost\n");
275 }
276
277 /* we handle address-errors here */
278 if( 0 != (status & SAA7146_I2C_APERR) ) {
279 DEB_I2C("error in address phase\n");
280 return -EREMOTEIO;
281 }
282
283 return -EIO;
284 }
285
286 /* read back data, just in case we were reading ... */
287 *dword = cpu_to_le32(saa7146_read(dev, I2C_TRANSFER));
288
289 DEB_I2C("after: 0x%08x\n", *dword);
290 return 0;
291}
292
293static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *msgs, int num, int retries)
294{
295 int i = 0, count = 0;
296 __le32 *buffer = dev->d_i2c.cpu_addr;
297 int err = 0;
298 int short_delay = 0;
299
300 if (mutex_lock_interruptible(&dev->i2c_lock))
301 return -ERESTARTSYS;
302
303 for(i=0;i<num;i++) {
304 DEB_I2C("msg:%d/%d\n", i+1, num);
305 }
306
307 /* prepare the message(s), get number of u32s to transfer */
308 count = saa7146_i2c_msg_prepare(msgs, num, buffer);
309 if ( 0 > count ) {
310 err = -1;
311 goto out;
312 }
313
314 if ( count > 3 || 0 != (SAA7146_I2C_SHORT_DELAY & dev->ext->flags) )
315 short_delay = 1;
316
317 do {
318 /* reset the i2c-device if necessary */
319 err = saa7146_i2c_reset(dev);
320 if ( 0 > err ) {
321 DEB_I2C("could not reset i2c-device\n");
322 goto out;
323 }
324
325 /* write out the u32s one after another */
326 for(i = 0; i < count; i++) {
327 err = saa7146_i2c_writeout(dev, &buffer[i], short_delay);
328 if ( 0 != err) {
329 /* this one is unsatisfying: some i2c slaves on some
330 dvb cards don't acknowledge correctly, so the saa7146
331 thinks that an address error occurred. in that case, the
332 transaction should be retrying, even if an address error
333 occurred. analog saa7146 based cards extensively rely on
334 i2c address probing, however, and address errors indicate that a
335 device is really *not* there. retrying in that case
336 increases the time the device needs to probe greatly, so
337 it should be avoided. So we bail out in irq mode after an
338 address error and trust the saa7146 address error detection. */
339 if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags))
340 goto out;
341 DEB_I2C("error while sending message(s). starting again\n");
342 break;
343 }
344 }
345 if( 0 == err ) {
346 err = num;
347 break;
348 }
349
350 /* delay a bit before retrying */
351 msleep(10);
352
353 } while (err != num && retries--);
354
355 /* quit if any error occurred */
356 if (err != num)
357 goto out;
358
359 /* if any things had to be read, get the results */
360 if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
361 DEB_I2C("could not cleanup i2c-message\n");
362 err = -1;
363 goto out;
364 }
365
366 /* return the number of delivered messages */
367 DEB_I2C("transmission successful. (msg:%d)\n", err);
368out:
369 /* another bug in revision 0: the i2c-registers get uploaded randomly by other
370 uploads, so we better clear them out before continuing */
371 if( 0 == dev->revision ) {
372 __le32 zero = 0;
373 saa7146_i2c_reset(dev);
374 if( 0 != saa7146_i2c_writeout(dev, &zero, short_delay)) {
375 pr_info("revision 0 error. this should never happen\n");
376 }
377 }
378
379 mutex_unlock(&dev->i2c_lock);
380 return err;
381}
382
383/* utility functions */
384static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
385{
386 struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
387 struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
388
389 /* use helper function to transfer data */
390 return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
391}
392
393
394/*****************************************************************************/
395/* i2c-adapter helper functions */
396
397/* exported algorithm data */
398static struct i2c_algorithm saa7146_algo = {
399 .master_xfer = saa7146_i2c_xfer,
400 .functionality = saa7146_i2c_func,
401};
402
403int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c_adapter, u32 bitrate)
404{
405 DEB_EE("bitrate: 0x%08x\n", bitrate);
406
407 /* enable i2c-port pins */
408 saa7146_write(dev, MC1, (MASK_08 | MASK_24));
409
410 dev->i2c_bitrate = bitrate;
411 saa7146_i2c_reset(dev);
412
413 if (i2c_adapter) {
414 i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
415 i2c_adapter->dev.parent = &dev->pci->dev;
416 i2c_adapter->algo = &saa7146_algo;
417 i2c_adapter->algo_data = NULL;
418 i2c_adapter->timeout = SAA7146_I2C_TIMEOUT;
419 i2c_adapter->retries = SAA7146_I2C_RETRIES;
420 }
421
422 return 0;
423}
diff --git a/drivers/media/common/saa7146/saa7146_vbi.c b/drivers/media/common/saa7146/saa7146_vbi.c
deleted file mode 100644
index 1e71e374bbf..00000000000
--- a/drivers/media/common/saa7146/saa7146_vbi.c
+++ /dev/null
@@ -1,498 +0,0 @@
1#include <media/saa7146_vv.h>
2
3static int vbi_pixel_to_capture = 720 * 2;
4
5static int vbi_workaround(struct saa7146_dev *dev)
6{
7 struct saa7146_vv *vv = dev->vv_data;
8
9 u32 *cpu;
10 dma_addr_t dma_addr;
11
12 int count = 0;
13 int i;
14
15 DECLARE_WAITQUEUE(wait, current);
16
17 DEB_VBI("dev:%p\n", dev);
18
19 /* once again, a bug in the saa7146: the brs acquisition
20 is buggy and especially the BXO-counter does not work
21 as specified. there is this workaround, but please
22 don't let me explain it. ;-) */
23
24 cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
25 if (NULL == cpu)
26 return -ENOMEM;
27
28 /* setup some basic programming, just for the workaround */
29 saa7146_write(dev, BASE_EVEN3, dma_addr);
30 saa7146_write(dev, BASE_ODD3, dma_addr+vbi_pixel_to_capture);
31 saa7146_write(dev, PROT_ADDR3, dma_addr+4096);
32 saa7146_write(dev, PITCH3, vbi_pixel_to_capture);
33 saa7146_write(dev, BASE_PAGE3, 0x0);
34 saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
35 saa7146_write(dev, MC2, MASK_04|MASK_20);
36
37 /* load brs-control register */
38 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
39 /* BXO = 1h, BRS to outbound */
40 WRITE_RPS1(0xc000008c);
41 /* wait for vbi_a or vbi_b*/
42 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
43 DEB_D("...using port b\n");
44 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
45 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
46/*
47 WRITE_RPS1(CMD_PAUSE | MASK_09);
48*/
49 } else {
50 DEB_D("...using port a\n");
51 WRITE_RPS1(CMD_PAUSE | MASK_10);
52 }
53 /* upload brs */
54 WRITE_RPS1(CMD_UPLOAD | MASK_08);
55 /* load brs-control register */
56 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
57 /* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
58 WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
59 /* wait for brs_done */
60 WRITE_RPS1(CMD_PAUSE | MASK_08);
61 /* upload brs */
62 WRITE_RPS1(CMD_UPLOAD | MASK_08);
63 /* load video-dma3 NumLines3 and NumBytes3 */
64 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
65 /* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
66 WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
67 /* load brs-control register */
68 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
69 /* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
70 WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start
71 /* wait for brs_done */
72 WRITE_RPS1(CMD_PAUSE | MASK_08);
73 /* upload brs and video-dma3*/
74 WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
75 /* load mc2 register: enable dma3 */
76 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
77 WRITE_RPS1(MASK_20 | MASK_04);
78 /* generate interrupt */
79 WRITE_RPS1(CMD_INTERRUPT);
80 /* stop rps1 */
81 WRITE_RPS1(CMD_STOP);
82
83 /* we have to do the workaround twice to be sure that
84 everything is ok */
85 for(i = 0; i < 2; i++) {
86
87 /* indicate to the irq handler that we do the workaround */
88 saa7146_write(dev, MC2, MASK_31|MASK_15);
89
90 saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
91 saa7146_write(dev, MC2, MASK_04|MASK_20);
92
93 /* enable rps1 irqs */
94 SAA7146_IER_ENABLE(dev,MASK_28);
95
96 /* prepare to wait to be woken up by the irq-handler */
97 add_wait_queue(&vv->vbi_wq, &wait);
98 current->state = TASK_INTERRUPTIBLE;
99
100 /* start rps1 to enable workaround */
101 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
102 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
103
104 schedule();
105
106 DEB_VBI("brs bug workaround %d/1\n", i);
107
108 remove_wait_queue(&vv->vbi_wq, &wait);
109 current->state = TASK_RUNNING;
110
111 /* disable rps1 irqs */
112 SAA7146_IER_DISABLE(dev,MASK_28);
113
114 /* stop video-dma3 */
115 saa7146_write(dev, MC1, MASK_20);
116
117 if(signal_pending(current)) {
118
119 DEB_VBI("aborted (rps:0x%08x)\n",
120 saa7146_read(dev, RPS_ADDR1));
121
122 /* stop rps1 for sure */
123 saa7146_write(dev, MC1, MASK_29);
124
125 pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
126 return -EINTR;
127 }
128 }
129
130 pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
131 return 0;
132}
133
134static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
135{
136 struct saa7146_vv *vv = dev->vv_data;
137
138 struct saa7146_video_dma vdma3;
139
140 int count = 0;
141 unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
142 unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
143
144/*
145 vdma3.base_even = 0xc8000000+2560*70;
146 vdma3.base_odd = 0xc8000000;
147 vdma3.prot_addr = 0xc8000000+2560*164;
148 vdma3.pitch = 2560;
149 vdma3.base_page = 0;
150 vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
151*/
152 vdma3.base_even = buf->pt[2].offset;
153 vdma3.base_odd = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
154 vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
155 vdma3.pitch = vbi_pixel_to_capture;
156 vdma3.base_page = buf->pt[2].dma | ME1;
157 vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
158
159 saa7146_write_out_dma(dev, 3, &vdma3);
160
161 /* write beginning of rps-program */
162 count = 0;
163
164 /* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
165
166 /* we don't wait here for the first field anymore. this is different from the video
167 capture and might cause that the first buffer is only half filled (with only
168 one field). but since this is some sort of streaming data, this is not that negative.
169 but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
170
171/*
172 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
173 WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
174*/
175 /* set bit 1 */
176 WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
177 WRITE_RPS1(MASK_28 | MASK_12);
178
179 /* turn on video-dma3 */
180 WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
181 WRITE_RPS1(MASK_04 | MASK_20); /* => mask */
182 WRITE_RPS1(MASK_04 | MASK_20); /* => values */
183
184 /* wait for o_fid_a/b / e_fid_a/b toggle */
185 WRITE_RPS1(CMD_PAUSE | o_wait);
186 WRITE_RPS1(CMD_PAUSE | e_wait);
187
188 /* generate interrupt */
189 WRITE_RPS1(CMD_INTERRUPT);
190
191 /* stop */
192 WRITE_RPS1(CMD_STOP);
193
194 /* enable rps1 irqs */
195 SAA7146_IER_ENABLE(dev, MASK_28);
196
197 /* write the address of the rps-program */
198 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
199
200 /* turn on rps */
201 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
202}
203
204static int buffer_activate(struct saa7146_dev *dev,
205 struct saa7146_buf *buf,
206 struct saa7146_buf *next)
207{
208 struct saa7146_vv *vv = dev->vv_data;
209 buf->vb.state = VIDEOBUF_ACTIVE;
210
211 DEB_VBI("dev:%p, buf:%p, next:%p\n", dev, buf, next);
212 saa7146_set_vbi_capture(dev,buf,next);
213
214 mod_timer(&vv->vbi_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
215 return 0;
216}
217
218static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
219{
220 struct file *file = q->priv_data;
221 struct saa7146_fh *fh = file->private_data;
222 struct saa7146_dev *dev = fh->dev;
223 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
224
225 int err = 0;
226 int lines, llength, size;
227
228 lines = 16 * 2 ; /* 2 fields */
229 llength = vbi_pixel_to_capture;
230 size = lines * llength;
231
232 DEB_VBI("vb:%p\n", vb);
233
234 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
235 DEB_VBI("size mismatch\n");
236 return -EINVAL;
237 }
238
239 if (buf->vb.size != size)
240 saa7146_dma_free(dev,q,buf);
241
242 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
243 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
244
245 buf->vb.width = llength;
246 buf->vb.height = lines;
247 buf->vb.size = size;
248 buf->vb.field = field; // FIXME: check this
249
250 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
251 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
252
253 err = videobuf_iolock(q,&buf->vb, NULL);
254 if (err)
255 goto oops;
256 err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
257 dma->sglist, dma->sglen);
258 if (0 != err)
259 return err;
260 }
261 buf->vb.state = VIDEOBUF_PREPARED;
262 buf->activate = buffer_activate;
263
264 return 0;
265
266 oops:
267 DEB_VBI("error out\n");
268 saa7146_dma_free(dev,q,buf);
269
270 return err;
271}
272
273static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
274{
275 int llength,lines;
276
277 lines = 16 * 2 ; /* 2 fields */
278 llength = vbi_pixel_to_capture;
279
280 *size = lines * llength;
281 *count = 2;
282
283 DEB_VBI("count:%d, size:%d\n", *count, *size);
284
285 return 0;
286}
287
288static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
289{
290 struct file *file = q->priv_data;
291 struct saa7146_fh *fh = file->private_data;
292 struct saa7146_dev *dev = fh->dev;
293 struct saa7146_vv *vv = dev->vv_data;
294 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
295
296 DEB_VBI("vb:%p\n", vb);
297 saa7146_buffer_queue(dev, &vv->vbi_dmaq, buf);
298}
299
300static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
301{
302 struct file *file = q->priv_data;
303 struct saa7146_fh *fh = file->private_data;
304 struct saa7146_dev *dev = fh->dev;
305 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
306
307 DEB_VBI("vb:%p\n", vb);
308 saa7146_dma_free(dev,q,buf);
309}
310
311static struct videobuf_queue_ops vbi_qops = {
312 .buf_setup = buffer_setup,
313 .buf_prepare = buffer_prepare,
314 .buf_queue = buffer_queue,
315 .buf_release = buffer_release,
316};
317
318/* ------------------------------------------------------------------ */
319
320static void vbi_stop(struct saa7146_fh *fh, struct file *file)
321{
322 struct saa7146_dev *dev = fh->dev;
323 struct saa7146_vv *vv = dev->vv_data;
324 unsigned long flags;
325 DEB_VBI("dev:%p, fh:%p\n", dev, fh);
326
327 spin_lock_irqsave(&dev->slock,flags);
328
329 /* disable rps1 */
330 saa7146_write(dev, MC1, MASK_29);
331
332 /* disable rps1 irqs */
333 SAA7146_IER_DISABLE(dev, MASK_28);
334
335 /* shut down dma 3 transfers */
336 saa7146_write(dev, MC1, MASK_20);
337
338 if (vv->vbi_dmaq.curr)
339 saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
340
341 videobuf_queue_cancel(&fh->vbi_q);
342
343 vv->vbi_streaming = NULL;
344
345 del_timer(&vv->vbi_dmaq.timeout);
346 del_timer(&vv->vbi_read_timeout);
347
348 spin_unlock_irqrestore(&dev->slock, flags);
349}
350
351static void vbi_read_timeout(unsigned long data)
352{
353 struct file *file = (struct file*)data;
354 struct saa7146_fh *fh = file->private_data;
355 struct saa7146_dev *dev = fh->dev;
356
357 DEB_VBI("dev:%p, fh:%p\n", dev, fh);
358
359 vbi_stop(fh, file);
360}
361
362static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
363{
364 DEB_VBI("dev:%p\n", dev);
365
366 INIT_LIST_HEAD(&vv->vbi_dmaq.queue);
367
368 init_timer(&vv->vbi_dmaq.timeout);
369 vv->vbi_dmaq.timeout.function = saa7146_buffer_timeout;
370 vv->vbi_dmaq.timeout.data = (unsigned long)(&vv->vbi_dmaq);
371 vv->vbi_dmaq.dev = dev;
372
373 init_waitqueue_head(&vv->vbi_wq);
374}
375
376static int vbi_open(struct saa7146_dev *dev, struct file *file)
377{
378 struct saa7146_fh *fh = file->private_data;
379 struct saa7146_vv *vv = fh->dev->vv_data;
380
381 u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
382 int ret = 0;
383
384 DEB_VBI("dev:%p, fh:%p\n", dev, fh);
385
386 ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
387 if (0 == ret) {
388 DEB_S("cannot get vbi RESOURCE_DMA3_BRS resource\n");
389 return -EBUSY;
390 }
391
392 /* adjust arbitrition control for video dma 3 */
393 arbtr_ctrl &= ~0x1f0000;
394 arbtr_ctrl |= 0x1d0000;
395 saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
396 saa7146_write(dev, MC2, (MASK_04|MASK_20));
397
398 videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
399 &dev->pci->dev, &dev->slock,
400 V4L2_BUF_TYPE_VBI_CAPTURE,
401 V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
402 sizeof(struct saa7146_buf),
403 file, &dev->v4l2_lock);
404
405 vv->vbi_read_timeout.function = vbi_read_timeout;
406 vv->vbi_read_timeout.data = (unsigned long)file;
407
408 /* initialize the brs */
409 if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
410 saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
411 } else {
412 saa7146_write(dev, BRS_CTRL, 0x00000001);
413
414 if (0 != (ret = vbi_workaround(dev))) {
415 DEB_VBI("vbi workaround failed!\n");
416 /* return ret;*/
417 }
418 }
419
420 /* upload brs register */
421 saa7146_write(dev, MC2, (MASK_08|MASK_24));
422 return 0;
423}
424
425static void vbi_close(struct saa7146_dev *dev, struct file *file)
426{
427 struct saa7146_fh *fh = file->private_data;
428 struct saa7146_vv *vv = dev->vv_data;
429 DEB_VBI("dev:%p, fh:%p\n", dev, fh);
430
431 if( fh == vv->vbi_streaming ) {
432 vbi_stop(fh, file);
433 }
434 saa7146_res_free(fh, RESOURCE_DMA3_BRS);
435}
436
437static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
438{
439 struct saa7146_vv *vv = dev->vv_data;
440 spin_lock(&dev->slock);
441
442 if (vv->vbi_dmaq.curr) {
443 DEB_VBI("dev:%p, curr:%p\n", dev, vv->vbi_dmaq.curr);
444 /* this must be += 2, one count for each field */
445 vv->vbi_fieldcount+=2;
446 vv->vbi_dmaq.curr->vb.field_count = vv->vbi_fieldcount;
447 saa7146_buffer_finish(dev, &vv->vbi_dmaq, VIDEOBUF_DONE);
448 } else {
449 DEB_VBI("dev:%p\n", dev);
450 }
451 saa7146_buffer_next(dev, &vv->vbi_dmaq, 1);
452
453 spin_unlock(&dev->slock);
454}
455
456static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
457{
458 struct saa7146_fh *fh = file->private_data;
459 struct saa7146_dev *dev = fh->dev;
460 struct saa7146_vv *vv = dev->vv_data;
461 ssize_t ret = 0;
462
463 DEB_VBI("dev:%p, fh:%p\n", dev, fh);
464
465 if( NULL == vv->vbi_streaming ) {
466 // fixme: check if dma3 is available
467 // fixme: activate vbi engine here if necessary. (really?)
468 vv->vbi_streaming = fh;
469 }
470
471 if( fh != vv->vbi_streaming ) {
472 DEB_VBI("open %p is already using vbi capture\n",
473 vv->vbi_streaming);
474 return -EBUSY;
475 }
476
477 mod_timer(&vv->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
478 ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
479 file->f_flags & O_NONBLOCK);
480/*
481 printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3));
482 printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3));
483 printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3));
484 printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3));
485 printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3));
486 printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
487 printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL));
488*/
489 return ret;
490}
491
492struct saa7146_use_ops saa7146_vbi_uops = {
493 .init = vbi_init,
494 .open = vbi_open,
495 .release = vbi_close,
496 .irq_done = vbi_irq_done,
497 .read = vbi_read,
498};
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
deleted file mode 100644
index 4143d61f79b..00000000000
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ /dev/null
@@ -1,1332 +0,0 @@
1#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2
3#include <media/saa7146_vv.h>
4#include <media/v4l2-chip-ident.h>
5#include <media/v4l2-event.h>
6#include <media/v4l2-ctrls.h>
7#include <linux/module.h>
8
9static int max_memory = 32;
10
11module_param(max_memory, int, 0644);
12MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)");
13
14#define IS_CAPTURE_ACTIVE(fh) \
15 (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh))
16
17#define IS_OVERLAY_ACTIVE(fh) \
18 (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh))
19
20/* format descriptions for capture and preview */
21static struct saa7146_format formats[] = {
22 {
23 .name = "RGB-8 (3-3-2)",
24 .pixelformat = V4L2_PIX_FMT_RGB332,
25 .trans = RGB08_COMPOSED,
26 .depth = 8,
27 .flags = 0,
28 }, {
29 .name = "RGB-16 (5/B-6/G-5/R)",
30 .pixelformat = V4L2_PIX_FMT_RGB565,
31 .trans = RGB16_COMPOSED,
32 .depth = 16,
33 .flags = 0,
34 }, {
35 .name = "RGB-24 (B-G-R)",
36 .pixelformat = V4L2_PIX_FMT_BGR24,
37 .trans = RGB24_COMPOSED,
38 .depth = 24,
39 .flags = 0,
40 }, {
41 .name = "RGB-32 (B-G-R)",
42 .pixelformat = V4L2_PIX_FMT_BGR32,
43 .trans = RGB32_COMPOSED,
44 .depth = 32,
45 .flags = 0,
46 }, {
47 .name = "RGB-32 (R-G-B)",
48 .pixelformat = V4L2_PIX_FMT_RGB32,
49 .trans = RGB32_COMPOSED,
50 .depth = 32,
51 .flags = 0,
52 .swap = 0x2,
53 }, {
54 .name = "Greyscale-8",
55 .pixelformat = V4L2_PIX_FMT_GREY,
56 .trans = Y8,
57 .depth = 8,
58 .flags = 0,
59 }, {
60 .name = "YUV 4:2:2 planar (Y-Cb-Cr)",
61 .pixelformat = V4L2_PIX_FMT_YUV422P,
62 .trans = YUV422_DECOMPOSED,
63 .depth = 16,
64 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
65 }, {
66 .name = "YVU 4:2:0 planar (Y-Cb-Cr)",
67 .pixelformat = V4L2_PIX_FMT_YVU420,
68 .trans = YUV420_DECOMPOSED,
69 .depth = 12,
70 .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
71 }, {
72 .name = "YUV 4:2:0 planar (Y-Cb-Cr)",
73 .pixelformat = V4L2_PIX_FMT_YUV420,
74 .trans = YUV420_DECOMPOSED,
75 .depth = 12,
76 .flags = FORMAT_IS_PLANAR,
77 }, {
78 .name = "YUV 4:2:2 (U-Y-V-Y)",
79 .pixelformat = V4L2_PIX_FMT_UYVY,
80 .trans = YUV422_COMPOSED,
81 .depth = 16,
82 .flags = 0,
83 }
84};
85
86/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
87 due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
88 (like V4L2_PIX_FMT_YUYV) ... 8-( */
89
90static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
91
92struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
93{
94 int i, j = NUM_FORMATS;
95
96 for (i = 0; i < j; i++) {
97 if (formats[i].pixelformat == fourcc) {
98 return formats+i;
99 }
100 }
101
102 DEB_D("unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
103 return NULL;
104}
105
106static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
107
108int saa7146_start_preview(struct saa7146_fh *fh)
109{
110 struct saa7146_dev *dev = fh->dev;
111 struct saa7146_vv *vv = dev->vv_data;
112 struct v4l2_format fmt;
113 int ret = 0, err = 0;
114
115 DEB_EE("dev:%p, fh:%p\n", dev, fh);
116
117 /* check if we have overlay information */
118 if (vv->ov.fh == NULL) {
119 DEB_D("no overlay data available. try S_FMT first.\n");
120 return -EAGAIN;
121 }
122
123 /* check if streaming capture is running */
124 if (IS_CAPTURE_ACTIVE(fh) != 0) {
125 DEB_D("streaming capture is active\n");
126 return -EBUSY;
127 }
128
129 /* check if overlay is running */
130 if (IS_OVERLAY_ACTIVE(fh) != 0) {
131 if (vv->video_fh == fh) {
132 DEB_D("overlay is already active\n");
133 return 0;
134 }
135 DEB_D("overlay is already active in another open\n");
136 return -EBUSY;
137 }
138
139 if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
140 DEB_D("cannot get necessary overlay resources\n");
141 return -EBUSY;
142 }
143
144 fmt.fmt.win = vv->ov.win;
145 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
146 if (0 != err) {
147 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
148 return -EBUSY;
149 }
150 vv->ov.win = fmt.fmt.win;
151
152 DEB_D("%dx%d+%d+%d %s field=%s\n",
153 vv->ov.win.w.width, vv->ov.win.w.height,
154 vv->ov.win.w.left, vv->ov.win.w.top,
155 vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);
156
157 if (0 != (ret = saa7146_enable_overlay(fh))) {
158 DEB_D("enabling overlay failed: %d\n", ret);
159 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
160 return ret;
161 }
162
163 vv->video_status = STATUS_OVERLAY;
164 vv->video_fh = fh;
165
166 return 0;
167}
168EXPORT_SYMBOL_GPL(saa7146_start_preview);
169
170int saa7146_stop_preview(struct saa7146_fh *fh)
171{
172 struct saa7146_dev *dev = fh->dev;
173 struct saa7146_vv *vv = dev->vv_data;
174
175 DEB_EE("dev:%p, fh:%p\n", dev, fh);
176
177 /* check if streaming capture is running */
178 if (IS_CAPTURE_ACTIVE(fh) != 0) {
179 DEB_D("streaming capture is active\n");
180 return -EBUSY;
181 }
182
183 /* check if overlay is running at all */
184 if ((vv->video_status & STATUS_OVERLAY) == 0) {
185 DEB_D("no active overlay\n");
186 return 0;
187 }
188
189 if (vv->video_fh != fh) {
190 DEB_D("overlay is active, but in another open\n");
191 return -EBUSY;
192 }
193
194 vv->video_status = 0;
195 vv->video_fh = NULL;
196
197 saa7146_disable_overlay(fh);
198
199 saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
200
201 return 0;
202}
203EXPORT_SYMBOL_GPL(saa7146_stop_preview);
204
205/********************************************************************************/
206/* common pagetable functions */
207
208static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
209{
210 struct pci_dev *pci = dev->pci;
211 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
212 struct scatterlist *list = dma->sglist;
213 int length = dma->sglen;
214 struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
215
216 DEB_EE("dev:%p, buf:%p, sg_len:%d\n", dev, buf, length);
217
218 if( 0 != IS_PLANAR(sfmt->trans)) {
219 struct saa7146_pgtable *pt1 = &buf->pt[0];
220 struct saa7146_pgtable *pt2 = &buf->pt[1];
221 struct saa7146_pgtable *pt3 = &buf->pt[2];
222 __le32 *ptr1, *ptr2, *ptr3;
223 __le32 fill;
224
225 int size = buf->fmt->width*buf->fmt->height;
226 int i,p,m1,m2,m3,o1,o2;
227
228 switch( sfmt->depth ) {
229 case 12: {
230 /* create some offsets inside the page table */
231 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
232 m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
233 m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
234 o1 = size%PAGE_SIZE;
235 o2 = (size+(size/4))%PAGE_SIZE;
236 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
237 size, m1, m2, m3, o1, o2);
238 break;
239 }
240 case 16: {
241 /* create some offsets inside the page table */
242 m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
243 m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
244 m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
245 o1 = size%PAGE_SIZE;
246 o2 = (size+(size/2))%PAGE_SIZE;
247 DEB_CAP("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",
248 size, m1, m2, m3, o1, o2);
249 break;
250 }
251 default: {
252 return -1;
253 }
254 }
255
256 ptr1 = pt1->cpu;
257 ptr2 = pt2->cpu;
258 ptr3 = pt3->cpu;
259
260 /* walk all pages, copy all page addresses to ptr1 */
261 for (i = 0; i < length; i++, list++) {
262 for (p = 0; p * 4096 < list->length; p++, ptr1++) {
263 *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset);
264 }
265 }
266/*
267 ptr1 = pt1->cpu;
268 for(j=0;j<40;j++) {
269 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
270 }
271*/
272
273 /* if we have a user buffer, the first page may not be
274 aligned to a page boundary. */
275 pt1->offset = dma->sglist->offset;
276 pt2->offset = pt1->offset+o1;
277 pt3->offset = pt1->offset+o2;
278
279 /* create video-dma2 page table */
280 ptr1 = pt1->cpu;
281 for(i = m1; i <= m2 ; i++, ptr2++) {
282 *ptr2 = ptr1[i];
283 }
284 fill = *(ptr2-1);
285 for(;i<1024;i++,ptr2++) {
286 *ptr2 = fill;
287 }
288 /* create video-dma3 page table */
289 ptr1 = pt1->cpu;
290 for(i = m2; i <= m3; i++,ptr3++) {
291 *ptr3 = ptr1[i];
292 }
293 fill = *(ptr3-1);
294 for(;i<1024;i++,ptr3++) {
295 *ptr3 = fill;
296 }
297 /* finally: finish up video-dma1 page table */
298 ptr1 = pt1->cpu+m1;
299 fill = pt1->cpu[m1];
300 for(i=m1;i<1024;i++,ptr1++) {
301 *ptr1 = fill;
302 }
303/*
304 ptr1 = pt1->cpu;
305 ptr2 = pt2->cpu;
306 ptr3 = pt3->cpu;
307 for(j=0;j<40;j++) {
308 printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
309 }
310 for(j=0;j<40;j++) {
311 printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
312 }
313 for(j=0;j<40;j++) {
314 printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
315 }
316*/
317 } else {
318 struct saa7146_pgtable *pt = &buf->pt[0];
319 return saa7146_pgtable_build_single(pci, pt, list, length);
320 }
321
322 return 0;
323}
324
325
326/********************************************************************************/
327/* file operations */
328
329static int video_begin(struct saa7146_fh *fh)
330{
331 struct saa7146_dev *dev = fh->dev;
332 struct saa7146_vv *vv = dev->vv_data;
333 struct saa7146_format *fmt = NULL;
334 unsigned int resource;
335 int ret = 0, err = 0;
336
337 DEB_EE("dev:%p, fh:%p\n", dev, fh);
338
339 if ((vv->video_status & STATUS_CAPTURE) != 0) {
340 if (vv->video_fh == fh) {
341 DEB_S("already capturing\n");
342 return 0;
343 }
344 DEB_S("already capturing in another open\n");
345 return -EBUSY;
346 }
347
348 if ((vv->video_status & STATUS_OVERLAY) != 0) {
349 DEB_S("warning: suspending overlay video for streaming capture\n");
350 vv->ov_suspend = vv->video_fh;
351 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
352 if (0 != err) {
353 DEB_D("suspending video failed. aborting\n");
354 return err;
355 }
356 }
357
358 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
359 /* we need to have a valid format set here */
360 BUG_ON(NULL == fmt);
361
362 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
363 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
364 } else {
365 resource = RESOURCE_DMA1_HPS;
366 }
367
368 ret = saa7146_res_get(fh, resource);
369 if (0 == ret) {
370 DEB_S("cannot get capture resource %d\n", resource);
371 if (vv->ov_suspend != NULL) {
372 saa7146_start_preview(vv->ov_suspend);
373 vv->ov_suspend = NULL;
374 }
375 return -EBUSY;
376 }
377
378 /* clear out beginning of streaming bit (rps register 0)*/
379 saa7146_write(dev, MC2, MASK_27 );
380
381 /* enable rps0 irqs */
382 SAA7146_IER_ENABLE(dev, MASK_27);
383
384 vv->video_fh = fh;
385 vv->video_status = STATUS_CAPTURE;
386
387 return 0;
388}
389
390static int video_end(struct saa7146_fh *fh, struct file *file)
391{
392 struct saa7146_dev *dev = fh->dev;
393 struct saa7146_vv *vv = dev->vv_data;
394 struct saa7146_format *fmt = NULL;
395 unsigned long flags;
396 unsigned int resource;
397 u32 dmas = 0;
398 DEB_EE("dev:%p, fh:%p\n", dev, fh);
399
400 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
401 DEB_S("not capturing\n");
402 return 0;
403 }
404
405 if (vv->video_fh != fh) {
406 DEB_S("capturing, but in another open\n");
407 return -EBUSY;
408 }
409
410 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
411 /* we need to have a valid format set here */
412 BUG_ON(NULL == fmt);
413
414 if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
415 resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
416 dmas = MASK_22 | MASK_21 | MASK_20;
417 } else {
418 resource = RESOURCE_DMA1_HPS;
419 dmas = MASK_22;
420 }
421 spin_lock_irqsave(&dev->slock,flags);
422
423 /* disable rps0 */
424 saa7146_write(dev, MC1, MASK_28);
425
426 /* disable rps0 irqs */
427 SAA7146_IER_DISABLE(dev, MASK_27);
428
429 /* shut down all used video dma transfers */
430 saa7146_write(dev, MC1, dmas);
431
432 spin_unlock_irqrestore(&dev->slock, flags);
433
434 vv->video_fh = NULL;
435 vv->video_status = 0;
436
437 saa7146_res_free(fh, resource);
438
439 if (vv->ov_suspend != NULL) {
440 saa7146_start_preview(vv->ov_suspend);
441 vv->ov_suspend = NULL;
442 }
443
444 return 0;
445}
446
447static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
448{
449 struct video_device *vdev = video_devdata(file);
450 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
451
452 strcpy((char *)cap->driver, "saa7146 v4l2");
453 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
454 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
455 cap->device_caps =
456 V4L2_CAP_VIDEO_CAPTURE |
457 V4L2_CAP_VIDEO_OVERLAY |
458 V4L2_CAP_READWRITE |
459 V4L2_CAP_STREAMING;
460 cap->device_caps |= dev->ext_vv_data->capabilities;
461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
462 if (vdev->vfl_type == VFL_TYPE_GRABBER)
463 cap->device_caps &=
464 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
465 else
466 cap->device_caps &=
467 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
468 return 0;
469}
470
471static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
472{
473 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
474 struct saa7146_vv *vv = dev->vv_data;
475
476 *fb = vv->ov_fb;
477 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
478 fb->flags = V4L2_FBUF_FLAG_PRIMARY;
479 return 0;
480}
481
482static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *fb)
483{
484 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
485 struct saa7146_vv *vv = dev->vv_data;
486 struct saa7146_format *fmt;
487
488 DEB_EE("VIDIOC_S_FBUF\n");
489
490 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
491 return -EPERM;
492
493 /* check args */
494 fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat);
495 if (NULL == fmt)
496 return -EINVAL;
497
498 /* planar formats are not allowed for overlay video, clipping and video dma would clash */
499 if (fmt->flags & FORMAT_IS_PLANAR)
500 DEB_S("planar pixelformat '%4.4s' not allowed for overlay\n",
501 (char *)&fmt->pixelformat);
502
503 /* check if overlay is running */
504 if (IS_OVERLAY_ACTIVE(fh) != 0) {
505 if (vv->video_fh != fh) {
506 DEB_D("refusing to change framebuffer informations while overlay is active in another open\n");
507 return -EBUSY;
508 }
509 }
510
511 /* ok, accept it */
512 vv->ov_fb = *fb;
513 vv->ov_fmt = fmt;
514
515 if (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
516 vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
517 DEB_D("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline);
518 }
519 return 0;
520}
521
522static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
523{
524 if (f->index >= NUM_FORMATS)
525 return -EINVAL;
526 strlcpy((char *)f->description, formats[f->index].name,
527 sizeof(f->description));
528 f->pixelformat = formats[f->index].pixelformat;
529 return 0;
530}
531
532int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
533{
534 struct saa7146_dev *dev = container_of(ctrl->handler,
535 struct saa7146_dev, ctrl_handler);
536 struct saa7146_vv *vv = dev->vv_data;
537 u32 val;
538
539 switch (ctrl->id) {
540 case V4L2_CID_BRIGHTNESS:
541 val = saa7146_read(dev, BCS_CTRL);
542 val &= 0x00ffffff;
543 val |= (ctrl->val << 24);
544 saa7146_write(dev, BCS_CTRL, val);
545 saa7146_write(dev, MC2, MASK_22 | MASK_06);
546 break;
547
548 case V4L2_CID_CONTRAST:
549 val = saa7146_read(dev, BCS_CTRL);
550 val &= 0xff00ffff;
551 val |= (ctrl->val << 16);
552 saa7146_write(dev, BCS_CTRL, val);
553 saa7146_write(dev, MC2, MASK_22 | MASK_06);
554 break;
555
556 case V4L2_CID_SATURATION:
557 val = saa7146_read(dev, BCS_CTRL);
558 val &= 0xffffff00;
559 val |= (ctrl->val << 0);
560 saa7146_write(dev, BCS_CTRL, val);
561 saa7146_write(dev, MC2, MASK_22 | MASK_06);
562 break;
563
564 case V4L2_CID_HFLIP:
565 /* fixme: we can support changing VFLIP and HFLIP here... */
566 if ((vv->video_status & STATUS_CAPTURE))
567 return -EBUSY;
568 vv->hflip = ctrl->val;
569 break;
570
571 case V4L2_CID_VFLIP:
572 if ((vv->video_status & STATUS_CAPTURE))
573 return -EBUSY;
574 vv->vflip = ctrl->val;
575 break;
576
577 default:
578 return -EINVAL;
579 }
580
581 if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
582 struct saa7146_fh *fh = vv->video_fh;
583
584 saa7146_stop_preview(fh);
585 saa7146_start_preview(fh);
586 }
587 return 0;
588}
589
590static int vidioc_g_parm(struct file *file, void *fh,
591 struct v4l2_streamparm *parm)
592{
593 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
594 struct saa7146_vv *vv = dev->vv_data;
595
596 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
597 return -EINVAL;
598 parm->parm.capture.readbuffers = 1;
599 v4l2_video_std_frame_period(vv->standard->id,
600 &parm->parm.capture.timeperframe);
601 return 0;
602}
603
604static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
605{
606 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
607 struct saa7146_vv *vv = dev->vv_data;
608
609 f->fmt.pix = vv->video_fmt;
610 return 0;
611}
612
613static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
614{
615 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
616 struct saa7146_vv *vv = dev->vv_data;
617
618 f->fmt.win = vv->ov.win;
619 return 0;
620}
621
622static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
623{
624 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
625 struct saa7146_vv *vv = dev->vv_data;
626
627 f->fmt.vbi = vv->vbi_fmt;
628 return 0;
629}
630
631static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
632{
633 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
634 struct saa7146_vv *vv = dev->vv_data;
635 struct saa7146_format *fmt;
636 enum v4l2_field field;
637 int maxw, maxh;
638 int calc_bpl;
639
640 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh);
641
642 fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat);
643 if (NULL == fmt)
644 return -EINVAL;
645
646 field = f->fmt.pix.field;
647 maxw = vv->standard->h_max_out;
648 maxh = vv->standard->v_max_out;
649
650 if (V4L2_FIELD_ANY == field) {
651 field = (f->fmt.pix.height > maxh / 2)
652 ? V4L2_FIELD_INTERLACED
653 : V4L2_FIELD_BOTTOM;
654 }
655 switch (field) {
656 case V4L2_FIELD_ALTERNATE:
657 vv->last_field = V4L2_FIELD_TOP;
658 maxh = maxh / 2;
659 break;
660 case V4L2_FIELD_TOP:
661 case V4L2_FIELD_BOTTOM:
662 vv->last_field = V4L2_FIELD_INTERLACED;
663 maxh = maxh / 2;
664 break;
665 case V4L2_FIELD_INTERLACED:
666 vv->last_field = V4L2_FIELD_INTERLACED;
667 break;
668 default:
669 DEB_D("no known field mode '%d'\n", field);
670 return -EINVAL;
671 }
672
673 f->fmt.pix.field = field;
674 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
675 if (f->fmt.pix.width > maxw)
676 f->fmt.pix.width = maxw;
677 if (f->fmt.pix.height > maxh)
678 f->fmt.pix.height = maxh;
679
680 calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
681
682 if (f->fmt.pix.bytesperline < calc_bpl)
683 f->fmt.pix.bytesperline = calc_bpl;
684
685 if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
686 f->fmt.pix.bytesperline = calc_bpl;
687
688 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
689 DEB_D("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",
690 f->fmt.pix.width, f->fmt.pix.height,
691 f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
692
693 return 0;
694}
695
696
697static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
698{
699 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
700 struct saa7146_vv *vv = dev->vv_data;
701 struct v4l2_window *win = &f->fmt.win;
702 enum v4l2_field field;
703 int maxw, maxh;
704
705 DEB_EE("dev:%p\n", dev);
706
707 if (NULL == vv->ov_fb.base) {
708 DEB_D("no fb base set\n");
709 return -EINVAL;
710 }
711 if (NULL == vv->ov_fmt) {
712 DEB_D("no fb fmt set\n");
713 return -EINVAL;
714 }
715 if (win->w.width < 48 || win->w.height < 32) {
716 DEB_D("min width/height. (%d,%d)\n",
717 win->w.width, win->w.height);
718 return -EINVAL;
719 }
720 if (win->clipcount > 16) {
721 DEB_D("clipcount too big\n");
722 return -EINVAL;
723 }
724
725 field = win->field;
726 maxw = vv->standard->h_max_out;
727 maxh = vv->standard->v_max_out;
728
729 if (V4L2_FIELD_ANY == field) {
730 field = (win->w.height > maxh / 2)
731 ? V4L2_FIELD_INTERLACED
732 : V4L2_FIELD_TOP;
733 }
734 switch (field) {
735 case V4L2_FIELD_TOP:
736 case V4L2_FIELD_BOTTOM:
737 case V4L2_FIELD_ALTERNATE:
738 maxh = maxh / 2;
739 break;
740 case V4L2_FIELD_INTERLACED:
741 break;
742 default:
743 DEB_D("no known field mode '%d'\n", field);
744 return -EINVAL;
745 }
746
747 win->field = field;
748 if (win->w.width > maxw)
749 win->w.width = maxw;
750 if (win->w.height > maxh)
751 win->w.height = maxh;
752
753 return 0;
754}
755
756static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
757{
758 struct saa7146_fh *fh = __fh;
759 struct saa7146_dev *dev = fh->dev;
760 struct saa7146_vv *vv = dev->vv_data;
761 int err;
762
763 DEB_EE("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh);
764 if (IS_CAPTURE_ACTIVE(fh) != 0) {
765 DEB_EE("streaming capture is active\n");
766 return -EBUSY;
767 }
768 err = vidioc_try_fmt_vid_cap(file, fh, f);
769 if (0 != err)
770 return err;
771 vv->video_fmt = f->fmt.pix;
772 DEB_EE("set to pixelformat '%4.4s'\n",
773 (char *)&vv->video_fmt.pixelformat);
774 return 0;
775}
776
777static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
778{
779 struct saa7146_fh *fh = __fh;
780 struct saa7146_dev *dev = fh->dev;
781 struct saa7146_vv *vv = dev->vv_data;
782 int err;
783
784 DEB_EE("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh);
785 err = vidioc_try_fmt_vid_overlay(file, fh, f);
786 if (0 != err)
787 return err;
788 vv->ov.win = f->fmt.win;
789 vv->ov.nclips = f->fmt.win.clipcount;
790 if (vv->ov.nclips > 16)
791 vv->ov.nclips = 16;
792 if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
793 sizeof(struct v4l2_clip) * vv->ov.nclips)) {
794 return -EFAULT;
795 }
796
797 /* vv->ov.fh is used to indicate that we have valid overlay informations, too */
798 vv->ov.fh = fh;
799
800 /* check if our current overlay is active */
801 if (IS_OVERLAY_ACTIVE(fh) != 0) {
802 saa7146_stop_preview(fh);
803 saa7146_start_preview(fh);
804 }
805 return 0;
806}
807
808static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
809{
810 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
811 struct saa7146_vv *vv = dev->vv_data;
812
813 *norm = vv->standard->id;
814 return 0;
815}
816
817 /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
818 PAL / NTSC / SECAM. if your hardware does not (or does more)
819 -- override this function in your extension */
820/*
821 case VIDIOC_ENUMSTD:
822 {
823 struct v4l2_standard *e = arg;
824 if (e->index < 0 )
825 return -EINVAL;
826 if( e->index < dev->ext_vv_data->num_stds ) {
827 DEB_EE("VIDIOC_ENUMSTD: index:%d\n", e->index);
828 v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
829 return 0;
830 }
831 return -EINVAL;
832 }
833 */
834
835static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
836{
837 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
838 struct saa7146_vv *vv = dev->vv_data;
839 int found = 0;
840 int err, i;
841
842 DEB_EE("VIDIOC_S_STD\n");
843
844 if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
845 DEB_D("cannot change video standard while streaming capture is active\n");
846 return -EBUSY;
847 }
848
849 if ((vv->video_status & STATUS_OVERLAY) != 0) {
850 vv->ov_suspend = vv->video_fh;
851 err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
852 if (0 != err) {
853 DEB_D("suspending video failed. aborting\n");
854 return err;
855 }
856 }
857
858 for (i = 0; i < dev->ext_vv_data->num_stds; i++)
859 if (*id & dev->ext_vv_data->stds[i].id)
860 break;
861 if (i != dev->ext_vv_data->num_stds) {
862 vv->standard = &dev->ext_vv_data->stds[i];
863 if (NULL != dev->ext_vv_data->std_callback)
864 dev->ext_vv_data->std_callback(dev, vv->standard);
865 found = 1;
866 }
867
868 if (vv->ov_suspend != NULL) {
869 saa7146_start_preview(vv->ov_suspend);
870 vv->ov_suspend = NULL;
871 }
872
873 if (!found) {
874 DEB_EE("VIDIOC_S_STD: standard not found\n");
875 return -EINVAL;
876 }
877
878 DEB_EE("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name);
879 return 0;
880}
881
882static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
883{
884 int err;
885
886 DEB_D("VIDIOC_OVERLAY on:%d\n", on);
887 if (on)
888 err = saa7146_start_preview(fh);
889 else
890 err = saa7146_stop_preview(fh);
891 return err;
892}
893
894static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
895{
896 struct saa7146_fh *fh = __fh;
897
898 if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
899 return videobuf_reqbufs(&fh->video_q, b);
900 if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
901 return videobuf_reqbufs(&fh->vbi_q, b);
902 return -EINVAL;
903}
904
905static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
906{
907 struct saa7146_fh *fh = __fh;
908
909 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
910 return videobuf_querybuf(&fh->video_q, buf);
911 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
912 return videobuf_querybuf(&fh->vbi_q, buf);
913 return -EINVAL;
914}
915
916static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
917{
918 struct saa7146_fh *fh = __fh;
919
920 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
921 return videobuf_qbuf(&fh->video_q, buf);
922 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
923 return videobuf_qbuf(&fh->vbi_q, buf);
924 return -EINVAL;
925}
926
927static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
928{
929 struct saa7146_fh *fh = __fh;
930
931 if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
932 return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
933 if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
934 return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
935 return -EINVAL;
936}
937
938static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
939{
940 struct saa7146_fh *fh = __fh;
941 int err;
942
943 DEB_D("VIDIOC_STREAMON, type:%d\n", type);
944
945 err = video_begin(fh);
946 if (err)
947 return err;
948 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
949 return videobuf_streamon(&fh->video_q);
950 if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
951 return videobuf_streamon(&fh->vbi_q);
952 return -EINVAL;
953}
954
955static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
956{
957 struct saa7146_fh *fh = __fh;
958 struct saa7146_dev *dev = fh->dev;
959 struct saa7146_vv *vv = dev->vv_data;
960 int err;
961
962 DEB_D("VIDIOC_STREAMOFF, type:%d\n", type);
963
964 /* ugly: we need to copy some checks from video_end(),
965 because videobuf_streamoff() relies on the capture running.
966 check and fix this */
967 if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
968 DEB_S("not capturing\n");
969 return 0;
970 }
971
972 if (vv->video_fh != fh) {
973 DEB_S("capturing, but in another open\n");
974 return -EBUSY;
975 }
976
977 err = -EINVAL;
978 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
979 err = videobuf_streamoff(&fh->video_q);
980 else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
981 err = videobuf_streamoff(&fh->vbi_q);
982 if (0 != err) {
983 DEB_D("warning: videobuf_streamoff() failed\n");
984 video_end(fh, file);
985 } else {
986 err = video_end(fh, file);
987 }
988 return err;
989}
990
991static int vidioc_g_chip_ident(struct file *file, void *__fh,
992 struct v4l2_dbg_chip_ident *chip)
993{
994 struct saa7146_fh *fh = __fh;
995 struct saa7146_dev *dev = fh->dev;
996
997 chip->ident = V4L2_IDENT_NONE;
998 chip->revision = 0;
999 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
1000 if (v4l2_chip_match_host(&chip->match))
1001 chip->ident = V4L2_IDENT_SAA7146;
1002 return 0;
1003 }
1004 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1005 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
1006 return -EINVAL;
1007 return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1008 core, g_chip_ident, chip);
1009}
1010
1011const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1012 .vidioc_querycap = vidioc_querycap,
1013 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1014 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
1015 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1016 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1017 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1018 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1019 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1020 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1021 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1022
1023 .vidioc_overlay = vidioc_overlay,
1024 .vidioc_g_fbuf = vidioc_g_fbuf,
1025 .vidioc_s_fbuf = vidioc_s_fbuf,
1026 .vidioc_reqbufs = vidioc_reqbufs,
1027 .vidioc_querybuf = vidioc_querybuf,
1028 .vidioc_qbuf = vidioc_qbuf,
1029 .vidioc_dqbuf = vidioc_dqbuf,
1030 .vidioc_g_std = vidioc_g_std,
1031 .vidioc_s_std = vidioc_s_std,
1032 .vidioc_streamon = vidioc_streamon,
1033 .vidioc_streamoff = vidioc_streamoff,
1034 .vidioc_g_parm = vidioc_g_parm,
1035 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1036 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1037};
1038
1039const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
1040 .vidioc_querycap = vidioc_querycap,
1041 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1042 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1043
1044 .vidioc_reqbufs = vidioc_reqbufs,
1045 .vidioc_querybuf = vidioc_querybuf,
1046 .vidioc_qbuf = vidioc_qbuf,
1047 .vidioc_dqbuf = vidioc_dqbuf,
1048 .vidioc_g_std = vidioc_g_std,
1049 .vidioc_s_std = vidioc_s_std,
1050 .vidioc_streamon = vidioc_streamon,
1051 .vidioc_streamoff = vidioc_streamoff,
1052 .vidioc_g_parm = vidioc_g_parm,
1053 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1054 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1055};
1056
1057/*********************************************************************************/
1058/* buffer handling functions */
1059
1060static int buffer_activate (struct saa7146_dev *dev,
1061 struct saa7146_buf *buf,
1062 struct saa7146_buf *next)
1063{
1064 struct saa7146_vv *vv = dev->vv_data;
1065
1066 buf->vb.state = VIDEOBUF_ACTIVE;
1067 saa7146_set_capture(dev,buf,next);
1068
1069 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
1070 return 0;
1071}
1072
1073static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
1074{
1075 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1076 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1077 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1078}
1079
1080static int buffer_prepare(struct videobuf_queue *q,
1081 struct videobuf_buffer *vb, enum v4l2_field field)
1082{
1083 struct file *file = q->priv_data;
1084 struct saa7146_fh *fh = file->private_data;
1085 struct saa7146_dev *dev = fh->dev;
1086 struct saa7146_vv *vv = dev->vv_data;
1087 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1088 int size,err = 0;
1089
1090 DEB_CAP("vbuf:%p\n", vb);
1091
1092 /* sanity checks */
1093 if (vv->video_fmt.width < 48 ||
1094 vv->video_fmt.height < 32 ||
1095 vv->video_fmt.width > vv->standard->h_max_out ||
1096 vv->video_fmt.height > vv->standard->v_max_out) {
1097 DEB_D("w (%d) / h (%d) out of bounds\n",
1098 vv->video_fmt.width, vv->video_fmt.height);
1099 return -EINVAL;
1100 }
1101
1102 size = vv->video_fmt.sizeimage;
1103 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1104 DEB_D("size mismatch\n");
1105 return -EINVAL;
1106 }
1107
1108 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1109 vv->video_fmt.width, vv->video_fmt.height,
1110 size, v4l2_field_names[vv->video_fmt.field]);
1111 if (buf->vb.width != vv->video_fmt.width ||
1112 buf->vb.bytesperline != vv->video_fmt.bytesperline ||
1113 buf->vb.height != vv->video_fmt.height ||
1114 buf->vb.size != size ||
1115 buf->vb.field != field ||
1116 buf->vb.field != vv->video_fmt.field ||
1117 buf->fmt != &vv->video_fmt) {
1118 saa7146_dma_free(dev,q,buf);
1119 }
1120
1121 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1122 struct saa7146_format *sfmt;
1123
1124 buf->vb.bytesperline = vv->video_fmt.bytesperline;
1125 buf->vb.width = vv->video_fmt.width;
1126 buf->vb.height = vv->video_fmt.height;
1127 buf->vb.size = size;
1128 buf->vb.field = field;
1129 buf->fmt = &vv->video_fmt;
1130 buf->vb.field = vv->video_fmt.field;
1131
1132 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1133
1134 release_all_pagetables(dev, buf);
1135 if( 0 != IS_PLANAR(sfmt->trans)) {
1136 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1137 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1138 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1139 } else {
1140 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1141 }
1142
1143 err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
1144 if (err)
1145 goto oops;
1146 err = saa7146_pgtable_build(dev,buf);
1147 if (err)
1148 goto oops;
1149 }
1150 buf->vb.state = VIDEOBUF_PREPARED;
1151 buf->activate = buffer_activate;
1152
1153 return 0;
1154
1155 oops:
1156 DEB_D("error out\n");
1157 saa7146_dma_free(dev,q,buf);
1158
1159 return err;
1160}
1161
1162static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1163{
1164 struct file *file = q->priv_data;
1165 struct saa7146_fh *fh = file->private_data;
1166 struct saa7146_vv *vv = fh->dev->vv_data;
1167
1168 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1169 *count = MAX_SAA7146_CAPTURE_BUFFERS;
1170
1171 *size = vv->video_fmt.sizeimage;
1172
1173 /* check if we exceed the "max_memory" parameter */
1174 if( (*count * *size) > (max_memory*1048576) ) {
1175 *count = (max_memory*1048576) / *size;
1176 }
1177
1178 DEB_CAP("%d buffers, %d bytes each\n", *count, *size);
1179
1180 return 0;
1181}
1182
1183static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1184{
1185 struct file *file = q->priv_data;
1186 struct saa7146_fh *fh = file->private_data;
1187 struct saa7146_dev *dev = fh->dev;
1188 struct saa7146_vv *vv = dev->vv_data;
1189 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1190
1191 DEB_CAP("vbuf:%p\n", vb);
1192 saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
1193}
1194
1195static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1196{
1197 struct file *file = q->priv_data;
1198 struct saa7146_fh *fh = file->private_data;
1199 struct saa7146_dev *dev = fh->dev;
1200 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1201
1202 DEB_CAP("vbuf:%p\n", vb);
1203
1204 saa7146_dma_free(dev,q,buf);
1205
1206 release_all_pagetables(dev, buf);
1207}
1208
1209static struct videobuf_queue_ops video_qops = {
1210 .buf_setup = buffer_setup,
1211 .buf_prepare = buffer_prepare,
1212 .buf_queue = buffer_queue,
1213 .buf_release = buffer_release,
1214};
1215
1216/********************************************************************************/
1217/* file operations */
1218
1219static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1220{
1221 INIT_LIST_HEAD(&vv->video_dmaq.queue);
1222
1223 init_timer(&vv->video_dmaq.timeout);
1224 vv->video_dmaq.timeout.function = saa7146_buffer_timeout;
1225 vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq);
1226 vv->video_dmaq.dev = dev;
1227
1228 /* set some default values */
1229 vv->standard = &dev->ext_vv_data->stds[0];
1230
1231 /* FIXME: what's this? */
1232 vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
1233 vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
1234}
1235
1236
1237static int video_open(struct saa7146_dev *dev, struct file *file)
1238{
1239 struct saa7146_fh *fh = file->private_data;
1240
1241 videobuf_queue_sg_init(&fh->video_q, &video_qops,
1242 &dev->pci->dev, &dev->slock,
1243 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1244 V4L2_FIELD_INTERLACED,
1245 sizeof(struct saa7146_buf),
1246 file, &dev->v4l2_lock);
1247
1248 return 0;
1249}
1250
1251
1252static void video_close(struct saa7146_dev *dev, struct file *file)
1253{
1254 struct saa7146_fh *fh = file->private_data;
1255 struct saa7146_vv *vv = dev->vv_data;
1256 struct videobuf_queue *q = &fh->video_q;
1257
1258 if (IS_CAPTURE_ACTIVE(fh) != 0)
1259 video_end(fh, file);
1260 else if (IS_OVERLAY_ACTIVE(fh) != 0)
1261 saa7146_stop_preview(fh);
1262
1263 videobuf_stop(q);
1264 /* hmm, why is this function declared void? */
1265}
1266
1267
1268static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1269{
1270 struct saa7146_vv *vv = dev->vv_data;
1271 struct saa7146_dmaqueue *q = &vv->video_dmaq;
1272
1273 spin_lock(&dev->slock);
1274 DEB_CAP("called\n");
1275
1276 /* only finish the buffer if we have one... */
1277 if( NULL != q->curr ) {
1278 saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
1279 }
1280 saa7146_buffer_next(dev,q,0);
1281
1282 spin_unlock(&dev->slock);
1283}
1284
1285static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1286{
1287 struct saa7146_fh *fh = file->private_data;
1288 struct saa7146_dev *dev = fh->dev;
1289 struct saa7146_vv *vv = dev->vv_data;
1290 ssize_t ret = 0;
1291
1292 DEB_EE("called\n");
1293
1294 if ((vv->video_status & STATUS_CAPTURE) != 0) {
1295 /* fixme: should we allow read() captures while streaming capture? */
1296 if (vv->video_fh == fh) {
1297 DEB_S("already capturing\n");
1298 return -EBUSY;
1299 }
1300 DEB_S("already capturing in another open\n");
1301 return -EBUSY;
1302 }
1303
1304 ret = video_begin(fh);
1305 if( 0 != ret) {
1306 goto out;
1307 }
1308
1309 ret = videobuf_read_one(&fh->video_q , data, count, ppos,
1310 file->f_flags & O_NONBLOCK);
1311 if (ret != 0) {
1312 video_end(fh, file);
1313 } else {
1314 ret = video_end(fh, file);
1315 }
1316out:
1317 /* restart overlay if it was active before */
1318 if (vv->ov_suspend != NULL) {
1319 saa7146_start_preview(vv->ov_suspend);
1320 vv->ov_suspend = NULL;
1321 }
1322
1323 return ret;
1324}
1325
1326struct saa7146_use_ops saa7146_video_uops = {
1327 .init = video_init,
1328 .open = video_open,
1329 .release = video_close,
1330 .irq_done = video_irq_done,
1331 .read = video_read,
1332};
diff --git a/drivers/media/common/siano/Kconfig b/drivers/media/common/siano/Kconfig
deleted file mode 100644
index 68f0f604678..00000000000
--- a/drivers/media/common/siano/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
1#
2# Siano Mobile Silicon Digital TV device configuration
3#
4
5config SMS_SIANO_MDTV
6 tristate
7 depends on DVB_CORE && HAS_DMA
8 depends on !RC_CORE || RC_CORE
9 depends on SMS_USB_DRV || SMS_SDIO_DRV
10 default y
11
12config SMS_SIANO_RC
13 bool "Enable Remote Controller support for Siano devices"
14 depends on SMS_SIANO_MDTV && RC_CORE
15 depends on SMS_USB_DRV || SMS_SDIO_DRV
16 depends on MEDIA_COMMON_OPTIONS
17 default y
18 ---help---
19 Choose Y to select Remote Controller support for Siano driver.
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
deleted file mode 100644
index 81b1e985bea..00000000000
--- a/drivers/media/common/siano/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
2
3obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
4
5ifeq ($(CONFIG_SMS_SIANO_RC),y)
6 smsmdtv-objs += smsir.o
7endif
8
9ccflags-y += -Idrivers/media/dvb-core
10ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
11
diff --git a/drivers/media/common/siano/sms-cards.c b/drivers/media/common/siano/sms-cards.c
deleted file mode 100644
index 680c781c8dd..00000000000
--- a/drivers/media/common/siano/sms-cards.c
+++ /dev/null
@@ -1,311 +0,0 @@
1/*
2 * Card-specific functions for the Siano SMS1xxx USB dongle
3 *
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
12 *
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include "sms-cards.h"
21#include "smsir.h"
22#include <linux/module.h>
23
24static int sms_dbg;
25module_param_named(cards_dbg, sms_dbg, int, 0644);
26MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
27
28static struct sms_board sms_boards[] = {
29 [SMS_BOARD_UNKNOWN] = {
30 .name = "Unknown board",
31 },
32 [SMS1XXX_BOARD_SIANO_STELLAR] = {
33 .name = "Siano Stellar Digital Receiver",
34 .type = SMS_STELLAR,
35 },
36 [SMS1XXX_BOARD_SIANO_NOVA_A] = {
37 .name = "Siano Nova A Digital Receiver",
38 .type = SMS_NOVA_A0,
39 },
40 [SMS1XXX_BOARD_SIANO_NOVA_B] = {
41 .name = "Siano Nova B Digital Receiver",
42 .type = SMS_NOVA_B0,
43 },
44 [SMS1XXX_BOARD_SIANO_VEGA] = {
45 .name = "Siano Vega Digital Receiver",
46 .type = SMS_VEGA,
47 },
48 [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
49 .name = "Hauppauge Catamount",
50 .type = SMS_STELLAR,
51 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
52 },
53 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
54 .name = "Hauppauge Okemo-A",
55 .type = SMS_NOVA_A0,
56 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
57 },
58 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
59 .name = "Hauppauge Okemo-B",
60 .type = SMS_NOVA_B0,
61 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
62 },
63 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
64 .name = "Hauppauge WinTV MiniStick",
65 .type = SMS_NOVA_B0,
66 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
67 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
68 .rc_codes = RC_MAP_HAUPPAUGE,
69 .board_cfg.leds_power = 26,
70 .board_cfg.led0 = 27,
71 .board_cfg.led1 = 28,
72 .board_cfg.ir = 9,
73 .led_power = 26,
74 .led_lo = 27,
75 .led_hi = 28,
76 },
77 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
78 .name = "Hauppauge WinTV MiniCard",
79 .type = SMS_NOVA_B0,
80 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
81 .lna_ctrl = 29,
82 .board_cfg.foreign_lna0_ctrl = 29,
83 .rf_switch = 17,
84 .board_cfg.rf_switch_uhf = 17,
85 },
86 [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
87 .name = "Hauppauge WinTV MiniCard",
88 .type = SMS_NOVA_B0,
89 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
90 .lna_ctrl = -1,
91 },
92 [SMS1XXX_BOARD_SIANO_NICE] = {
93 /* 11 */
94 .name = "Siano Nice Digital Receiver",
95 .type = SMS_NOVA_B0,
96 },
97 [SMS1XXX_BOARD_SIANO_VENICE] = {
98 /* 12 */
99 .name = "Siano Venice Digital Receiver",
100 .type = SMS_VEGA,
101 },
102};
103
104struct sms_board *sms_get_board(unsigned id)
105{
106 BUG_ON(id >= ARRAY_SIZE(sms_boards));
107
108 return &sms_boards[id];
109}
110EXPORT_SYMBOL_GPL(sms_get_board);
111static inline void sms_gpio_assign_11xx_default_led_config(
112 struct smscore_gpio_config *pGpioConfig) {
113 pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
114 pGpioConfig->InputCharacteristics =
115 SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
116 pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
117 pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
118 pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
119}
120
121int sms_board_event(struct smscore_device_t *coredev,
122 enum SMS_BOARD_EVENTS gevent) {
123 struct smscore_gpio_config MyGpioConfig;
124
125 sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
126
127 switch (gevent) {
128 case BOARD_EVENT_POWER_INIT: /* including hotplug */
129 break; /* BOARD_EVENT_BIND */
130
131 case BOARD_EVENT_POWER_SUSPEND:
132 break; /* BOARD_EVENT_POWER_SUSPEND */
133
134 case BOARD_EVENT_POWER_RESUME:
135 break; /* BOARD_EVENT_POWER_RESUME */
136
137 case BOARD_EVENT_BIND:
138 break; /* BOARD_EVENT_BIND */
139
140 case BOARD_EVENT_SCAN_PROG:
141 break; /* BOARD_EVENT_SCAN_PROG */
142 case BOARD_EVENT_SCAN_COMP:
143 break; /* BOARD_EVENT_SCAN_COMP */
144 case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
145 break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
146 case BOARD_EVENT_FE_LOCK:
147 break; /* BOARD_EVENT_FE_LOCK */
148 case BOARD_EVENT_FE_UNLOCK:
149 break; /* BOARD_EVENT_FE_UNLOCK */
150 case BOARD_EVENT_DEMOD_LOCK:
151 break; /* BOARD_EVENT_DEMOD_LOCK */
152 case BOARD_EVENT_DEMOD_UNLOCK:
153 break; /* BOARD_EVENT_DEMOD_UNLOCK */
154 case BOARD_EVENT_RECEPTION_MAX_4:
155 break; /* BOARD_EVENT_RECEPTION_MAX_4 */
156 case BOARD_EVENT_RECEPTION_3:
157 break; /* BOARD_EVENT_RECEPTION_3 */
158 case BOARD_EVENT_RECEPTION_2:
159 break; /* BOARD_EVENT_RECEPTION_2 */
160 case BOARD_EVENT_RECEPTION_1:
161 break; /* BOARD_EVENT_RECEPTION_1 */
162 case BOARD_EVENT_RECEPTION_LOST_0:
163 break; /* BOARD_EVENT_RECEPTION_LOST_0 */
164 case BOARD_EVENT_MULTIPLEX_OK:
165 break; /* BOARD_EVENT_MULTIPLEX_OK */
166 case BOARD_EVENT_MULTIPLEX_ERRORS:
167 break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
168
169 default:
170 sms_err("Unknown SMS board event");
171 break;
172 }
173 return 0;
174}
175EXPORT_SYMBOL_GPL(sms_board_event);
176
177static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
178{
179 int lvl, ret;
180 u32 gpio;
181 struct smscore_config_gpio gpioconfig = {
182 .direction = SMS_GPIO_DIRECTION_OUTPUT,
183 .pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
184 .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
185 .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
186 .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
187 };
188
189 if (pin == 0)
190 return -EINVAL;
191
192 if (pin < 0) {
193 /* inverted gpio */
194 gpio = pin * -1;
195 lvl = enable ? 0 : 1;
196 } else {
197 gpio = pin;
198 lvl = enable ? 1 : 0;
199 }
200
201 ret = smscore_configure_gpio(coredev, gpio, &gpioconfig);
202 if (ret < 0)
203 return ret;
204
205 return smscore_set_gpio(coredev, gpio, lvl);
206}
207
208int sms_board_setup(struct smscore_device_t *coredev)
209{
210 int board_id = smscore_get_board_id(coredev);
211 struct sms_board *board = sms_get_board(board_id);
212
213 switch (board_id) {
214 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
215 /* turn off all LEDs */
216 sms_set_gpio(coredev, board->led_power, 0);
217 sms_set_gpio(coredev, board->led_hi, 0);
218 sms_set_gpio(coredev, board->led_lo, 0);
219 break;
220 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
221 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
222 /* turn off LNA */
223 sms_set_gpio(coredev, board->lna_ctrl, 0);
224 break;
225 }
226 return 0;
227}
228EXPORT_SYMBOL_GPL(sms_board_setup);
229
230int sms_board_power(struct smscore_device_t *coredev, int onoff)
231{
232 int board_id = smscore_get_board_id(coredev);
233 struct sms_board *board = sms_get_board(board_id);
234
235 switch (board_id) {
236 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
237 /* power LED */
238 sms_set_gpio(coredev,
239 board->led_power, onoff ? 1 : 0);
240 break;
241 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
242 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
243 /* LNA */
244 if (!onoff)
245 sms_set_gpio(coredev, board->lna_ctrl, 0);
246 break;
247 }
248 return 0;
249}
250EXPORT_SYMBOL_GPL(sms_board_power);
251
252int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
253{
254 int board_id = smscore_get_board_id(coredev);
255 struct sms_board *board = sms_get_board(board_id);
256
257 /* dont touch GPIO if LEDs are already set */
258 if (smscore_led_state(coredev, -1) == led)
259 return 0;
260
261 switch (board_id) {
262 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
263 sms_set_gpio(coredev,
264 board->led_lo, (led & SMS_LED_LO) ? 1 : 0);
265 sms_set_gpio(coredev,
266 board->led_hi, (led & SMS_LED_HI) ? 1 : 0);
267
268 smscore_led_state(coredev, led);
269 break;
270 }
271 return 0;
272}
273EXPORT_SYMBOL_GPL(sms_board_led_feedback);
274
275int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
276{
277 int board_id = smscore_get_board_id(coredev);
278 struct sms_board *board = sms_get_board(board_id);
279
280 sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
281
282 switch (board_id) {
283 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
284 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
285 sms_set_gpio(coredev,
286 board->rf_switch, onoff ? 1 : 0);
287 return sms_set_gpio(coredev,
288 board->lna_ctrl, onoff ? 1 : 0);
289 }
290 return -EINVAL;
291}
292EXPORT_SYMBOL_GPL(sms_board_lna_control);
293
294int sms_board_load_modules(int id)
295{
296 switch (id) {
297 case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
298 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
299 case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
300 case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
301 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
302 case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
303 request_module("smsdvb");
304 break;
305 default:
306 /* do nothing */
307 break;
308 }
309 return 0;
310}
311EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/common/siano/sms-cards.h b/drivers/media/common/siano/sms-cards.h
deleted file mode 100644
index d8cdf756f7c..00000000000
--- a/drivers/media/common/siano/sms-cards.h
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Card-specific functions for the Siano SMS1xxx USB dongle
3 *
4 * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation;
9 *
10 * Software distributed under the License is distributed on an "AS IS"
11 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
12 *
13 * See the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef __SMS_CARDS_H__
21#define __SMS_CARDS_H__
22
23#include <linux/usb.h>
24#include "smscoreapi.h"
25#include "smsir.h"
26
27#define SMS_BOARD_UNKNOWN 0
28#define SMS1XXX_BOARD_SIANO_STELLAR 1
29#define SMS1XXX_BOARD_SIANO_NOVA_A 2
30#define SMS1XXX_BOARD_SIANO_NOVA_B 3
31#define SMS1XXX_BOARD_SIANO_VEGA 4
32#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
33#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
34#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
35#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
36#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9
37#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
38#define SMS1XXX_BOARD_SIANO_NICE 11
39#define SMS1XXX_BOARD_SIANO_VENICE 12
40
41struct sms_board_gpio_cfg {
42 int lna_vhf_exist;
43 int lna_vhf_ctrl;
44 int lna_uhf_exist;
45 int lna_uhf_ctrl;
46 int lna_uhf_d_ctrl;
47 int lna_sband_exist;
48 int lna_sband_ctrl;
49 int lna_sband_d_ctrl;
50 int foreign_lna0_ctrl;
51 int foreign_lna1_ctrl;
52 int foreign_lna2_ctrl;
53 int rf_switch_vhf;
54 int rf_switch_uhf;
55 int rf_switch_sband;
56 int leds_power;
57 int led0;
58 int led1;
59 int led2;
60 int led3;
61 int led4;
62 int ir;
63 int eeprom_wp;
64 int mrc_sense;
65 int mrc_pdn_resetn;
66 int mrc_gp0; /* mrcs spi int */
67 int mrc_gp1;
68 int mrc_gp2;
69 int mrc_gp3;
70 int mrc_gp4;
71 int host_spi_gsp_ts_int;
72};
73
74struct sms_board {
75 enum sms_device_type_st type;
76 char *name, *fw[DEVICE_MODE_MAX];
77 struct sms_board_gpio_cfg board_cfg;
78 char *rc_codes; /* Name of IR codes table */
79
80 /* gpios */
81 int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
82};
83
84struct sms_board *sms_get_board(unsigned id);
85
86extern struct smscore_device_t *coredev;
87
88enum SMS_BOARD_EVENTS {
89 BOARD_EVENT_POWER_INIT,
90 BOARD_EVENT_POWER_SUSPEND,
91 BOARD_EVENT_POWER_RESUME,
92 BOARD_EVENT_BIND,
93 BOARD_EVENT_SCAN_PROG,
94 BOARD_EVENT_SCAN_COMP,
95 BOARD_EVENT_EMERGENCY_WARNING_SIGNAL,
96 BOARD_EVENT_FE_LOCK,
97 BOARD_EVENT_FE_UNLOCK,
98 BOARD_EVENT_DEMOD_LOCK,
99 BOARD_EVENT_DEMOD_UNLOCK,
100 BOARD_EVENT_RECEPTION_MAX_4,
101 BOARD_EVENT_RECEPTION_3,
102 BOARD_EVENT_RECEPTION_2,
103 BOARD_EVENT_RECEPTION_1,
104 BOARD_EVENT_RECEPTION_LOST_0,
105 BOARD_EVENT_MULTIPLEX_OK,
106 BOARD_EVENT_MULTIPLEX_ERRORS
107};
108
109int sms_board_event(struct smscore_device_t *coredev,
110 enum SMS_BOARD_EVENTS gevent);
111
112int sms_board_setup(struct smscore_device_t *coredev);
113
114#define SMS_LED_OFF 0
115#define SMS_LED_LO 1
116#define SMS_LED_HI 2
117int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
118int sms_board_power(struct smscore_device_t *coredev, int onoff);
119int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
120
121extern int sms_board_load_modules(int id);
122
123#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c
deleted file mode 100644
index 1842e64e633..00000000000
--- a/drivers/media/common/siano/smscoreapi.c
+++ /dev/null
@@ -1,1637 +0,0 @@
1/*
2 * Siano core API module
3 *
4 * This file contains implementation for the interface to sms core component
5 *
6 * author: Uri Shkolnik
7 *
8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation;
13 *
14 * Software distributed under the License is distributed on an "AS IS"
15 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
16 *
17 * See the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/dma-mapping.h>
29#include <linux/delay.h>
30#include <linux/io.h>
31#include <linux/slab.h>
32
33#include <linux/firmware.h>
34#include <linux/wait.h>
35#include <asm/byteorder.h>
36
37#include "smscoreapi.h"
38#include "sms-cards.h"
39#include "smsir.h"
40#include "smsendian.h"
41
42static int sms_dbg;
43module_param_named(debug, sms_dbg, int, 0644);
44MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
45
46struct smscore_device_notifyee_t {
47 struct list_head entry;
48 hotplug_t hotplug;
49};
50
51struct smscore_idlist_t {
52 struct list_head entry;
53 int id;
54 int data_type;
55};
56
57struct smscore_client_t {
58 struct list_head entry;
59 struct smscore_device_t *coredev;
60 void *context;
61 struct list_head idlist;
62 onresponse_t onresponse_handler;
63 onremove_t onremove_handler;
64};
65
66void smscore_set_board_id(struct smscore_device_t *core, int id)
67{
68 core->board_id = id;
69}
70
71int smscore_led_state(struct smscore_device_t *core, int led)
72{
73 if (led >= 0)
74 core->led_state = led;
75 return core->led_state;
76}
77EXPORT_SYMBOL_GPL(smscore_set_board_id);
78
79int smscore_get_board_id(struct smscore_device_t *core)
80{
81 return core->board_id;
82}
83EXPORT_SYMBOL_GPL(smscore_get_board_id);
84
85struct smscore_registry_entry_t {
86 struct list_head entry;
87 char devpath[32];
88 int mode;
89 enum sms_device_type_st type;
90};
91
92static struct list_head g_smscore_notifyees;
93static struct list_head g_smscore_devices;
94static struct mutex g_smscore_deviceslock;
95
96static struct list_head g_smscore_registry;
97static struct mutex g_smscore_registrylock;
98
99static int default_mode = 4;
100
101module_param(default_mode, int, 0644);
102MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
103
104static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
105{
106 struct smscore_registry_entry_t *entry;
107 struct list_head *next;
108
109 kmutex_lock(&g_smscore_registrylock);
110 for (next = g_smscore_registry.next;
111 next != &g_smscore_registry;
112 next = next->next) {
113 entry = (struct smscore_registry_entry_t *) next;
114 if (!strcmp(entry->devpath, devpath)) {
115 kmutex_unlock(&g_smscore_registrylock);
116 return entry;
117 }
118 }
119 entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
120 if (entry) {
121 entry->mode = default_mode;
122 strcpy(entry->devpath, devpath);
123 list_add(&entry->entry, &g_smscore_registry);
124 } else
125 sms_err("failed to create smscore_registry.");
126 kmutex_unlock(&g_smscore_registrylock);
127 return entry;
128}
129
130int smscore_registry_getmode(char *devpath)
131{
132 struct smscore_registry_entry_t *entry;
133
134 entry = smscore_find_registry(devpath);
135 if (entry)
136 return entry->mode;
137 else
138 sms_err("No registry found.");
139
140 return default_mode;
141}
142EXPORT_SYMBOL_GPL(smscore_registry_getmode);
143
144static enum sms_device_type_st smscore_registry_gettype(char *devpath)
145{
146 struct smscore_registry_entry_t *entry;
147
148 entry = smscore_find_registry(devpath);
149 if (entry)
150 return entry->type;
151 else
152 sms_err("No registry found.");
153
154 return -1;
155}
156
157void smscore_registry_setmode(char *devpath, int mode)
158{
159 struct smscore_registry_entry_t *entry;
160
161 entry = smscore_find_registry(devpath);
162 if (entry)
163 entry->mode = mode;
164 else
165 sms_err("No registry found.");
166}
167
168static void smscore_registry_settype(char *devpath,
169 enum sms_device_type_st type)
170{
171 struct smscore_registry_entry_t *entry;
172
173 entry = smscore_find_registry(devpath);
174 if (entry)
175 entry->type = type;
176 else
177 sms_err("No registry found.");
178}
179
180
181static void list_add_locked(struct list_head *new, struct list_head *head,
182 spinlock_t *lock)
183{
184 unsigned long flags;
185
186 spin_lock_irqsave(lock, flags);
187
188 list_add(new, head);
189
190 spin_unlock_irqrestore(lock, flags);
191}
192
193/**
194 * register a client callback that called when device plugged in/unplugged
195 * NOTE: if devices exist callback is called immediately for each device
196 *
197 * @param hotplug callback
198 *
199 * @return 0 on success, <0 on error.
200 */
201int smscore_register_hotplug(hotplug_t hotplug)
202{
203 struct smscore_device_notifyee_t *notifyee;
204 struct list_head *next, *first;
205 int rc = 0;
206
207 kmutex_lock(&g_smscore_deviceslock);
208
209 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
210 GFP_KERNEL);
211 if (notifyee) {
212 /* now notify callback about existing devices */
213 first = &g_smscore_devices;
214 for (next = first->next;
215 next != first && !rc;
216 next = next->next) {
217 struct smscore_device_t *coredev =
218 (struct smscore_device_t *) next;
219 rc = hotplug(coredev, coredev->device, 1);
220 }
221
222 if (rc >= 0) {
223 notifyee->hotplug = hotplug;
224 list_add(&notifyee->entry, &g_smscore_notifyees);
225 } else
226 kfree(notifyee);
227 } else
228 rc = -ENOMEM;
229
230 kmutex_unlock(&g_smscore_deviceslock);
231
232 return rc;
233}
234EXPORT_SYMBOL_GPL(smscore_register_hotplug);
235
236/**
237 * unregister a client callback that called when device plugged in/unplugged
238 *
239 * @param hotplug callback
240 *
241 */
242void smscore_unregister_hotplug(hotplug_t hotplug)
243{
244 struct list_head *next, *first;
245
246 kmutex_lock(&g_smscore_deviceslock);
247
248 first = &g_smscore_notifyees;
249
250 for (next = first->next; next != first;) {
251 struct smscore_device_notifyee_t *notifyee =
252 (struct smscore_device_notifyee_t *) next;
253 next = next->next;
254
255 if (notifyee->hotplug == hotplug) {
256 list_del(&notifyee->entry);
257 kfree(notifyee);
258 }
259 }
260
261 kmutex_unlock(&g_smscore_deviceslock);
262}
263EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
264
265static void smscore_notify_clients(struct smscore_device_t *coredev)
266{
267 struct smscore_client_t *client;
268
269 /* the client must call smscore_unregister_client from remove handler */
270 while (!list_empty(&coredev->clients)) {
271 client = (struct smscore_client_t *) coredev->clients.next;
272 client->onremove_handler(client->context);
273 }
274}
275
276static int smscore_notify_callbacks(struct smscore_device_t *coredev,
277 struct device *device, int arrival)
278{
279 struct smscore_device_notifyee_t *elem;
280 int rc = 0;
281
282 /* note: must be called under g_deviceslock */
283
284 list_for_each_entry(elem, &g_smscore_notifyees, entry) {
285 rc = elem->hotplug(coredev, device, arrival);
286 if (rc < 0)
287 break;
288 }
289
290 return rc;
291}
292
293static struct
294smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
295 dma_addr_t common_buffer_phys)
296{
297 struct smscore_buffer_t *cb =
298 kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
299 if (!cb) {
300 sms_info("kmalloc(...) failed");
301 return NULL;
302 }
303
304 cb->p = buffer;
305 cb->offset_in_common = buffer - (u8 *) common_buffer;
306 cb->phys = common_buffer_phys + cb->offset_in_common;
307
308 return cb;
309}
310
311/**
312 * creates coredev object for a device, prepares buffers,
313 * creates buffer mappings, notifies registered hotplugs about new device.
314 *
315 * @param params device pointer to struct with device specific parameters
316 * and handlers
317 * @param coredev pointer to a value that receives created coredev object
318 *
319 * @return 0 on success, <0 on error.
320 */
321int smscore_register_device(struct smsdevice_params_t *params,
322 struct smscore_device_t **coredev)
323{
324 struct smscore_device_t *dev;
325 u8 *buffer;
326
327 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
328 if (!dev) {
329 sms_info("kzalloc(...) failed");
330 return -ENOMEM;
331 }
332
333 /* init list entry so it could be safe in smscore_unregister_device */
334 INIT_LIST_HEAD(&dev->entry);
335
336 /* init queues */
337 INIT_LIST_HEAD(&dev->clients);
338 INIT_LIST_HEAD(&dev->buffers);
339
340 /* init locks */
341 spin_lock_init(&dev->clientslock);
342 spin_lock_init(&dev->bufferslock);
343
344 /* init completion events */
345 init_completion(&dev->version_ex_done);
346 init_completion(&dev->data_download_done);
347 init_completion(&dev->trigger_done);
348 init_completion(&dev->init_device_done);
349 init_completion(&dev->reload_start_done);
350 init_completion(&dev->resume_done);
351 init_completion(&dev->gpio_configuration_done);
352 init_completion(&dev->gpio_set_level_done);
353 init_completion(&dev->gpio_get_level_done);
354 init_completion(&dev->ir_init_done);
355
356 /* Buffer management */
357 init_waitqueue_head(&dev->buffer_mng_waitq);
358
359 /* alloc common buffer */
360 dev->common_buffer_size = params->buffer_size * params->num_buffers;
361 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
362 &dev->common_buffer_phys,
363 GFP_KERNEL | GFP_DMA);
364 if (!dev->common_buffer) {
365 smscore_unregister_device(dev);
366 return -ENOMEM;
367 }
368
369 /* prepare dma buffers */
370 for (buffer = dev->common_buffer;
371 dev->num_buffers < params->num_buffers;
372 dev->num_buffers++, buffer += params->buffer_size) {
373 struct smscore_buffer_t *cb =
374 smscore_createbuffer(buffer, dev->common_buffer,
375 dev->common_buffer_phys);
376 if (!cb) {
377 smscore_unregister_device(dev);
378 return -ENOMEM;
379 }
380
381 smscore_putbuffer(dev, cb);
382 }
383
384 sms_info("allocated %d buffers", dev->num_buffers);
385
386 dev->mode = DEVICE_MODE_NONE;
387 dev->context = params->context;
388 dev->device = params->device;
389 dev->setmode_handler = params->setmode_handler;
390 dev->detectmode_handler = params->detectmode_handler;
391 dev->sendrequest_handler = params->sendrequest_handler;
392 dev->preload_handler = params->preload_handler;
393 dev->postload_handler = params->postload_handler;
394
395 dev->device_flags = params->flags;
396 strcpy(dev->devpath, params->devpath);
397
398 smscore_registry_settype(dev->devpath, params->device_type);
399
400 /* add device to devices list */
401 kmutex_lock(&g_smscore_deviceslock);
402 list_add(&dev->entry, &g_smscore_devices);
403 kmutex_unlock(&g_smscore_deviceslock);
404
405 *coredev = dev;
406
407 sms_info("device %p created", dev);
408
409 return 0;
410}
411EXPORT_SYMBOL_GPL(smscore_register_device);
412
413
414static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
415 void *buffer, size_t size, struct completion *completion) {
416 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
417 if (rc < 0) {
418 sms_info("sendrequest returned error %d", rc);
419 return rc;
420 }
421
422 return wait_for_completion_timeout(completion,
423 msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
424 0 : -ETIME;
425}
426
427/**
428 * Starts & enables IR operations
429 *
430 * @return 0 on success, < 0 on error.
431 */
432static int smscore_init_ir(struct smscore_device_t *coredev)
433{
434 int ir_io;
435 int rc;
436 void *buffer;
437
438 coredev->ir.dev = NULL;
439 ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
440 if (ir_io) {/* only if IR port exist we use IR sub-module */
441 sms_info("IR loading");
442 rc = sms_ir_init(coredev);
443
444 if (rc != 0)
445 sms_err("Error initialization DTV IR sub-module");
446 else {
447 buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
448 SMS_DMA_ALIGNMENT,
449 GFP_KERNEL | GFP_DMA);
450 if (buffer) {
451 struct SmsMsgData_ST2 *msg =
452 (struct SmsMsgData_ST2 *)
453 SMS_ALIGN_ADDRESS(buffer);
454
455 SMS_INIT_MSG(&msg->xMsgHeader,
456 MSG_SMS_START_IR_REQ,
457 sizeof(struct SmsMsgData_ST2));
458 msg->msgData[0] = coredev->ir.controller;
459 msg->msgData[1] = coredev->ir.timeout;
460
461 smsendian_handle_tx_message(
462 (struct SmsMsgHdr_ST2 *)msg);
463 rc = smscore_sendrequest_and_wait(coredev, msg,
464 msg->xMsgHeader. msgLength,
465 &coredev->ir_init_done);
466
467 kfree(buffer);
468 } else
469 sms_err
470 ("Sending IR initialization message failed");
471 }
472 } else
473 sms_info("IR port has not been detected");
474
475 return 0;
476}
477
478/**
479 * sets initial device mode and notifies client hotplugs that device is ready
480 *
481 * @param coredev pointer to a coredev object returned by
482 * smscore_register_device
483 *
484 * @return 0 on success, <0 on error.
485 */
486int smscore_start_device(struct smscore_device_t *coredev)
487{
488 int rc = smscore_set_device_mode(
489 coredev, smscore_registry_getmode(coredev->devpath));
490 if (rc < 0) {
491 sms_info("set device mode faile , rc %d", rc);
492 return rc;
493 }
494
495 kmutex_lock(&g_smscore_deviceslock);
496
497 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
498 smscore_init_ir(coredev);
499
500 sms_info("device %p started, rc %d", coredev, rc);
501
502 kmutex_unlock(&g_smscore_deviceslock);
503
504 return rc;
505}
506EXPORT_SYMBOL_GPL(smscore_start_device);
507
508
509static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
510 void *buffer, size_t size)
511{
512 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
513 struct SmsMsgHdr_ST *msg;
514 u32 mem_address;
515 u8 *payload = firmware->Payload;
516 int rc = 0;
517 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
518 firmware->Length = le32_to_cpu(firmware->Length);
519
520 mem_address = firmware->StartAddress;
521
522 sms_info("loading FW to addr 0x%x size %d",
523 mem_address, firmware->Length);
524 if (coredev->preload_handler) {
525 rc = coredev->preload_handler(coredev->context);
526 if (rc < 0)
527 return rc;
528 }
529
530 /* PAGE_SIZE buffer shall be enough and dma aligned */
531 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
532 if (!msg)
533 return -ENOMEM;
534
535 if (coredev->mode != DEVICE_MODE_NONE) {
536 sms_debug("sending reload command.");
537 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
538 sizeof(struct SmsMsgHdr_ST));
539 rc = smscore_sendrequest_and_wait(coredev, msg,
540 msg->msgLength,
541 &coredev->reload_start_done);
542 mem_address = *(u32 *) &payload[20];
543 }
544
545 while (size && rc >= 0) {
546 struct SmsDataDownload_ST *DataMsg =
547 (struct SmsDataDownload_ST *) msg;
548 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
549
550 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
551 (u16)(sizeof(struct SmsMsgHdr_ST) +
552 sizeof(u32) + payload_size));
553
554 DataMsg->MemAddr = mem_address;
555 memcpy(DataMsg->Payload, payload, payload_size);
556
557 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
558 (coredev->mode == DEVICE_MODE_NONE))
559 rc = coredev->sendrequest_handler(
560 coredev->context, DataMsg,
561 DataMsg->xMsgHeader.msgLength);
562 else
563 rc = smscore_sendrequest_and_wait(
564 coredev, DataMsg,
565 DataMsg->xMsgHeader.msgLength,
566 &coredev->data_download_done);
567
568 payload += payload_size;
569 size -= payload_size;
570 mem_address += payload_size;
571 }
572
573 if (rc >= 0) {
574 if (coredev->mode == DEVICE_MODE_NONE) {
575 struct SmsMsgData_ST *TriggerMsg =
576 (struct SmsMsgData_ST *) msg;
577
578 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
579 sizeof(struct SmsMsgHdr_ST) +
580 sizeof(u32) * 5);
581
582 TriggerMsg->msgData[0] = firmware->StartAddress;
583 /* Entry point */
584 TriggerMsg->msgData[1] = 5; /* Priority */
585 TriggerMsg->msgData[2] = 0x200; /* Stack size */
586 TriggerMsg->msgData[3] = 0; /* Parameter */
587 TriggerMsg->msgData[4] = 4; /* Task ID */
588
589 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
590 rc = coredev->sendrequest_handler(
591 coredev->context, TriggerMsg,
592 TriggerMsg->xMsgHeader.msgLength);
593 msleep(100);
594 } else
595 rc = smscore_sendrequest_and_wait(
596 coredev, TriggerMsg,
597 TriggerMsg->xMsgHeader.msgLength,
598 &coredev->trigger_done);
599 } else {
600 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
601 sizeof(struct SmsMsgHdr_ST));
602
603 rc = coredev->sendrequest_handler(coredev->context,
604 msg, msg->msgLength);
605 }
606 msleep(500);
607 }
608
609 sms_debug("rc=%d, postload=%p ", rc,
610 coredev->postload_handler);
611
612 kfree(msg);
613
614 return ((rc >= 0) && coredev->postload_handler) ?
615 coredev->postload_handler(coredev->context) :
616 rc;
617}
618
619/**
620 * loads specified firmware into a buffer and calls device loadfirmware_handler
621 *
622 * @param coredev pointer to a coredev object returned by
623 * smscore_register_device
624 * @param filename null-terminated string specifies firmware file name
625 * @param loadfirmware_handler device handler that loads firmware
626 *
627 * @return 0 on success, <0 on error.
628 */
629static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
630 char *filename,
631 loadfirmware_t loadfirmware_handler)
632{
633 int rc = -ENOENT;
634 const struct firmware *fw;
635 u8 *fw_buffer;
636
637 if (loadfirmware_handler == NULL && !(coredev->device_flags &
638 SMS_DEVICE_FAMILY2))
639 return -EINVAL;
640
641 rc = request_firmware(&fw, filename, coredev->device);
642 if (rc < 0) {
643 sms_info("failed to open \"%s\"", filename);
644 return rc;
645 }
646 sms_info("read FW %s, size=%zd", filename, fw->size);
647 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
648 GFP_KERNEL | GFP_DMA);
649 if (fw_buffer) {
650 memcpy(fw_buffer, fw->data, fw->size);
651
652 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
653 smscore_load_firmware_family2(coredev,
654 fw_buffer,
655 fw->size) :
656 loadfirmware_handler(coredev->context,
657 fw_buffer, fw->size);
658
659 kfree(fw_buffer);
660 } else {
661 sms_info("failed to allocate firmware buffer");
662 rc = -ENOMEM;
663 }
664
665 release_firmware(fw);
666
667 return rc;
668}
669
670/**
671 * notifies all clients registered with the device, notifies hotplugs,
672 * frees all buffers and coredev object
673 *
674 * @param coredev pointer to a coredev object returned by
675 * smscore_register_device
676 *
677 * @return 0 on success, <0 on error.
678 */
679void smscore_unregister_device(struct smscore_device_t *coredev)
680{
681 struct smscore_buffer_t *cb;
682 int num_buffers = 0;
683 int retry = 0;
684
685 kmutex_lock(&g_smscore_deviceslock);
686
687 /* Release input device (IR) resources */
688 sms_ir_exit(coredev);
689
690 smscore_notify_clients(coredev);
691 smscore_notify_callbacks(coredev, NULL, 0);
692
693 /* at this point all buffers should be back
694 * onresponse must no longer be called */
695
696 while (1) {
697 while (!list_empty(&coredev->buffers)) {
698 cb = (struct smscore_buffer_t *) coredev->buffers.next;
699 list_del(&cb->entry);
700 kfree(cb);
701 num_buffers++;
702 }
703 if (num_buffers == coredev->num_buffers)
704 break;
705 if (++retry > 10) {
706 sms_info("exiting although "
707 "not all buffers released.");
708 break;
709 }
710
711 sms_info("waiting for %d buffer(s)",
712 coredev->num_buffers - num_buffers);
713 msleep(100);
714 }
715
716 sms_info("freed %d buffers", num_buffers);
717
718 if (coredev->common_buffer)
719 dma_free_coherent(NULL, coredev->common_buffer_size,
720 coredev->common_buffer, coredev->common_buffer_phys);
721
722 if (coredev->fw_buf != NULL)
723 kfree(coredev->fw_buf);
724
725 list_del(&coredev->entry);
726 kfree(coredev);
727
728 kmutex_unlock(&g_smscore_deviceslock);
729
730 sms_info("device %p destroyed", coredev);
731}
732EXPORT_SYMBOL_GPL(smscore_unregister_device);
733
734static int smscore_detect_mode(struct smscore_device_t *coredev)
735{
736 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
737 GFP_KERNEL | GFP_DMA);
738 struct SmsMsgHdr_ST *msg =
739 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
740 int rc;
741
742 if (!buffer)
743 return -ENOMEM;
744
745 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
746 sizeof(struct SmsMsgHdr_ST));
747
748 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
749 &coredev->version_ex_done);
750 if (rc == -ETIME) {
751 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
752
753 if (wait_for_completion_timeout(&coredev->resume_done,
754 msecs_to_jiffies(5000))) {
755 rc = smscore_sendrequest_and_wait(
756 coredev, msg, msg->msgLength,
757 &coredev->version_ex_done);
758 if (rc < 0)
759 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
760 "second try, rc %d", rc);
761 } else
762 rc = -ETIME;
763 }
764
765 kfree(buffer);
766
767 return rc;
768}
769
770static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
771 /*Stellar NOVA A0 Nova B0 VEGA*/
772 /*DVBT*/
773 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
774 /*DVBH*/
775 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
776 /*TDMB*/
777 {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
778 /*DABIP*/
779 {"none", "none", "none", "none"},
780 /*BDA*/
781 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
782 /*ISDBT*/
783 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
784 /*ISDBTBDA*/
785 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
786 /*CMMB*/
787 {"none", "none", "none", "cmmb_vega_12mhz.inp"}
788};
789
790static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
791 int mode, enum sms_device_type_st type)
792{
793 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
794 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
795}
796
797/**
798 * calls device handler to change mode of operation
799 * NOTE: stellar/usb may disconnect when changing mode
800 *
801 * @param coredev pointer to a coredev object returned by
802 * smscore_register_device
803 * @param mode requested mode of operation
804 *
805 * @return 0 on success, <0 on error.
806 */
807int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
808{
809 void *buffer;
810 int rc = 0;
811 enum sms_device_type_st type;
812
813 sms_debug("set device mode to %d", mode);
814 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
815 if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
816 sms_err("invalid mode specified %d", mode);
817 return -EINVAL;
818 }
819
820 smscore_registry_setmode(coredev->devpath, mode);
821
822 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
823 rc = smscore_detect_mode(coredev);
824 if (rc < 0) {
825 sms_err("mode detect failed %d", rc);
826 return rc;
827 }
828 }
829
830 if (coredev->mode == mode) {
831 sms_info("device mode %d already set", mode);
832 return 0;
833 }
834
835 if (!(coredev->modes_supported & (1 << mode))) {
836 char *fw_filename;
837
838 type = smscore_registry_gettype(coredev->devpath);
839 fw_filename = sms_get_fw_name(coredev, mode, type);
840
841 rc = smscore_load_firmware_from_file(coredev,
842 fw_filename, NULL);
843 if (rc < 0) {
844 sms_warn("error %d loading firmware: %s, "
845 "trying again with default firmware",
846 rc, fw_filename);
847
848 /* try again with the default firmware */
849 fw_filename = smscore_fw_lkup[mode][type];
850 rc = smscore_load_firmware_from_file(coredev,
851 fw_filename, NULL);
852
853 if (rc < 0) {
854 sms_warn("error %d loading "
855 "firmware: %s", rc,
856 fw_filename);
857 return rc;
858 }
859 }
860 sms_log("firmware download success: %s", fw_filename);
861 } else
862 sms_info("mode %d supported by running "
863 "firmware", mode);
864
865 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
866 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
867 if (buffer) {
868 struct SmsMsgData_ST *msg =
869 (struct SmsMsgData_ST *)
870 SMS_ALIGN_ADDRESS(buffer);
871
872 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
873 sizeof(struct SmsMsgData_ST));
874 msg->msgData[0] = mode;
875
876 rc = smscore_sendrequest_and_wait(
877 coredev, msg, msg->xMsgHeader.msgLength,
878 &coredev->init_device_done);
879
880 kfree(buffer);
881 } else {
882 sms_err("Could not allocate buffer for "
883 "init device message.");
884 rc = -ENOMEM;
885 }
886 } else {
887 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
888 sms_err("invalid mode specified %d", mode);
889 return -EINVAL;
890 }
891
892 smscore_registry_setmode(coredev->devpath, mode);
893
894 if (coredev->detectmode_handler)
895 coredev->detectmode_handler(coredev->context,
896 &coredev->mode);
897
898 if (coredev->mode != mode && coredev->setmode_handler)
899 rc = coredev->setmode_handler(coredev->context, mode);
900 }
901
902 if (rc >= 0) {
903 coredev->mode = mode;
904 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
905 }
906
907 if (rc < 0)
908 sms_err("return error code %d.", rc);
909 return rc;
910}
911
912/**
913 * calls device handler to get current mode of operation
914 *
915 * @param coredev pointer to a coredev object returned by
916 * smscore_register_device
917 *
918 * @return current mode
919 */
920int smscore_get_device_mode(struct smscore_device_t *coredev)
921{
922 return coredev->mode;
923}
924EXPORT_SYMBOL_GPL(smscore_get_device_mode);
925
926/**
927 * find client by response id & type within the clients list.
928 * return client handle or NULL.
929 *
930 * @param coredev pointer to a coredev object returned by
931 * smscore_register_device
932 * @param data_type client data type (SMS_DONT_CARE for all types)
933 * @param id client id (SMS_DONT_CARE for all id)
934 *
935 */
936static struct
937smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
938 int data_type, int id)
939{
940 struct list_head *first;
941 struct smscore_client_t *client;
942 unsigned long flags;
943 struct list_head *firstid;
944 struct smscore_idlist_t *client_id;
945
946 spin_lock_irqsave(&coredev->clientslock, flags);
947 first = &coredev->clients;
948 list_for_each_entry(client, first, entry) {
949 firstid = &client->idlist;
950 list_for_each_entry(client_id, firstid, entry) {
951 if ((client_id->id == id) &&
952 (client_id->data_type == data_type ||
953 (client_id->data_type == 0)))
954 goto found;
955 }
956 }
957 client = NULL;
958found:
959 spin_unlock_irqrestore(&coredev->clientslock, flags);
960 return client;
961}
962
963/**
964 * find client by response id/type, call clients onresponse handler
965 * return buffer to pool on error
966 *
967 * @param coredev pointer to a coredev object returned by
968 * smscore_register_device
969 * @param cb pointer to response buffer descriptor
970 *
971 */
972void smscore_onresponse(struct smscore_device_t *coredev,
973 struct smscore_buffer_t *cb) {
974 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
975 + cb->offset);
976 struct smscore_client_t *client;
977 int rc = -EBUSY;
978 static unsigned long last_sample_time; /* = 0; */
979 static int data_total; /* = 0; */
980 unsigned long time_now = jiffies_to_msecs(jiffies);
981
982 if (!last_sample_time)
983 last_sample_time = time_now;
984
985 if (time_now - last_sample_time > 10000) {
986 sms_debug("\ndata rate %d bytes/secs",
987 (int)((data_total * 1000) /
988 (time_now - last_sample_time)));
989
990 last_sample_time = time_now;
991 data_total = 0;
992 }
993
994 data_total += cb->size;
995 /* Do we need to re-route? */
996 if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
997 (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
998 if (coredev->mode == DEVICE_MODE_DVBT_BDA)
999 phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
1000 }
1001
1002
1003 client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
1004
1005 /* If no client registered for type & id,
1006 * check for control client where type is not registered */
1007 if (client)
1008 rc = client->onresponse_handler(client->context, cb);
1009
1010 if (rc < 0) {
1011 switch (phdr->msgType) {
1012 case MSG_SMS_GET_VERSION_EX_RES:
1013 {
1014 struct SmsVersionRes_ST *ver =
1015 (struct SmsVersionRes_ST *) phdr;
1016 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
1017 "id %d prots 0x%x ver %d.%d",
1018 ver->FirmwareId, ver->SupportedProtocols,
1019 ver->RomVersionMajor, ver->RomVersionMinor);
1020
1021 coredev->mode = ver->FirmwareId == 255 ?
1022 DEVICE_MODE_NONE : ver->FirmwareId;
1023 coredev->modes_supported = ver->SupportedProtocols;
1024
1025 complete(&coredev->version_ex_done);
1026 break;
1027 }
1028 case MSG_SMS_INIT_DEVICE_RES:
1029 sms_debug("MSG_SMS_INIT_DEVICE_RES");
1030 complete(&coredev->init_device_done);
1031 break;
1032 case MSG_SW_RELOAD_START_RES:
1033 sms_debug("MSG_SW_RELOAD_START_RES");
1034 complete(&coredev->reload_start_done);
1035 break;
1036 case MSG_SMS_DATA_DOWNLOAD_RES:
1037 complete(&coredev->data_download_done);
1038 break;
1039 case MSG_SW_RELOAD_EXEC_RES:
1040 sms_debug("MSG_SW_RELOAD_EXEC_RES");
1041 break;
1042 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1043 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
1044 complete(&coredev->trigger_done);
1045 break;
1046 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1047 complete(&coredev->resume_done);
1048 break;
1049 case MSG_SMS_GPIO_CONFIG_EX_RES:
1050 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1051 complete(&coredev->gpio_configuration_done);
1052 break;
1053 case MSG_SMS_GPIO_SET_LEVEL_RES:
1054 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1055 complete(&coredev->gpio_set_level_done);
1056 break;
1057 case MSG_SMS_GPIO_GET_LEVEL_RES:
1058 {
1059 u32 *msgdata = (u32 *) phdr;
1060 coredev->gpio_get_res = msgdata[1];
1061 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
1062 coredev->gpio_get_res);
1063 complete(&coredev->gpio_get_level_done);
1064 break;
1065 }
1066 case MSG_SMS_START_IR_RES:
1067 complete(&coredev->ir_init_done);
1068 break;
1069 case MSG_SMS_IR_SAMPLES_IND:
1070 sms_ir_event(coredev,
1071 (const char *)
1072 ((char *)phdr
1073 + sizeof(struct SmsMsgHdr_ST)),
1074 (int)phdr->msgLength
1075 - sizeof(struct SmsMsgHdr_ST));
1076 break;
1077
1078 default:
1079 break;
1080 }
1081 smscore_putbuffer(coredev, cb);
1082 }
1083}
1084EXPORT_SYMBOL_GPL(smscore_onresponse);
1085
1086/**
1087 * return pointer to next free buffer descriptor from core pool
1088 *
1089 * @param coredev pointer to a coredev object returned by
1090 * smscore_register_device
1091 *
1092 * @return pointer to descriptor on success, NULL on error.
1093 */
1094
1095static struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
1096{
1097 struct smscore_buffer_t *cb = NULL;
1098 unsigned long flags;
1099
1100 spin_lock_irqsave(&coredev->bufferslock, flags);
1101 if (!list_empty(&coredev->buffers)) {
1102 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1103 list_del(&cb->entry);
1104 }
1105 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1106 return cb;
1107}
1108
1109struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1110{
1111 struct smscore_buffer_t *cb = NULL;
1112
1113 wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));
1114
1115 return cb;
1116}
1117EXPORT_SYMBOL_GPL(smscore_getbuffer);
1118
1119/**
1120 * return buffer descriptor to a pool
1121 *
1122 * @param coredev pointer to a coredev object returned by
1123 * smscore_register_device
1124 * @param cb pointer buffer descriptor
1125 *
1126 */
1127void smscore_putbuffer(struct smscore_device_t *coredev,
1128 struct smscore_buffer_t *cb) {
1129 wake_up_interruptible(&coredev->buffer_mng_waitq);
1130 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1131}
1132EXPORT_SYMBOL_GPL(smscore_putbuffer);
1133
1134static int smscore_validate_client(struct smscore_device_t *coredev,
1135 struct smscore_client_t *client,
1136 int data_type, int id)
1137{
1138 struct smscore_idlist_t *listentry;
1139 struct smscore_client_t *registered_client;
1140
1141 if (!client) {
1142 sms_err("bad parameter.");
1143 return -EINVAL;
1144 }
1145 registered_client = smscore_find_client(coredev, data_type, id);
1146 if (registered_client == client)
1147 return 0;
1148
1149 if (registered_client) {
1150 sms_err("The msg ID already registered to another client.");
1151 return -EEXIST;
1152 }
1153 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1154 if (!listentry) {
1155 sms_err("Can't allocate memory for client id.");
1156 return -ENOMEM;
1157 }
1158 listentry->id = id;
1159 listentry->data_type = data_type;
1160 list_add_locked(&listentry->entry, &client->idlist,
1161 &coredev->clientslock);
1162 return 0;
1163}
1164
1165/**
1166 * creates smsclient object, check that id is taken by another client
1167 *
1168 * @param coredev pointer to a coredev object from clients hotplug
1169 * @param initial_id all messages with this id would be sent to this client
1170 * @param data_type all messages of this type would be sent to this client
1171 * @param onresponse_handler client handler that is called to
1172 * process incoming messages
1173 * @param onremove_handler client handler that is called when device is removed
1174 * @param context client-specific context
1175 * @param client pointer to a value that receives created smsclient object
1176 *
1177 * @return 0 on success, <0 on error.
1178 */
1179int smscore_register_client(struct smscore_device_t *coredev,
1180 struct smsclient_params_t *params,
1181 struct smscore_client_t **client)
1182{
1183 struct smscore_client_t *newclient;
1184 /* check that no other channel with same parameters exists */
1185 if (smscore_find_client(coredev, params->data_type,
1186 params->initial_id)) {
1187 sms_err("Client already exist.");
1188 return -EEXIST;
1189 }
1190
1191 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1192 if (!newclient) {
1193 sms_err("Failed to allocate memory for client.");
1194 return -ENOMEM;
1195 }
1196
1197 INIT_LIST_HEAD(&newclient->idlist);
1198 newclient->coredev = coredev;
1199 newclient->onresponse_handler = params->onresponse_handler;
1200 newclient->onremove_handler = params->onremove_handler;
1201 newclient->context = params->context;
1202 list_add_locked(&newclient->entry, &coredev->clients,
1203 &coredev->clientslock);
1204 smscore_validate_client(coredev, newclient, params->data_type,
1205 params->initial_id);
1206 *client = newclient;
1207 sms_debug("%p %d %d", params->context, params->data_type,
1208 params->initial_id);
1209
1210 return 0;
1211}
1212EXPORT_SYMBOL_GPL(smscore_register_client);
1213
1214/**
1215 * frees smsclient object and all subclients associated with it
1216 *
1217 * @param client pointer to smsclient object returned by
1218 * smscore_register_client
1219 *
1220 */
1221void smscore_unregister_client(struct smscore_client_t *client)
1222{
1223 struct smscore_device_t *coredev = client->coredev;
1224 unsigned long flags;
1225
1226 spin_lock_irqsave(&coredev->clientslock, flags);
1227
1228
1229 while (!list_empty(&client->idlist)) {
1230 struct smscore_idlist_t *identry =
1231 (struct smscore_idlist_t *) client->idlist.next;
1232 list_del(&identry->entry);
1233 kfree(identry);
1234 }
1235
1236 sms_info("%p", client->context);
1237
1238 list_del(&client->entry);
1239 kfree(client);
1240
1241 spin_unlock_irqrestore(&coredev->clientslock, flags);
1242}
1243EXPORT_SYMBOL_GPL(smscore_unregister_client);
1244
1245/**
1246 * verifies that source id is not taken by another client,
1247 * calls device handler to send requests to the device
1248 *
1249 * @param client pointer to smsclient object returned by
1250 * smscore_register_client
1251 * @param buffer pointer to a request buffer
1252 * @param size size (in bytes) of request buffer
1253 *
1254 * @return 0 on success, <0 on error.
1255 */
1256int smsclient_sendrequest(struct smscore_client_t *client,
1257 void *buffer, size_t size)
1258{
1259 struct smscore_device_t *coredev;
1260 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1261 int rc;
1262
1263 if (client == NULL) {
1264 sms_err("Got NULL client");
1265 return -EINVAL;
1266 }
1267
1268 coredev = client->coredev;
1269
1270 /* check that no other channel with same id exists */
1271 if (coredev == NULL) {
1272 sms_err("Got NULL coredev");
1273 return -EINVAL;
1274 }
1275
1276 rc = smscore_validate_client(client->coredev, client, 0,
1277 phdr->msgSrcId);
1278 if (rc < 0)
1279 return rc;
1280
1281 return coredev->sendrequest_handler(coredev->context, buffer, size);
1282}
1283EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1284
1285
1286/* old GPIO managements implementation */
1287int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1288 struct smscore_config_gpio *pinconfig)
1289{
1290 struct {
1291 struct SmsMsgHdr_ST hdr;
1292 u32 data[6];
1293 } msg;
1294
1295 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1296 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1297 msg.hdr.msgDstId = HIF_TASK;
1298 msg.hdr.msgFlags = 0;
1299 msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1300 msg.hdr.msgLength = sizeof(msg);
1301
1302 msg.data[0] = pin;
1303 msg.data[1] = pinconfig->pullupdown;
1304
1305 /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
1306 msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
1307
1308 switch (pinconfig->outputdriving) {
1309 case SMS_GPIO_OUTPUTDRIVING_16mA:
1310 msg.data[3] = 7; /* Nova - 16mA */
1311 break;
1312 case SMS_GPIO_OUTPUTDRIVING_12mA:
1313 msg.data[3] = 5; /* Nova - 11mA */
1314 break;
1315 case SMS_GPIO_OUTPUTDRIVING_8mA:
1316 msg.data[3] = 3; /* Nova - 7mA */
1317 break;
1318 case SMS_GPIO_OUTPUTDRIVING_4mA:
1319 default:
1320 msg.data[3] = 2; /* Nova - 4mA */
1321 break;
1322 }
1323
1324 msg.data[4] = pinconfig->direction;
1325 msg.data[5] = 0;
1326 } else /* TODO: SMS_DEVICE_FAMILY1 */
1327 return -EINVAL;
1328
1329 return coredev->sendrequest_handler(coredev->context,
1330 &msg, sizeof(msg));
1331}
1332
1333int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1334{
1335 struct {
1336 struct SmsMsgHdr_ST hdr;
1337 u32 data[3];
1338 } msg;
1339
1340 if (pin > MAX_GPIO_PIN_NUMBER)
1341 return -EINVAL;
1342
1343 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1344 msg.hdr.msgDstId = HIF_TASK;
1345 msg.hdr.msgFlags = 0;
1346 msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1347 msg.hdr.msgLength = sizeof(msg);
1348
1349 msg.data[0] = pin;
1350 msg.data[1] = level ? 1 : 0;
1351 msg.data[2] = 0;
1352
1353 return coredev->sendrequest_handler(coredev->context,
1354 &msg, sizeof(msg));
1355}
1356
1357/* new GPIO management implementation */
1358static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1359 u32 *pGroupNum, u32 *pGroupCfg) {
1360
1361 *pGroupCfg = 1;
1362
1363 if (PinNum <= 1) {
1364 *pTranslatedPinNum = 0;
1365 *pGroupNum = 9;
1366 *pGroupCfg = 2;
1367 } else if (PinNum >= 2 && PinNum <= 6) {
1368 *pTranslatedPinNum = 2;
1369 *pGroupNum = 0;
1370 *pGroupCfg = 2;
1371 } else if (PinNum >= 7 && PinNum <= 11) {
1372 *pTranslatedPinNum = 7;
1373 *pGroupNum = 1;
1374 } else if (PinNum >= 12 && PinNum <= 15) {
1375 *pTranslatedPinNum = 12;
1376 *pGroupNum = 2;
1377 *pGroupCfg = 3;
1378 } else if (PinNum == 16) {
1379 *pTranslatedPinNum = 16;
1380 *pGroupNum = 23;
1381 } else if (PinNum >= 17 && PinNum <= 24) {
1382 *pTranslatedPinNum = 17;
1383 *pGroupNum = 3;
1384 } else if (PinNum == 25) {
1385 *pTranslatedPinNum = 25;
1386 *pGroupNum = 6;
1387 } else if (PinNum >= 26 && PinNum <= 28) {
1388 *pTranslatedPinNum = 26;
1389 *pGroupNum = 4;
1390 } else if (PinNum == 29) {
1391 *pTranslatedPinNum = 29;
1392 *pGroupNum = 5;
1393 *pGroupCfg = 2;
1394 } else if (PinNum == 30) {
1395 *pTranslatedPinNum = 30;
1396 *pGroupNum = 8;
1397 } else if (PinNum == 31) {
1398 *pTranslatedPinNum = 31;
1399 *pGroupNum = 17;
1400 } else
1401 return -1;
1402
1403 *pGroupCfg <<= 24;
1404
1405 return 0;
1406}
1407
1408int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1409 struct smscore_gpio_config *pGpioConfig) {
1410
1411 u32 totalLen;
1412 u32 TranslatedPinNum = 0;
1413 u32 GroupNum = 0;
1414 u32 ElectricChar;
1415 u32 groupCfg;
1416 void *buffer;
1417 int rc;
1418
1419 struct SetGpioMsg {
1420 struct SmsMsgHdr_ST xMsgHeader;
1421 u32 msgData[6];
1422 } *pMsg;
1423
1424
1425 if (PinNum > MAX_GPIO_PIN_NUMBER)
1426 return -EINVAL;
1427
1428 if (pGpioConfig == NULL)
1429 return -EINVAL;
1430
1431 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1432
1433 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1434 GFP_KERNEL | GFP_DMA);
1435 if (!buffer)
1436 return -ENOMEM;
1437
1438 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1439
1440 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1441 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1442 pMsg->xMsgHeader.msgFlags = 0;
1443 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1444 pMsg->msgData[0] = PinNum;
1445
1446 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1447 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1448 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1449 &groupCfg) != 0) {
1450 rc = -EINVAL;
1451 goto free;
1452 }
1453
1454 pMsg->msgData[1] = TranslatedPinNum;
1455 pMsg->msgData[2] = GroupNum;
1456 ElectricChar = (pGpioConfig->PullUpDown)
1457 | (pGpioConfig->InputCharacteristics << 2)
1458 | (pGpioConfig->OutputSlewRate << 3)
1459 | (pGpioConfig->OutputDriving << 4);
1460 pMsg->msgData[3] = ElectricChar;
1461 pMsg->msgData[4] = pGpioConfig->Direction;
1462 pMsg->msgData[5] = groupCfg;
1463 } else {
1464 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1465 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1466 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1467 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1468 pMsg->msgData[4] = pGpioConfig->Direction;
1469 pMsg->msgData[5] = 0;
1470 }
1471
1472 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1473 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1474 &coredev->gpio_configuration_done);
1475
1476 if (rc != 0) {
1477 if (rc == -ETIME)
1478 sms_err("smscore_gpio_configure timeout");
1479 else
1480 sms_err("smscore_gpio_configure error");
1481 }
1482free:
1483 kfree(buffer);
1484
1485 return rc;
1486}
1487
1488int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1489 u8 NewLevel) {
1490
1491 u32 totalLen;
1492 int rc;
1493 void *buffer;
1494
1495 struct SetGpioMsg {
1496 struct SmsMsgHdr_ST xMsgHeader;
1497 u32 msgData[3]; /* keep it 3 ! */
1498 } *pMsg;
1499
1500 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER))
1501 return -EINVAL;
1502
1503 totalLen = sizeof(struct SmsMsgHdr_ST) +
1504 (3 * sizeof(u32)); /* keep it 3 ! */
1505
1506 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1507 GFP_KERNEL | GFP_DMA);
1508 if (!buffer)
1509 return -ENOMEM;
1510
1511 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1512
1513 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1514 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1515 pMsg->xMsgHeader.msgFlags = 0;
1516 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1517 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1518 pMsg->msgData[0] = PinNum;
1519 pMsg->msgData[1] = NewLevel;
1520
1521 /* Send message to SMS */
1522 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1523 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1524 &coredev->gpio_set_level_done);
1525
1526 if (rc != 0) {
1527 if (rc == -ETIME)
1528 sms_err("smscore_gpio_set_level timeout");
1529 else
1530 sms_err("smscore_gpio_set_level error");
1531 }
1532 kfree(buffer);
1533
1534 return rc;
1535}
1536
1537int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1538 u8 *level) {
1539
1540 u32 totalLen;
1541 int rc;
1542 void *buffer;
1543
1544 struct SetGpioMsg {
1545 struct SmsMsgHdr_ST xMsgHeader;
1546 u32 msgData[2];
1547 } *pMsg;
1548
1549
1550 if (PinNum > MAX_GPIO_PIN_NUMBER)
1551 return -EINVAL;
1552
1553 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1554
1555 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1556 GFP_KERNEL | GFP_DMA);
1557 if (!buffer)
1558 return -ENOMEM;
1559
1560 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1561
1562 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1563 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1564 pMsg->xMsgHeader.msgFlags = 0;
1565 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1566 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1567 pMsg->msgData[0] = PinNum;
1568 pMsg->msgData[1] = 0;
1569
1570 /* Send message to SMS */
1571 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1572 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1573 &coredev->gpio_get_level_done);
1574
1575 if (rc != 0) {
1576 if (rc == -ETIME)
1577 sms_err("smscore_gpio_get_level timeout");
1578 else
1579 sms_err("smscore_gpio_get_level error");
1580 }
1581 kfree(buffer);
1582
1583 /* Its a race between other gpio_get_level() and the copy of the single
1584 * global 'coredev->gpio_get_res' to the function's variable 'level'
1585 */
1586 *level = coredev->gpio_get_res;
1587
1588 return rc;
1589}
1590
1591static int __init smscore_module_init(void)
1592{
1593 int rc = 0;
1594
1595 INIT_LIST_HEAD(&g_smscore_notifyees);
1596 INIT_LIST_HEAD(&g_smscore_devices);
1597 kmutex_init(&g_smscore_deviceslock);
1598
1599 INIT_LIST_HEAD(&g_smscore_registry);
1600 kmutex_init(&g_smscore_registrylock);
1601
1602 return rc;
1603}
1604
1605static void __exit smscore_module_exit(void)
1606{
1607 kmutex_lock(&g_smscore_deviceslock);
1608 while (!list_empty(&g_smscore_notifyees)) {
1609 struct smscore_device_notifyee_t *notifyee =
1610 (struct smscore_device_notifyee_t *)
1611 g_smscore_notifyees.next;
1612
1613 list_del(&notifyee->entry);
1614 kfree(notifyee);
1615 }
1616 kmutex_unlock(&g_smscore_deviceslock);
1617
1618 kmutex_lock(&g_smscore_registrylock);
1619 while (!list_empty(&g_smscore_registry)) {
1620 struct smscore_registry_entry_t *entry =
1621 (struct smscore_registry_entry_t *)
1622 g_smscore_registry.next;
1623
1624 list_del(&entry->entry);
1625 kfree(entry);
1626 }
1627 kmutex_unlock(&g_smscore_registrylock);
1628
1629 sms_debug("");
1630}
1631
1632module_init(smscore_module_init);
1633module_exit(smscore_module_exit);
1634
1635MODULE_DESCRIPTION("Siano MDTV Core module");
1636MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
1637MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smscoreapi.h b/drivers/media/common/siano/smscoreapi.h
deleted file mode 100644
index c592ae09039..00000000000
--- a/drivers/media/common/siano/smscoreapi.h
+++ /dev/null
@@ -1,775 +0,0 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_CORE_API_H__
23#define __SMS_CORE_API_H__
24
25#include <linux/device.h>
26#include <linux/list.h>
27#include <linux/mm.h>
28#include <linux/scatterlist.h>
29#include <linux/types.h>
30#include <linux/mutex.h>
31#include <linux/wait.h>
32#include <linux/timer.h>
33
34#include <asm/page.h>
35
36#include "smsir.h"
37
38#define kmutex_init(_p_) mutex_init(_p_)
39#define kmutex_lock(_p_) mutex_lock(_p_)
40#define kmutex_trylock(_p_) mutex_trylock(_p_)
41#define kmutex_unlock(_p_) mutex_unlock(_p_)
42
43#ifndef min
44#define min(a, b) (((a) < (b)) ? (a) : (b))
45#endif
46
47#define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
48#define SMS_ALLOC_ALIGNMENT 128
49#define SMS_DMA_ALIGNMENT 16
50#define SMS_ALIGN_ADDRESS(addr) \
51 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
52
53#define SMS_DEVICE_FAMILY2 1
54#define SMS_ROM_NO_RESPONSE 2
55#define SMS_DEVICE_NOT_READY 0x8000000
56
57enum sms_device_type_st {
58 SMS_STELLAR = 0,
59 SMS_NOVA_A0,
60 SMS_NOVA_B0,
61 SMS_VEGA,
62 SMS_NUM_OF_DEVICE_TYPES
63};
64
65struct smscore_device_t;
66struct smscore_client_t;
67struct smscore_buffer_t;
68
69typedef int (*hotplug_t)(struct smscore_device_t *coredev,
70 struct device *device, int arrival);
71
72typedef int (*setmode_t)(void *context, int mode);
73typedef void (*detectmode_t)(void *context, int *mode);
74typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
75typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
76typedef int (*preload_t)(void *context);
77typedef int (*postload_t)(void *context);
78
79typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
80typedef void (*onremove_t)(void *context);
81
82struct smscore_buffer_t {
83 /* public members, once passed to clients can be changed freely */
84 struct list_head entry;
85 int size;
86 int offset;
87
88 /* private members, read-only for clients */
89 void *p;
90 dma_addr_t phys;
91 unsigned long offset_in_common;
92};
93
94struct smsdevice_params_t {
95 struct device *device;
96
97 int buffer_size;
98 int num_buffers;
99
100 char devpath[32];
101 unsigned long flags;
102
103 setmode_t setmode_handler;
104 detectmode_t detectmode_handler;
105 sendrequest_t sendrequest_handler;
106 preload_t preload_handler;
107 postload_t postload_handler;
108
109 void *context;
110 enum sms_device_type_st device_type;
111};
112
113struct smsclient_params_t {
114 int initial_id;
115 int data_type;
116 onresponse_t onresponse_handler;
117 onremove_t onremove_handler;
118 void *context;
119};
120
121struct smscore_device_t {
122 struct list_head entry;
123
124 struct list_head clients;
125 struct list_head subclients;
126 spinlock_t clientslock;
127
128 struct list_head buffers;
129 spinlock_t bufferslock;
130 int num_buffers;
131
132 void *common_buffer;
133 int common_buffer_size;
134 dma_addr_t common_buffer_phys;
135
136 void *context;
137 struct device *device;
138
139 char devpath[32];
140 unsigned long device_flags;
141
142 setmode_t setmode_handler;
143 detectmode_t detectmode_handler;
144 sendrequest_t sendrequest_handler;
145 preload_t preload_handler;
146 postload_t postload_handler;
147
148 int mode, modes_supported;
149
150 /* host <--> device messages */
151 struct completion version_ex_done, data_download_done, trigger_done;
152 struct completion init_device_done, reload_start_done, resume_done;
153 struct completion gpio_configuration_done, gpio_set_level_done;
154 struct completion gpio_get_level_done, ir_init_done;
155
156 /* Buffer management */
157 wait_queue_head_t buffer_mng_waitq;
158
159 /* GPIO */
160 int gpio_get_res;
161
162 /* Target hardware board */
163 int board_id;
164
165 /* Firmware */
166 u8 *fw_buf;
167 u32 fw_buf_size;
168
169 /* Infrared (IR) */
170 struct ir_t ir;
171
172 int led_state;
173};
174
175/* GPIO definitions for antenna frequency domain control (SMS8021) */
176#define SMS_ANTENNA_GPIO_0 1
177#define SMS_ANTENNA_GPIO_1 0
178
179#define BW_8_MHZ 0
180#define BW_7_MHZ 1
181#define BW_6_MHZ 2
182#define BW_5_MHZ 3
183#define BW_ISDBT_1SEG 4
184#define BW_ISDBT_3SEG 5
185
186#define MSG_HDR_FLAG_SPLIT_MSG 4
187
188#define MAX_GPIO_PIN_NUMBER 31
189
190#define HIF_TASK 11
191#define SMS_HOST_LIB 150
192#define DVBT_BDA_CONTROL_MSG_ID 201
193
194#define SMS_MAX_PAYLOAD_SIZE 240
195#define SMS_TUNE_TIMEOUT 500
196
197#define MSG_SMS_GPIO_CONFIG_REQ 507
198#define MSG_SMS_GPIO_CONFIG_RES 508
199#define MSG_SMS_GPIO_SET_LEVEL_REQ 509
200#define MSG_SMS_GPIO_SET_LEVEL_RES 510
201#define MSG_SMS_GPIO_GET_LEVEL_REQ 511
202#define MSG_SMS_GPIO_GET_LEVEL_RES 512
203#define MSG_SMS_RF_TUNE_REQ 561
204#define MSG_SMS_RF_TUNE_RES 562
205#define MSG_SMS_INIT_DEVICE_REQ 578
206#define MSG_SMS_INIT_DEVICE_RES 579
207#define MSG_SMS_ADD_PID_FILTER_REQ 601
208#define MSG_SMS_ADD_PID_FILTER_RES 602
209#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
210#define MSG_SMS_REMOVE_PID_FILTER_RES 604
211#define MSG_SMS_DAB_CHANNEL 607
212#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
213#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
214#define MSG_SMS_GET_STATISTICS_RES 616
215#define MSG_SMS_GET_STATISTICS_REQ 615
216#define MSG_SMS_HO_PER_SLICES_IND 630
217#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
218#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
219#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
220#define MSG_SMS_DATA_DOWNLOAD_REQ 660
221#define MSG_SMS_DATA_DOWNLOAD_RES 661
222#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
223#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
224#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
225#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
226#define MSG_SMS_GET_VERSION_EX_REQ 668
227#define MSG_SMS_GET_VERSION_EX_RES 669
228#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
229#define MSG_SMS_I2C_SET_FREQ_REQ 685
230#define MSG_SMS_GENERIC_I2C_REQ 687
231#define MSG_SMS_GENERIC_I2C_RES 688
232#define MSG_SMS_DVBT_BDA_DATA 693
233#define MSG_SW_RELOAD_REQ 697
234#define MSG_SMS_DATA_MSG 699
235#define MSG_SW_RELOAD_START_REQ 702
236#define MSG_SW_RELOAD_START_RES 703
237#define MSG_SW_RELOAD_EXEC_REQ 704
238#define MSG_SW_RELOAD_EXEC_RES 705
239#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
240#define MSG_SMS_GPIO_CONFIG_EX_REQ 712
241#define MSG_SMS_GPIO_CONFIG_EX_RES 713
242#define MSG_SMS_ISDBT_TUNE_REQ 776
243#define MSG_SMS_ISDBT_TUNE_RES 777
244#define MSG_SMS_TRANSMISSION_IND 782
245#define MSG_SMS_START_IR_REQ 800
246#define MSG_SMS_START_IR_RES 801
247#define MSG_SMS_IR_SAMPLES_IND 802
248#define MSG_SMS_SIGNAL_DETECTED_IND 827
249#define MSG_SMS_NO_SIGNAL_IND 828
250
251#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
252 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
253 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
254} while (0)
255
256#define SMS_INIT_MSG(ptr, type, len) \
257 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
258
259enum SMS_DVB3_EVENTS {
260 DVB3_EVENT_INIT = 0,
261 DVB3_EVENT_SLEEP,
262 DVB3_EVENT_HOTPLUG,
263 DVB3_EVENT_FE_LOCK,
264 DVB3_EVENT_FE_UNLOCK,
265 DVB3_EVENT_UNC_OK,
266 DVB3_EVENT_UNC_ERR
267};
268
269enum SMS_DEVICE_MODE {
270 DEVICE_MODE_NONE = -1,
271 DEVICE_MODE_DVBT = 0,
272 DEVICE_MODE_DVBH,
273 DEVICE_MODE_DAB_TDMB,
274 DEVICE_MODE_DAB_TDMB_DABIP,
275 DEVICE_MODE_DVBT_BDA,
276 DEVICE_MODE_ISDBT,
277 DEVICE_MODE_ISDBT_BDA,
278 DEVICE_MODE_CMMB,
279 DEVICE_MODE_RAW_TUNER,
280 DEVICE_MODE_MAX,
281};
282
283struct SmsMsgHdr_ST {
284 u16 msgType;
285 u8 msgSrcId;
286 u8 msgDstId;
287 u16 msgLength; /* Length of entire message, including header */
288 u16 msgFlags;
289};
290
291struct SmsMsgData_ST {
292 struct SmsMsgHdr_ST xMsgHeader;
293 u32 msgData[1];
294};
295
296struct SmsMsgData_ST2 {
297 struct SmsMsgHdr_ST xMsgHeader;
298 u32 msgData[2];
299};
300
301struct SmsDataDownload_ST {
302 struct SmsMsgHdr_ST xMsgHeader;
303 u32 MemAddr;
304 u8 Payload[SMS_MAX_PAYLOAD_SIZE];
305};
306
307struct SmsVersionRes_ST {
308 struct SmsMsgHdr_ST xMsgHeader;
309
310 u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
311 u8 Step; /* 0 - Step A */
312 u8 MetalFix; /* 0 - Metal 0 */
313
314 /* FirmwareId 0xFF if ROM, otherwise the
315 * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
316 u8 FirmwareId;
317 /* SupportedProtocols Bitwise OR combination of
318 * supported protocols */
319 u8 SupportedProtocols;
320
321 u8 VersionMajor;
322 u8 VersionMinor;
323 u8 VersionPatch;
324 u8 VersionFieldPatch;
325
326 u8 RomVersionMajor;
327 u8 RomVersionMinor;
328 u8 RomVersionPatch;
329 u8 RomVersionFieldPatch;
330
331 u8 TextLabel[34];
332};
333
334struct SmsFirmware_ST {
335 u32 CheckSum;
336 u32 Length;
337 u32 StartAddress;
338 u8 Payload[1];
339};
340
341/* Statistics information returned as response for
342 * SmsHostApiGetStatistics_Req */
343struct SMSHOSTLIB_STATISTICS_ST {
344 u32 Reserved; /* Reserved */
345
346 /* Common parameters */
347 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
348 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
349 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
350
351 /* Reception quality */
352 s32 SNR; /* dB */
353 u32 BER; /* Post Viterbi BER [1E-5] */
354 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
355 u32 TS_PER; /* Transport stream PER,
356 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
357 u32 MFER; /* DVB-H frame error rate in percentage,
358 0xFFFFFFFF indicate N/A, valid only for DVB-H */
359 s32 RSSI; /* dBm */
360 s32 InBandPwr; /* In band power in dBM */
361 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
362
363 /* Transmission parameters */
364 u32 Frequency; /* Frequency in Hz */
365 u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */
366 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
367 for DVB-T/H FFT mode carriers in Kilos */
368 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
369 valid only for DVB-T/H */
370 u32 GuardInterval; /* Guard Interval from
371 SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
372 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
373 valid only for DVB-T/H */
374 u32 LPCodeRate; /* Low Priority Code Rate from
375 SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
376 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
377 valid only for DVB-T/H */
378 u32 Constellation; /* Constellation from
379 SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
380
381 /* Burst parameters, valid only for DVB-H */
382 u32 BurstSize; /* Current burst size in bytes,
383 valid only for DVB-H */
384 u32 BurstDuration; /* Current burst duration in mSec,
385 valid only for DVB-H */
386 u32 BurstCycleTime; /* Current burst cycle time in mSec,
387 valid only for DVB-H */
388 u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
389 as calculated by demodulator, valid only for DVB-H */
390 u32 NumOfRows; /* Number of rows in MPE table,
391 valid only for DVB-H */
392 u32 NumOfPaddCols; /* Number of padding columns in MPE table,
393 valid only for DVB-H */
394 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table,
395 valid only for DVB-H */
396 u32 ErrorTSPackets; /* Number of erroneous
397 transport-stream packets */
398 u32 TotalTSPackets; /* Total number of transport-stream packets */
399 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
400 errors after MPE RS decoding */
401 u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
402 after MPE RS decoding */
403 u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
404 corrected by MPE RS decoding */
405 /* Common params */
406 u32 BERErrorCount; /* Number of errornous SYNC bits. */
407 u32 BERBitCount; /* Total number of SYNC bits. */
408
409 /* Interface information */
410 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
411
412 /* DAB/T-DMB */
413 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
414
415 /* DVB-H TPS parameters */
416 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
417 if set to 0xFFFFFFFF cell_id not yet recovered */
418 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
419 Time Slicing indicator, bit 0 - MPE-FEC indicator */
420 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
421 Time Slicing indicator, bit 0 - MPE-FEC indicator */
422
423 u32 NumMPEReceived; /* DVB-H, Num MPE section received */
424
425 u32 ReservedFields[10]; /* Reserved */
426};
427
428struct SmsMsgStatisticsInfo_ST {
429 u32 RequestResult;
430
431 struct SMSHOSTLIB_STATISTICS_ST Stat;
432
433 /* Split the calc of the SNR in DAB */
434 u32 Signal; /* dB */
435 u32 Noise; /* dB */
436
437};
438
439struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST {
440 /* Per-layer information */
441 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
442 * 255 means layer does not exist */
443 u32 Constellation; /* Constellation from SMSHOSTLIB_CONSTELLATION_ET,
444 * 255 means layer does not exist */
445 u32 BER; /* Post Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
446 u32 BERErrorCount; /* Post Viterbi Error Bits Count */
447 u32 BERBitCount; /* Post Viterbi Total Bits Count */
448 u32 PreBER; /* Pre Viterbi BER [1E-5], 0xFFFFFFFF indicate N/A */
449 u32 TS_PER; /* Transport stream PER [%], 0xFFFFFFFF indicate N/A */
450 u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
451 u32 TotalTSPackets; /* Total number of transport-stream packets */
452 u32 TILdepthI; /* Time interleaver depth I parameter,
453 * 255 means layer does not exist */
454 u32 NumberOfSegments; /* Number of segments in layer A,
455 * 255 means layer does not exist */
456 u32 TMCCErrors; /* TMCC errors */
457};
458
459struct SMSHOSTLIB_STATISTICS_ISDBT_ST {
460 u32 StatisticsType; /* Enumerator identifying the type of the
461 * structure. Values are the same as
462 * SMSHOSTLIB_DEVICE_MODES_E
463 *
464 * This field MUST always be first in any
465 * statistics structure */
466
467 u32 FullSize; /* Total size of the structure returned by the modem.
468 * If the size requested by the host is smaller than
469 * FullSize, the struct will be truncated */
470
471 /* Common parameters */
472 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
473 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
474 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
475
476 /* Reception quality */
477 s32 SNR; /* dB */
478 s32 RSSI; /* dBm */
479 s32 InBandPwr; /* In band power in dBM */
480 s32 CarrierOffset; /* Carrier Offset in Hz */
481
482 /* Transmission parameters */
483 u32 Frequency; /* Frequency in Hz */
484 u32 Bandwidth; /* Bandwidth in MHz */
485 u32 TransmissionMode; /* ISDB-T transmission mode */
486 u32 ModemState; /* 0 - Acquisition, 1 - Locked */
487 u32 GuardInterval; /* Guard Interval, 1 divided by value */
488 u32 SystemType; /* ISDB-T system type (ISDB-T / ISDB-Tsb) */
489 u32 PartialReception; /* TRUE - partial reception, FALSE otherwise */
490 u32 NumOfLayers; /* Number of ISDB-T layers in the network */
491
492 /* Per-layer information */
493 /* Layers A, B and C */
494 struct SMSHOSTLIB_ISDBT_LAYER_STAT_ST LayerInfo[3];
495 /* Per-layer statistics, see SMSHOSTLIB_ISDBT_LAYER_STAT_ST */
496
497 /* Interface information */
498 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
499};
500
501struct PID_STATISTICS_DATA_S {
502 struct PID_BURST_S {
503 u32 size;
504 u32 padding_cols;
505 u32 punct_cols;
506 u32 duration;
507 u32 cycle;
508 u32 calc_cycle;
509 } burst;
510
511 u32 tot_tbl_cnt;
512 u32 invalid_tbl_cnt;
513 u32 tot_cor_tbl;
514};
515
516struct PID_DATA_S {
517 u32 pid;
518 u32 num_rows;
519 struct PID_STATISTICS_DATA_S pid_statistics;
520};
521
522#define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
523#define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
524#define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
525 if (_stat.TransmissionMode == 0) \
526 _stat.TransmissionMode = 2; \
527 else if (_stat.TransmissionMode == 1) \
528 _stat.TransmissionMode = 8; \
529 else \
530 _stat.TransmissionMode = 4;
531
532struct TRANSMISSION_STATISTICS_S {
533 u32 Frequency; /* Frequency in Hz */
534 u32 Bandwidth; /* Bandwidth in MHz */
535 u32 TransmissionMode; /* FFT mode carriers in Kilos */
536 u32 GuardInterval; /* Guard Interval from
537 SMSHOSTLIB_GUARD_INTERVALS_ET */
538 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
539 u32 LPCodeRate; /* Low Priority Code Rate from
540 SMSHOSTLIB_CODE_RATE_ET */
541 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
542 u32 Constellation; /* Constellation from
543 SMSHOSTLIB_CONSTELLATION_ET */
544
545 /* DVB-H TPS parameters */
546 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
547 if set to 0xFFFFFFFF cell_id not yet recovered */
548 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
549 Time Slicing indicator, bit 0 - MPE-FEC indicator */
550 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
551 Time Slicing indicator, bit 0 - MPE-FEC indicator */
552 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
553};
554
555struct RECEPTION_STATISTICS_S {
556 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
557 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
558 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
559
560 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
561 s32 SNR; /* dB */
562 u32 BER; /* Post Viterbi BER [1E-5] */
563 u32 BERErrorCount; /* Number of erronous SYNC bits. */
564 u32 BERBitCount; /* Total number of SYNC bits. */
565 u32 TS_PER; /* Transport stream PER,
566 0xFFFFFFFF indicate N/A */
567 u32 MFER; /* DVB-H frame error rate in percentage,
568 0xFFFFFFFF indicate N/A, valid only for DVB-H */
569 s32 RSSI; /* dBm */
570 s32 InBandPwr; /* In band power in dBM */
571 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
572 u32 ErrorTSPackets; /* Number of erroneous
573 transport-stream packets */
574 u32 TotalTSPackets; /* Total number of transport-stream packets */
575
576 s32 MRC_SNR; /* dB */
577 s32 MRC_RSSI; /* dBm */
578 s32 MRC_InBandPwr; /* In band power in dBM */
579};
580
581
582/* Statistics information returned as response for
583 * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
584struct SMSHOSTLIB_STATISTICS_DVB_S {
585 /* Reception */
586 struct RECEPTION_STATISTICS_S ReceptionData;
587
588 /* Transmission parameters */
589 struct TRANSMISSION_STATISTICS_S TransmissionData;
590
591 /* Burst parameters, valid only for DVB-H */
592#define SRVM_MAX_PID_FILTERS 8
593 struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
594};
595
596struct SRVM_SIGNAL_STATUS_S {
597 u32 result;
598 u32 snr;
599 u32 tsPackets;
600 u32 etsPackets;
601 u32 constellation;
602 u32 hpCode;
603 u32 tpsSrvIndLP;
604 u32 tpsSrvIndHP;
605 u32 cellId;
606 u32 reason;
607
608 s32 inBandPower;
609 u32 requestId;
610};
611
612struct SMSHOSTLIB_I2C_REQ_ST {
613 u32 DeviceAddress; /* I2c device address */
614 u32 WriteCount; /* number of bytes to write */
615 u32 ReadCount; /* number of bytes to read */
616 u8 Data[1];
617};
618
619struct SMSHOSTLIB_I2C_RES_ST {
620 u32 Status; /* non-zero value in case of failure */
621 u32 ReadCount; /* number of bytes read */
622 u8 Data[1];
623};
624
625
626struct smscore_config_gpio {
627#define SMS_GPIO_DIRECTION_INPUT 0
628#define SMS_GPIO_DIRECTION_OUTPUT 1
629 u8 direction;
630
631#define SMS_GPIO_PULLUPDOWN_NONE 0
632#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
633#define SMS_GPIO_PULLUPDOWN_PULLUP 2
634#define SMS_GPIO_PULLUPDOWN_KEEPER 3
635 u8 pullupdown;
636
637#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0
638#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
639 u8 inputcharacteristics;
640
641#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
642#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
643 u8 outputslewrate;
644
645#define SMS_GPIO_OUTPUTDRIVING_4mA 0
646#define SMS_GPIO_OUTPUTDRIVING_8mA 1
647#define SMS_GPIO_OUTPUTDRIVING_12mA 2
648#define SMS_GPIO_OUTPUTDRIVING_16mA 3
649 u8 outputdriving;
650};
651
652struct smscore_gpio_config {
653#define SMS_GPIO_DIRECTION_INPUT 0
654#define SMS_GPIO_DIRECTION_OUTPUT 1
655 u8 Direction;
656
657#define SMS_GPIO_PULL_UP_DOWN_NONE 0
658#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
659#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2
660#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3
661 u8 PullUpDown;
662
663#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
664#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
665 u8 InputCharacteristics;
666
667#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
668#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
669
670
671#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
672#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
673#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
674#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
675 u8 OutputSlewRate;
676
677#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
678#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
679#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
680#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
681
682#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
683#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
684#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
685#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
686#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
687#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
688#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
689#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
690 u8 OutputDriving;
691};
692
693extern void smscore_registry_setmode(char *devpath, int mode);
694extern int smscore_registry_getmode(char *devpath);
695
696extern int smscore_register_hotplug(hotplug_t hotplug);
697extern void smscore_unregister_hotplug(hotplug_t hotplug);
698
699extern int smscore_register_device(struct smsdevice_params_t *params,
700 struct smscore_device_t **coredev);
701extern void smscore_unregister_device(struct smscore_device_t *coredev);
702
703extern int smscore_start_device(struct smscore_device_t *coredev);
704extern int smscore_load_firmware(struct smscore_device_t *coredev,
705 char *filename,
706 loadfirmware_t loadfirmware_handler);
707
708extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
709extern int smscore_get_device_mode(struct smscore_device_t *coredev);
710
711extern int smscore_register_client(struct smscore_device_t *coredev,
712 struct smsclient_params_t *params,
713 struct smscore_client_t **client);
714extern void smscore_unregister_client(struct smscore_client_t *client);
715
716extern int smsclient_sendrequest(struct smscore_client_t *client,
717 void *buffer, size_t size);
718extern void smscore_onresponse(struct smscore_device_t *coredev,
719 struct smscore_buffer_t *cb);
720
721extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
722extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
723 struct vm_area_struct *vma);
724extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
725 int mode, char *filename);
726extern int smscore_send_fw_file(struct smscore_device_t *coredev,
727 u8 *ufwbuf, int size);
728
729extern
730struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
731extern void smscore_putbuffer(struct smscore_device_t *coredev,
732 struct smscore_buffer_t *cb);
733
734/* old GPIO management */
735int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
736 struct smscore_config_gpio *pinconfig);
737int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
738
739/* new GPIO management */
740extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
741 struct smscore_gpio_config *pGpioConfig);
742extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
743 u8 NewLevel);
744extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
745 u8 *level);
746
747void smscore_set_board_id(struct smscore_device_t *core, int id);
748int smscore_get_board_id(struct smscore_device_t *core);
749
750int smscore_led_state(struct smscore_device_t *core, int led);
751
752
753/* ------------------------------------------------------------------------ */
754
755#define DBG_INFO 1
756#define DBG_ADV 2
757
758#define sms_printk(kern, fmt, arg...) \
759 printk(kern "%s: " fmt "\n", __func__, ##arg)
760
761#define dprintk(kern, lvl, fmt, arg...) do {\
762 if (sms_dbg & lvl) \
763 sms_printk(kern, fmt, ##arg); } while (0)
764
765#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
766#define sms_err(fmt, arg...) \
767 sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
768#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
769#define sms_info(fmt, arg...) \
770 dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
771#define sms_debug(fmt, arg...) \
772 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
773
774
775#endif /* __SMS_CORE_API_H__ */
diff --git a/drivers/media/common/siano/smsdvb.c b/drivers/media/common/siano/smsdvb.c
deleted file mode 100644
index aa77e54a8fa..00000000000
--- a/drivers/media/common/siano/smsdvb.c
+++ /dev/null
@@ -1,1078 +0,0 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2008, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#include <linux/module.h>
23#include <linux/slab.h>
24#include <linux/init.h>
25
26#include "dmxdev.h"
27#include "dvbdev.h"
28#include "dvb_demux.h"
29#include "dvb_frontend.h"
30
31#include "smscoreapi.h"
32#include "smsendian.h"
33#include "sms-cards.h"
34
35DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
36
37struct smsdvb_client_t {
38 struct list_head entry;
39
40 struct smscore_device_t *coredev;
41 struct smscore_client_t *smsclient;
42
43 struct dvb_adapter adapter;
44 struct dvb_demux demux;
45 struct dmxdev dmxdev;
46 struct dvb_frontend frontend;
47
48 fe_status_t fe_status;
49
50 struct completion tune_done;
51
52 struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb;
53 int event_fe_state;
54 int event_unc_state;
55};
56
57static struct list_head g_smsdvb_clients;
58static struct mutex g_smsdvb_clientslock;
59
60static int sms_dbg;
61module_param_named(debug, sms_dbg, int, 0644);
62MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
63
64/* Events that may come from DVB v3 adapter */
65static void sms_board_dvb3_event(struct smsdvb_client_t *client,
66 enum SMS_DVB3_EVENTS event) {
67
68 struct smscore_device_t *coredev = client->coredev;
69 switch (event) {
70 case DVB3_EVENT_INIT:
71 sms_debug("DVB3_EVENT_INIT");
72 sms_board_event(coredev, BOARD_EVENT_BIND);
73 break;
74 case DVB3_EVENT_SLEEP:
75 sms_debug("DVB3_EVENT_SLEEP");
76 sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND);
77 break;
78 case DVB3_EVENT_HOTPLUG:
79 sms_debug("DVB3_EVENT_HOTPLUG");
80 sms_board_event(coredev, BOARD_EVENT_POWER_INIT);
81 break;
82 case DVB3_EVENT_FE_LOCK:
83 if (client->event_fe_state != DVB3_EVENT_FE_LOCK) {
84 client->event_fe_state = DVB3_EVENT_FE_LOCK;
85 sms_debug("DVB3_EVENT_FE_LOCK");
86 sms_board_event(coredev, BOARD_EVENT_FE_LOCK);
87 }
88 break;
89 case DVB3_EVENT_FE_UNLOCK:
90 if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) {
91 client->event_fe_state = DVB3_EVENT_FE_UNLOCK;
92 sms_debug("DVB3_EVENT_FE_UNLOCK");
93 sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK);
94 }
95 break;
96 case DVB3_EVENT_UNC_OK:
97 if (client->event_unc_state != DVB3_EVENT_UNC_OK) {
98 client->event_unc_state = DVB3_EVENT_UNC_OK;
99 sms_debug("DVB3_EVENT_UNC_OK");
100 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK);
101 }
102 break;
103 case DVB3_EVENT_UNC_ERR:
104 if (client->event_unc_state != DVB3_EVENT_UNC_ERR) {
105 client->event_unc_state = DVB3_EVENT_UNC_ERR;
106 sms_debug("DVB3_EVENT_UNC_ERR");
107 sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS);
108 }
109 break;
110
111 default:
112 sms_err("Unknown dvb3 api event");
113 break;
114 }
115}
116
117
118static void smsdvb_update_dvb_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
119 struct SMSHOSTLIB_STATISTICS_ST *p)
120{
121 if (sms_dbg & 2) {
122 printk(KERN_DEBUG "Reserved = %d", p->Reserved);
123 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
124 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
125 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
126 printk(KERN_DEBUG "SNR = %d", p->SNR);
127 printk(KERN_DEBUG "BER = %d", p->BER);
128 printk(KERN_DEBUG "FIB_CRC = %d", p->FIB_CRC);
129 printk(KERN_DEBUG "TS_PER = %d", p->TS_PER);
130 printk(KERN_DEBUG "MFER = %d", p->MFER);
131 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
132 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
133 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
134 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
135 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
136 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
137 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
138 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
139 printk(KERN_DEBUG "CodeRate = %d", p->CodeRate);
140 printk(KERN_DEBUG "LPCodeRate = %d", p->LPCodeRate);
141 printk(KERN_DEBUG "Hierarchy = %d", p->Hierarchy);
142 printk(KERN_DEBUG "Constellation = %d", p->Constellation);
143 printk(KERN_DEBUG "BurstSize = %d", p->BurstSize);
144 printk(KERN_DEBUG "BurstDuration = %d", p->BurstDuration);
145 printk(KERN_DEBUG "BurstCycleTime = %d", p->BurstCycleTime);
146 printk(KERN_DEBUG "CalculatedBurstCycleTime = %d", p->CalculatedBurstCycleTime);
147 printk(KERN_DEBUG "NumOfRows = %d", p->NumOfRows);
148 printk(KERN_DEBUG "NumOfPaddCols = %d", p->NumOfPaddCols);
149 printk(KERN_DEBUG "NumOfPunctCols = %d", p->NumOfPunctCols);
150 printk(KERN_DEBUG "ErrorTSPackets = %d", p->ErrorTSPackets);
151 printk(KERN_DEBUG "TotalTSPackets = %d", p->TotalTSPackets);
152 printk(KERN_DEBUG "NumOfValidMpeTlbs = %d", p->NumOfValidMpeTlbs);
153 printk(KERN_DEBUG "NumOfInvalidMpeTlbs = %d", p->NumOfInvalidMpeTlbs);
154 printk(KERN_DEBUG "NumOfCorrectedMpeTlbs = %d", p->NumOfCorrectedMpeTlbs);
155 printk(KERN_DEBUG "BERErrorCount = %d", p->BERErrorCount);
156 printk(KERN_DEBUG "BERBitCount = %d", p->BERBitCount);
157 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
158 printk(KERN_DEBUG "PreBER = %d", p->PreBER);
159 printk(KERN_DEBUG "CellId = %d", p->CellId);
160 printk(KERN_DEBUG "DvbhSrvIndHP = %d", p->DvbhSrvIndHP);
161 printk(KERN_DEBUG "DvbhSrvIndLP = %d", p->DvbhSrvIndLP);
162 printk(KERN_DEBUG "NumMPEReceived = %d", p->NumMPEReceived);
163 }
164
165 pReceptionData->IsDemodLocked = p->IsDemodLocked;
166
167 pReceptionData->SNR = p->SNR;
168 pReceptionData->BER = p->BER;
169 pReceptionData->BERErrorCount = p->BERErrorCount;
170 pReceptionData->InBandPwr = p->InBandPwr;
171 pReceptionData->ErrorTSPackets = p->ErrorTSPackets;
172};
173
174
175static void smsdvb_update_isdbt_stats(struct RECEPTION_STATISTICS_S *pReceptionData,
176 struct SMSHOSTLIB_STATISTICS_ISDBT_ST *p)
177{
178 int i;
179
180 if (sms_dbg & 2) {
181 printk(KERN_DEBUG "IsRfLocked = %d", p->IsRfLocked);
182 printk(KERN_DEBUG "IsDemodLocked = %d", p->IsDemodLocked);
183 printk(KERN_DEBUG "IsExternalLNAOn = %d", p->IsExternalLNAOn);
184 printk(KERN_DEBUG "SNR = %d", p->SNR);
185 printk(KERN_DEBUG "RSSI = %d", p->RSSI);
186 printk(KERN_DEBUG "InBandPwr = %d", p->InBandPwr);
187 printk(KERN_DEBUG "CarrierOffset = %d", p->CarrierOffset);
188 printk(KERN_DEBUG "Frequency = %d", p->Frequency);
189 printk(KERN_DEBUG "Bandwidth = %d", p->Bandwidth);
190 printk(KERN_DEBUG "TransmissionMode = %d", p->TransmissionMode);
191 printk(KERN_DEBUG "ModemState = %d", p->ModemState);
192 printk(KERN_DEBUG "GuardInterval = %d", p->GuardInterval);
193 printk(KERN_DEBUG "SystemType = %d", p->SystemType);
194 printk(KERN_DEBUG "PartialReception = %d", p->PartialReception);
195 printk(KERN_DEBUG "NumOfLayers = %d", p->NumOfLayers);
196 printk(KERN_DEBUG "SmsToHostTxErrors = %d", p->SmsToHostTxErrors);
197
198 for (i = 0; i < 3; i++) {
199 printk(KERN_DEBUG "%d: CodeRate = %d", i, p->LayerInfo[i].CodeRate);
200 printk(KERN_DEBUG "%d: Constellation = %d", i, p->LayerInfo[i].Constellation);
201 printk(KERN_DEBUG "%d: BER = %d", i, p->LayerInfo[i].BER);
202 printk(KERN_DEBUG "%d: BERErrorCount = %d", i, p->LayerInfo[i].BERErrorCount);
203 printk(KERN_DEBUG "%d: BERBitCount = %d", i, p->LayerInfo[i].BERBitCount);
204 printk(KERN_DEBUG "%d: PreBER = %d", i, p->LayerInfo[i].PreBER);
205 printk(KERN_DEBUG "%d: TS_PER = %d", i, p->LayerInfo[i].TS_PER);
206 printk(KERN_DEBUG "%d: ErrorTSPackets = %d", i, p->LayerInfo[i].ErrorTSPackets);
207 printk(KERN_DEBUG "%d: TotalTSPackets = %d", i, p->LayerInfo[i].TotalTSPackets);
208 printk(KERN_DEBUG "%d: TILdepthI = %d", i, p->LayerInfo[i].TILdepthI);
209 printk(KERN_DEBUG "%d: NumberOfSegments = %d", i, p->LayerInfo[i].NumberOfSegments);
210 printk(KERN_DEBUG "%d: TMCCErrors = %d", i, p->LayerInfo[i].TMCCErrors);
211 }
212 }
213
214 pReceptionData->IsDemodLocked = p->IsDemodLocked;
215
216 pReceptionData->SNR = p->SNR;
217 pReceptionData->InBandPwr = p->InBandPwr;
218
219 pReceptionData->ErrorTSPackets = 0;
220 pReceptionData->BER = 0;
221 pReceptionData->BERErrorCount = 0;
222 for (i = 0; i < 3; i++) {
223 pReceptionData->BER += p->LayerInfo[i].BER;
224 pReceptionData->BERErrorCount += p->LayerInfo[i].BERErrorCount;
225 pReceptionData->ErrorTSPackets += p->LayerInfo[i].ErrorTSPackets;
226 }
227}
228
229static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
230{
231 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
232 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
233 + cb->offset);
234 u32 *pMsgData = (u32 *) phdr + 1;
235 /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
236 bool is_status_update = false;
237
238 smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);
239
240 switch (phdr->msgType) {
241 case MSG_SMS_DVBT_BDA_DATA:
242 dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
243 cb->size - sizeof(struct SmsMsgHdr_ST));
244 break;
245
246 case MSG_SMS_RF_TUNE_RES:
247 case MSG_SMS_ISDBT_TUNE_RES:
248 complete(&client->tune_done);
249 break;
250
251 case MSG_SMS_SIGNAL_DETECTED_IND:
252 sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
253 client->sms_stat_dvb.TransmissionData.IsDemodLocked = true;
254 is_status_update = true;
255 break;
256
257 case MSG_SMS_NO_SIGNAL_IND:
258 sms_info("MSG_SMS_NO_SIGNAL_IND");
259 client->sms_stat_dvb.TransmissionData.IsDemodLocked = false;
260 is_status_update = true;
261 break;
262
263 case MSG_SMS_TRANSMISSION_IND: {
264 sms_info("MSG_SMS_TRANSMISSION_IND");
265
266 pMsgData++;
267 memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
268 sizeof(struct TRANSMISSION_STATISTICS_S));
269
270 /* Mo need to correct guard interval
271 * (as opposed to old statistics message).
272 */
273 CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
274 CORRECT_STAT_TRANSMISSON_MODE(
275 client->sms_stat_dvb.TransmissionData);
276 is_status_update = true;
277 break;
278 }
279 case MSG_SMS_HO_PER_SLICES_IND: {
280 struct RECEPTION_STATISTICS_S *pReceptionData =
281 &client->sms_stat_dvb.ReceptionData;
282 struct SRVM_SIGNAL_STATUS_S SignalStatusData;
283
284 /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
285 pMsgData++;
286 SignalStatusData.result = pMsgData[0];
287 SignalStatusData.snr = pMsgData[1];
288 SignalStatusData.inBandPower = (s32) pMsgData[2];
289 SignalStatusData.tsPackets = pMsgData[3];
290 SignalStatusData.etsPackets = pMsgData[4];
291 SignalStatusData.constellation = pMsgData[5];
292 SignalStatusData.hpCode = pMsgData[6];
293 SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
294 SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
295 SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
296 SignalStatusData.reason = pMsgData[10];
297 SignalStatusData.requestId = pMsgData[11];
298 pReceptionData->IsRfLocked = pMsgData[16];
299 pReceptionData->IsDemodLocked = pMsgData[17];
300 pReceptionData->ModemState = pMsgData[12];
301 pReceptionData->SNR = pMsgData[1];
302 pReceptionData->BER = pMsgData[13];
303 pReceptionData->RSSI = pMsgData[14];
304 CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
305
306 pReceptionData->InBandPwr = (s32) pMsgData[2];
307 pReceptionData->CarrierOffset = (s32) pMsgData[15];
308 pReceptionData->TotalTSPackets = pMsgData[3];
309 pReceptionData->ErrorTSPackets = pMsgData[4];
310
311 /* TS PER */
312 if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
313 > 0) {
314 pReceptionData->TS_PER = (SignalStatusData.etsPackets
315 * 100) / (SignalStatusData.tsPackets
316 + SignalStatusData.etsPackets);
317 } else {
318 pReceptionData->TS_PER = 0;
319 }
320
321 pReceptionData->BERBitCount = pMsgData[18];
322 pReceptionData->BERErrorCount = pMsgData[19];
323
324 pReceptionData->MRC_SNR = pMsgData[20];
325 pReceptionData->MRC_InBandPwr = pMsgData[21];
326 pReceptionData->MRC_RSSI = pMsgData[22];
327
328 is_status_update = true;
329 break;
330 }
331 case MSG_SMS_GET_STATISTICS_RES: {
332 union {
333 struct SMSHOSTLIB_STATISTICS_ISDBT_ST isdbt;
334 struct SmsMsgStatisticsInfo_ST dvb;
335 } *p = (void *) (phdr + 1);
336 struct RECEPTION_STATISTICS_S *pReceptionData =
337 &client->sms_stat_dvb.ReceptionData;
338
339 sms_info("MSG_SMS_GET_STATISTICS_RES");
340
341 is_status_update = true;
342
343 switch (smscore_get_device_mode(client->coredev)) {
344 case DEVICE_MODE_ISDBT:
345 case DEVICE_MODE_ISDBT_BDA:
346 smsdvb_update_isdbt_stats(pReceptionData, &p->isdbt);
347 break;
348 default:
349 smsdvb_update_dvb_stats(pReceptionData, &p->dvb.Stat);
350 }
351 if (!pReceptionData->IsDemodLocked) {
352 pReceptionData->SNR = 0;
353 pReceptionData->BER = 0;
354 pReceptionData->BERErrorCount = 0;
355 pReceptionData->InBandPwr = 0;
356 pReceptionData->ErrorTSPackets = 0;
357 }
358
359 complete(&client->tune_done);
360 break;
361 }
362 default:
363 sms_info("Unhandled message %d", phdr->msgType);
364
365 }
366 smscore_putbuffer(client->coredev, cb);
367
368 if (is_status_update) {
369 if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
370 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
371 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
372 sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
373 if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets
374 == 0)
375 sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
376 else
377 sms_board_dvb3_event(client,
378 DVB3_EVENT_UNC_ERR);
379
380 } else {
381 if (client->sms_stat_dvb.ReceptionData.IsRfLocked)
382 client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
383 else
384 client->fe_status = 0;
385 sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
386 }
387 }
388
389 return 0;
390}
391
392static void smsdvb_unregister_client(struct smsdvb_client_t *client)
393{
394 /* must be called under clientslock */
395
396 list_del(&client->entry);
397
398 smscore_unregister_client(client->smsclient);
399 dvb_unregister_frontend(&client->frontend);
400 dvb_dmxdev_release(&client->dmxdev);
401 dvb_dmx_release(&client->demux);
402 dvb_unregister_adapter(&client->adapter);
403 kfree(client);
404}
405
406static void smsdvb_onremove(void *context)
407{
408 kmutex_lock(&g_smsdvb_clientslock);
409
410 smsdvb_unregister_client((struct smsdvb_client_t *) context);
411
412 kmutex_unlock(&g_smsdvb_clientslock);
413}
414
415static int smsdvb_start_feed(struct dvb_demux_feed *feed)
416{
417 struct smsdvb_client_t *client =
418 container_of(feed->demux, struct smsdvb_client_t, demux);
419 struct SmsMsgData_ST PidMsg;
420
421 sms_debug("add pid %d(%x)",
422 feed->pid, feed->pid);
423
424 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
425 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
426 PidMsg.xMsgHeader.msgFlags = 0;
427 PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ;
428 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
429 PidMsg.msgData[0] = feed->pid;
430
431 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
432 return smsclient_sendrequest(client->smsclient,
433 &PidMsg, sizeof(PidMsg));
434}
435
436static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
437{
438 struct smsdvb_client_t *client =
439 container_of(feed->demux, struct smsdvb_client_t, demux);
440 struct SmsMsgData_ST PidMsg;
441
442 sms_debug("remove pid %d(%x)",
443 feed->pid, feed->pid);
444
445 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
446 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
447 PidMsg.xMsgHeader.msgFlags = 0;
448 PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ;
449 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
450 PidMsg.msgData[0] = feed->pid;
451
452 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)&PidMsg);
453 return smsclient_sendrequest(client->smsclient,
454 &PidMsg, sizeof(PidMsg));
455}
456
457static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
458 void *buffer, size_t size,
459 struct completion *completion)
460{
461 int rc;
462
463 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)buffer);
464 rc = smsclient_sendrequest(client->smsclient, buffer, size);
465 if (rc < 0)
466 return rc;
467
468 return wait_for_completion_timeout(completion,
469 msecs_to_jiffies(2000)) ?
470 0 : -ETIME;
471}
472
473static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
474{
475 int rc;
476 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
477 DVBT_BDA_CONTROL_MSG_ID,
478 HIF_TASK,
479 sizeof(struct SmsMsgHdr_ST), 0 };
480
481 rc = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
482 &client->tune_done);
483
484 return rc;
485}
486
487static inline int led_feedback(struct smsdvb_client_t *client)
488{
489 if (client->fe_status & FE_HAS_LOCK)
490 return sms_board_led_feedback(client->coredev,
491 (client->sms_stat_dvb.ReceptionData.BER
492 == 0) ? SMS_LED_HI : SMS_LED_LO);
493 else
494 return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
495}
496
497static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
498{
499 int rc;
500 struct smsdvb_client_t *client;
501 client = container_of(fe, struct smsdvb_client_t, frontend);
502
503 rc = smsdvb_send_statistics_request(client);
504
505 *stat = client->fe_status;
506
507 led_feedback(client);
508
509 return rc;
510}
511
512static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
513{
514 int rc;
515 struct smsdvb_client_t *client;
516 client = container_of(fe, struct smsdvb_client_t, frontend);
517
518 rc = smsdvb_send_statistics_request(client);
519
520 *ber = client->sms_stat_dvb.ReceptionData.BER;
521
522 led_feedback(client);
523
524 return rc;
525}
526
527static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
528{
529 int rc;
530
531 struct smsdvb_client_t *client;
532 client = container_of(fe, struct smsdvb_client_t, frontend);
533
534 rc = smsdvb_send_statistics_request(client);
535
536 if (client->sms_stat_dvb.ReceptionData.InBandPwr < -95)
537 *strength = 0;
538 else if (client->sms_stat_dvb.ReceptionData.InBandPwr > -29)
539 *strength = 100;
540 else
541 *strength =
542 (client->sms_stat_dvb.ReceptionData.InBandPwr
543 + 95) * 3 / 2;
544
545 led_feedback(client);
546
547 return rc;
548}
549
550static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
551{
552 int rc;
553 struct smsdvb_client_t *client;
554 client = container_of(fe, struct smsdvb_client_t, frontend);
555
556 rc = smsdvb_send_statistics_request(client);
557
558 *snr = client->sms_stat_dvb.ReceptionData.SNR;
559
560 led_feedback(client);
561
562 return rc;
563}
564
565static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
566{
567 int rc;
568 struct smsdvb_client_t *client;
569 client = container_of(fe, struct smsdvb_client_t, frontend);
570
571 rc = smsdvb_send_statistics_request(client);
572
573 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
574
575 led_feedback(client);
576
577 return rc;
578}
579
580static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
581 struct dvb_frontend_tune_settings *tune)
582{
583 sms_debug("");
584
585 tune->min_delay_ms = 400;
586 tune->step_size = 250000;
587 tune->max_drift = 0;
588 return 0;
589}
590
591static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
592{
593 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
594 struct smsdvb_client_t *client =
595 container_of(fe, struct smsdvb_client_t, frontend);
596
597 struct {
598 struct SmsMsgHdr_ST Msg;
599 u32 Data[3];
600 } Msg;
601
602 int ret;
603
604 client->fe_status = FE_HAS_SIGNAL;
605 client->event_fe_state = -1;
606 client->event_unc_state = -1;
607 fe->dtv_property_cache.delivery_system = SYS_DVBT;
608
609 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
610 Msg.Msg.msgDstId = HIF_TASK;
611 Msg.Msg.msgFlags = 0;
612 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
613 Msg.Msg.msgLength = sizeof(Msg);
614 Msg.Data[0] = c->frequency;
615 Msg.Data[2] = 12000000;
616
617 sms_info("%s: freq %d band %d", __func__, c->frequency,
618 c->bandwidth_hz);
619
620 switch (c->bandwidth_hz / 1000000) {
621 case 8:
622 Msg.Data[1] = BW_8_MHZ;
623 break;
624 case 7:
625 Msg.Data[1] = BW_7_MHZ;
626 break;
627 case 6:
628 Msg.Data[1] = BW_6_MHZ;
629 break;
630 case 0:
631 return -EOPNOTSUPP;
632 default:
633 return -EINVAL;
634 }
635 /* Disable LNA, if any. An error is returned if no LNA is present */
636 ret = sms_board_lna_control(client->coredev, 0);
637 if (ret == 0) {
638 fe_status_t status;
639
640 /* tune with LNA off at first */
641 ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
642 &client->tune_done);
643
644 smsdvb_read_status(fe, &status);
645
646 if (status & FE_HAS_LOCK)
647 return ret;
648
649 /* previous tune didn't lock - enable LNA and tune again */
650 sms_board_lna_control(client->coredev, 1);
651 }
652
653 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
654 &client->tune_done);
655}
656
657static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
658{
659 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
660 struct smsdvb_client_t *client =
661 container_of(fe, struct smsdvb_client_t, frontend);
662
663 struct {
664 struct SmsMsgHdr_ST Msg;
665 u32 Data[4];
666 } Msg;
667
668 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
669
670 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
671 Msg.Msg.msgDstId = HIF_TASK;
672 Msg.Msg.msgFlags = 0;
673 Msg.Msg.msgType = MSG_SMS_ISDBT_TUNE_REQ;
674 Msg.Msg.msgLength = sizeof(Msg);
675
676 if (c->isdbt_sb_segment_idx == -1)
677 c->isdbt_sb_segment_idx = 0;
678
679 switch (c->isdbt_sb_segment_count) {
680 case 3:
681 Msg.Data[1] = BW_ISDBT_3SEG;
682 break;
683 case 1:
684 Msg.Data[1] = BW_ISDBT_1SEG;
685 break;
686 case 0: /* AUTO */
687 switch (c->bandwidth_hz / 1000000) {
688 case 8:
689 case 7:
690 c->isdbt_sb_segment_count = 3;
691 Msg.Data[1] = BW_ISDBT_3SEG;
692 break;
693 case 6:
694 c->isdbt_sb_segment_count = 1;
695 Msg.Data[1] = BW_ISDBT_1SEG;
696 break;
697 default: /* Assumes 6 MHZ bw */
698 c->isdbt_sb_segment_count = 1;
699 c->bandwidth_hz = 6000;
700 Msg.Data[1] = BW_ISDBT_1SEG;
701 break;
702 }
703 break;
704 default:
705 sms_info("Segment count %d not supported", c->isdbt_sb_segment_count);
706 return -EINVAL;
707 }
708
709 Msg.Data[0] = c->frequency;
710 Msg.Data[2] = 12000000;
711 Msg.Data[3] = c->isdbt_sb_segment_idx;
712
713 sms_info("%s: freq %d segwidth %d segindex %d\n", __func__,
714 c->frequency, c->isdbt_sb_segment_count,
715 c->isdbt_sb_segment_idx);
716
717 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
718 &client->tune_done);
719}
720
721static int smsdvb_set_frontend(struct dvb_frontend *fe)
722{
723 struct smsdvb_client_t *client =
724 container_of(fe, struct smsdvb_client_t, frontend);
725 struct smscore_device_t *coredev = client->coredev;
726
727 switch (smscore_get_device_mode(coredev)) {
728 case DEVICE_MODE_DVBT:
729 case DEVICE_MODE_DVBT_BDA:
730 return smsdvb_dvbt_set_frontend(fe);
731 case DEVICE_MODE_ISDBT:
732 case DEVICE_MODE_ISDBT_BDA:
733 return smsdvb_isdbt_set_frontend(fe);
734 default:
735 return -EINVAL;
736 }
737}
738
739static int smsdvb_get_frontend(struct dvb_frontend *fe)
740{
741 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
742 struct smsdvb_client_t *client =
743 container_of(fe, struct smsdvb_client_t, frontend);
744 struct smscore_device_t *coredev = client->coredev;
745 struct TRANSMISSION_STATISTICS_S *td =
746 &client->sms_stat_dvb.TransmissionData;
747
748 switch (smscore_get_device_mode(coredev)) {
749 case DEVICE_MODE_DVBT:
750 case DEVICE_MODE_DVBT_BDA:
751 fep->frequency = td->Frequency;
752
753 switch (td->Bandwidth) {
754 case 6:
755 fep->bandwidth_hz = 6000000;
756 break;
757 case 7:
758 fep->bandwidth_hz = 7000000;
759 break;
760 case 8:
761 fep->bandwidth_hz = 8000000;
762 break;
763 }
764
765 switch (td->TransmissionMode) {
766 case 2:
767 fep->transmission_mode = TRANSMISSION_MODE_2K;
768 break;
769 case 8:
770 fep->transmission_mode = TRANSMISSION_MODE_8K;
771 }
772
773 switch (td->GuardInterval) {
774 case 0:
775 fep->guard_interval = GUARD_INTERVAL_1_32;
776 break;
777 case 1:
778 fep->guard_interval = GUARD_INTERVAL_1_16;
779 break;
780 case 2:
781 fep->guard_interval = GUARD_INTERVAL_1_8;
782 break;
783 case 3:
784 fep->guard_interval = GUARD_INTERVAL_1_4;
785 break;
786 }
787
788 switch (td->CodeRate) {
789 case 0:
790 fep->code_rate_HP = FEC_1_2;
791 break;
792 case 1:
793 fep->code_rate_HP = FEC_2_3;
794 break;
795 case 2:
796 fep->code_rate_HP = FEC_3_4;
797 break;
798 case 3:
799 fep->code_rate_HP = FEC_5_6;
800 break;
801 case 4:
802 fep->code_rate_HP = FEC_7_8;
803 break;
804 }
805
806 switch (td->LPCodeRate) {
807 case 0:
808 fep->code_rate_LP = FEC_1_2;
809 break;
810 case 1:
811 fep->code_rate_LP = FEC_2_3;
812 break;
813 case 2:
814 fep->code_rate_LP = FEC_3_4;
815 break;
816 case 3:
817 fep->code_rate_LP = FEC_5_6;
818 break;
819 case 4:
820 fep->code_rate_LP = FEC_7_8;
821 break;
822 }
823
824 switch (td->Constellation) {
825 case 0:
826 fep->modulation = QPSK;
827 break;
828 case 1:
829 fep->modulation = QAM_16;
830 break;
831 case 2:
832 fep->modulation = QAM_64;
833 break;
834 }
835
836 switch (td->Hierarchy) {
837 case 0:
838 fep->hierarchy = HIERARCHY_NONE;
839 break;
840 case 1:
841 fep->hierarchy = HIERARCHY_1;
842 break;
843 case 2:
844 fep->hierarchy = HIERARCHY_2;
845 break;
846 case 3:
847 fep->hierarchy = HIERARCHY_4;
848 break;
849 }
850
851 fep->inversion = INVERSION_AUTO;
852 break;
853 case DEVICE_MODE_ISDBT:
854 case DEVICE_MODE_ISDBT_BDA:
855 fep->frequency = td->Frequency;
856 fep->bandwidth_hz = 6000000;
857 /* todo: retrive the other parameters */
858 break;
859 default:
860 return -EINVAL;
861 }
862
863 return 0;
864}
865
866static int smsdvb_init(struct dvb_frontend *fe)
867{
868 struct smsdvb_client_t *client =
869 container_of(fe, struct smsdvb_client_t, frontend);
870
871 sms_board_power(client->coredev, 1);
872
873 sms_board_dvb3_event(client, DVB3_EVENT_INIT);
874 return 0;
875}
876
877static int smsdvb_sleep(struct dvb_frontend *fe)
878{
879 struct smsdvb_client_t *client =
880 container_of(fe, struct smsdvb_client_t, frontend);
881
882 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
883 sms_board_power(client->coredev, 0);
884
885 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
886
887 return 0;
888}
889
890static void smsdvb_release(struct dvb_frontend *fe)
891{
892 /* do nothing */
893}
894
895static struct dvb_frontend_ops smsdvb_fe_ops = {
896 .info = {
897 .name = "Siano Mobile Digital MDTV Receiver",
898 .frequency_min = 44250000,
899 .frequency_max = 867250000,
900 .frequency_stepsize = 250000,
901 .caps = FE_CAN_INVERSION_AUTO |
902 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
903 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
904 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
905 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
906 FE_CAN_GUARD_INTERVAL_AUTO |
907 FE_CAN_RECOVER |
908 FE_CAN_HIERARCHY_AUTO,
909 },
910
911 .release = smsdvb_release,
912
913 .set_frontend = smsdvb_set_frontend,
914 .get_frontend = smsdvb_get_frontend,
915 .get_tune_settings = smsdvb_get_tune_settings,
916
917 .read_status = smsdvb_read_status,
918 .read_ber = smsdvb_read_ber,
919 .read_signal_strength = smsdvb_read_signal_strength,
920 .read_snr = smsdvb_read_snr,
921 .read_ucblocks = smsdvb_read_ucblocks,
922
923 .init = smsdvb_init,
924 .sleep = smsdvb_sleep,
925};
926
927static int smsdvb_hotplug(struct smscore_device_t *coredev,
928 struct device *device, int arrival)
929{
930 struct smsclient_params_t params;
931 struct smsdvb_client_t *client;
932 int rc;
933
934 /* device removal handled by onremove callback */
935 if (!arrival)
936 return 0;
937 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
938 if (!client) {
939 sms_err("kmalloc() failed");
940 return -ENOMEM;
941 }
942
943 /* register dvb adapter */
944 rc = dvb_register_adapter(&client->adapter,
945 sms_get_board(
946 smscore_get_board_id(coredev))->name,
947 THIS_MODULE, device, adapter_nr);
948 if (rc < 0) {
949 sms_err("dvb_register_adapter() failed %d", rc);
950 goto adapter_error;
951 }
952
953 /* init dvb demux */
954 client->demux.dmx.capabilities = DMX_TS_FILTERING;
955 client->demux.filternum = 32; /* todo: nova ??? */
956 client->demux.feednum = 32;
957 client->demux.start_feed = smsdvb_start_feed;
958 client->demux.stop_feed = smsdvb_stop_feed;
959
960 rc = dvb_dmx_init(&client->demux);
961 if (rc < 0) {
962 sms_err("dvb_dmx_init failed %d", rc);
963 goto dvbdmx_error;
964 }
965
966 /* init dmxdev */
967 client->dmxdev.filternum = 32;
968 client->dmxdev.demux = &client->demux.dmx;
969 client->dmxdev.capabilities = 0;
970
971 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
972 if (rc < 0) {
973 sms_err("dvb_dmxdev_init failed %d", rc);
974 goto dmxdev_error;
975 }
976
977 /* init and register frontend */
978 memcpy(&client->frontend.ops, &smsdvb_fe_ops,
979 sizeof(struct dvb_frontend_ops));
980
981 switch (smscore_get_device_mode(coredev)) {
982 case DEVICE_MODE_DVBT:
983 case DEVICE_MODE_DVBT_BDA:
984 client->frontend.ops.delsys[0] = SYS_DVBT;
985 break;
986 case DEVICE_MODE_ISDBT:
987 case DEVICE_MODE_ISDBT_BDA:
988 client->frontend.ops.delsys[0] = SYS_ISDBT;
989 break;
990 }
991
992 rc = dvb_register_frontend(&client->adapter, &client->frontend);
993 if (rc < 0) {
994 sms_err("frontend registration failed %d", rc);
995 goto frontend_error;
996 }
997
998 params.initial_id = 1;
999 params.data_type = MSG_SMS_DVBT_BDA_DATA;
1000 params.onresponse_handler = smsdvb_onresponse;
1001 params.onremove_handler = smsdvb_onremove;
1002 params.context = client;
1003
1004 rc = smscore_register_client(coredev, &params, &client->smsclient);
1005 if (rc < 0) {
1006 sms_err("smscore_register_client() failed %d", rc);
1007 goto client_error;
1008 }
1009
1010 client->coredev = coredev;
1011
1012 init_completion(&client->tune_done);
1013
1014 kmutex_lock(&g_smsdvb_clientslock);
1015
1016 list_add(&client->entry, &g_smsdvb_clients);
1017
1018 kmutex_unlock(&g_smsdvb_clientslock);
1019
1020 client->event_fe_state = -1;
1021 client->event_unc_state = -1;
1022 sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
1023
1024 sms_info("success");
1025 sms_board_setup(coredev);
1026
1027 return 0;
1028
1029client_error:
1030 dvb_unregister_frontend(&client->frontend);
1031
1032frontend_error:
1033 dvb_dmxdev_release(&client->dmxdev);
1034
1035dmxdev_error:
1036 dvb_dmx_release(&client->demux);
1037
1038dvbdmx_error:
1039 dvb_unregister_adapter(&client->adapter);
1040
1041adapter_error:
1042 kfree(client);
1043 return rc;
1044}
1045
1046static int __init smsdvb_module_init(void)
1047{
1048 int rc;
1049
1050 INIT_LIST_HEAD(&g_smsdvb_clients);
1051 kmutex_init(&g_smsdvb_clientslock);
1052
1053 rc = smscore_register_hotplug(smsdvb_hotplug);
1054
1055 sms_debug("");
1056
1057 return rc;
1058}
1059
1060static void __exit smsdvb_module_exit(void)
1061{
1062 smscore_unregister_hotplug(smsdvb_hotplug);
1063
1064 kmutex_lock(&g_smsdvb_clientslock);
1065
1066 while (!list_empty(&g_smsdvb_clients))
1067 smsdvb_unregister_client(
1068 (struct smsdvb_client_t *) g_smsdvb_clients.next);
1069
1070 kmutex_unlock(&g_smsdvb_clientslock);
1071}
1072
1073module_init(smsdvb_module_init);
1074module_exit(smsdvb_module_exit);
1075
1076MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
1077MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
1078MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
deleted file mode 100644
index e2657c2f010..00000000000
--- a/drivers/media/common/siano/smsendian.c
+++ /dev/null
@@ -1,103 +0,0 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20 ****************************************************************/
21
22#include <linux/export.h>
23#include <asm/byteorder.h>
24
25#include "smsendian.h"
26#include "smscoreapi.h"
27
28void smsendian_handle_tx_message(void *buffer)
29{
30#ifdef __BIG_ENDIAN
31 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
32 int i;
33 int msgWords;
34
35 switch (msg->xMsgHeader.msgType) {
36 case MSG_SMS_DATA_DOWNLOAD_REQ:
37 {
38 msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
39 break;
40 }
41
42 default:
43 msgWords = (msg->xMsgHeader.msgLength -
44 sizeof(struct SmsMsgHdr_ST))/4;
45
46 for (i = 0; i < msgWords; i++)
47 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
48
49 break;
50 }
51#endif /* __BIG_ENDIAN */
52}
53EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
54
55void smsendian_handle_rx_message(void *buffer)
56{
57#ifdef __BIG_ENDIAN
58 struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
59 int i;
60 int msgWords;
61
62 switch (msg->xMsgHeader.msgType) {
63 case MSG_SMS_GET_VERSION_EX_RES:
64 {
65 struct SmsVersionRes_ST *ver =
66 (struct SmsVersionRes_ST *) msg;
67 ver->ChipModel = le16_to_cpu(ver->ChipModel);
68 break;
69 }
70
71 case MSG_SMS_DVBT_BDA_DATA:
72 case MSG_SMS_DAB_CHANNEL:
73 case MSG_SMS_DATA_MSG:
74 {
75 break;
76 }
77
78 default:
79 {
80 msgWords = (msg->xMsgHeader.msgLength -
81 sizeof(struct SmsMsgHdr_ST))/4;
82
83 for (i = 0; i < msgWords; i++)
84 msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
85
86 break;
87 }
88 }
89#endif /* __BIG_ENDIAN */
90}
91EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
92
93void smsendian_handle_message_header(void *msg)
94{
95#ifdef __BIG_ENDIAN
96 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
97
98 phdr->msgType = le16_to_cpu(phdr->msgType);
99 phdr->msgLength = le16_to_cpu(phdr->msgLength);
100 phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
101#endif /* __BIG_ENDIAN */
102}
103EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/common/siano/smsendian.h b/drivers/media/common/siano/smsendian.h
deleted file mode 100644
index 1624d6fd367..00000000000
--- a/drivers/media/common/siano/smsendian.h
+++ /dev/null
@@ -1,32 +0,0 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 2 of the License, or
10(at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20****************************************************************/
21
22#ifndef __SMS_ENDIAN_H__
23#define __SMS_ENDIAN_H__
24
25#include <asm/byteorder.h>
26
27extern void smsendian_handle_tx_message(void *buffer);
28extern void smsendian_handle_rx_message(void *buffer);
29extern void smsendian_handle_message_header(void *msg);
30
31#endif /* __SMS_ENDIAN_H__ */
32
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
deleted file mode 100644
index b8c5cad7853..00000000000
--- a/drivers/media/common/siano/smsir.c
+++ /dev/null
@@ -1,114 +0,0 @@
1/****************************************************************
2
3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2009, Uri Shkolnik
6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
12 This program is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25 ****************************************************************/
26
27
28#include <linux/types.h>
29#include <linux/input.h>
30
31#include "smscoreapi.h"
32#include "smsir.h"
33#include "sms-cards.h"
34
35#define MODULE_NAME "smsmdtv"
36
37void sms_ir_event(struct smscore_device_t *coredev, const char *buf, int len)
38{
39 int i;
40 const s32 *samples = (const void *)buf;
41
42 for (i = 0; i < len >> 2; i++) {
43 DEFINE_IR_RAW_EVENT(ev);
44
45 ev.duration = abs(samples[i]) * 1000; /* Convert to ns */
46 ev.pulse = (samples[i] > 0) ? false : true;
47
48 ir_raw_event_store(coredev->ir.dev, &ev);
49 }
50 ir_raw_event_handle(coredev->ir.dev);
51}
52
53int sms_ir_init(struct smscore_device_t *coredev)
54{
55 int err;
56 int board_id = smscore_get_board_id(coredev);
57 struct rc_dev *dev;
58
59 sms_log("Allocating rc device");
60 dev = rc_allocate_device();
61 if (!dev) {
62 sms_err("Not enough memory");
63 return -ENOMEM;
64 }
65
66 coredev->ir.controller = 0; /* Todo: vega/nova SPI number */
67 coredev->ir.timeout = IR_DEFAULT_TIMEOUT;
68 sms_log("IR port %d, timeout %d ms",
69 coredev->ir.controller, coredev->ir.timeout);
70
71 snprintf(coredev->ir.name, sizeof(coredev->ir.name),
72 "SMS IR (%s)", sms_get_board(board_id)->name);
73
74 strlcpy(coredev->ir.phys, coredev->devpath, sizeof(coredev->ir.phys));
75 strlcat(coredev->ir.phys, "/ir0", sizeof(coredev->ir.phys));
76
77 dev->input_name = coredev->ir.name;
78 dev->input_phys = coredev->ir.phys;
79 dev->dev.parent = coredev->device;
80
81#if 0
82 /* TODO: properly initialize the parameters bellow */
83 dev->input_id.bustype = BUS_USB;
84 dev->input_id.version = 1;
85 dev->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
86 dev->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
87#endif
88
89 dev->priv = coredev;
90 dev->driver_type = RC_DRIVER_IR_RAW;
91 dev->allowed_protos = RC_BIT_ALL;
92 dev->map_name = sms_get_board(board_id)->rc_codes;
93 dev->driver_name = MODULE_NAME;
94
95 sms_log("Input device (IR) %s is set for key events", dev->input_name);
96
97 err = rc_register_device(dev);
98 if (err < 0) {
99 sms_err("Failed to register device");
100 rc_free_device(dev);
101 return err;
102 }
103
104 coredev->ir.dev = dev;
105 return 0;
106}
107
108void sms_ir_exit(struct smscore_device_t *coredev)
109{
110 if (coredev->ir.dev)
111 rc_unregister_device(coredev->ir.dev);
112
113 sms_log("");
114}
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
deleted file mode 100644
index 69b59b9eee2..00000000000
--- a/drivers/media/common/siano/smsir.h
+++ /dev/null
@@ -1,64 +0,0 @@
1/****************************************************************
2
3Siano Mobile Silicon, Inc.
4MDTV receiver kernel modules.
5Copyright (C) 2006-2009, Uri Shkolnik
6
7 Copyright (c) 2010 - Mauro Carvalho Chehab
8 - Ported the driver to use rc-core
9 - IR raw event decoding is now done at rc-core
10 - Code almost re-written
11
12This program is free software: you can redistribute it and/or modify
13it under the terms of the GNU General Public License as published by
14the Free Software Foundation, either version 2 of the License, or
15(at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU General Public License for more details.
21
22You should have received a copy of the GNU General Public License
23along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25****************************************************************/
26
27#ifndef __SMS_IR_H__
28#define __SMS_IR_H__
29
30#include <linux/input.h>
31#include <media/rc-core.h>
32
33#define IR_DEFAULT_TIMEOUT 100
34
35struct smscore_device_t;
36
37struct ir_t {
38 struct rc_dev *dev;
39 char name[40];
40 char phys[32];
41
42 char *rc_codes;
43 u64 protocol;
44
45 u32 timeout;
46 u32 controller;
47};
48
49#ifdef CONFIG_SMS_SIANO_RC
50int sms_ir_init(struct smscore_device_t *coredev);
51void sms_ir_exit(struct smscore_device_t *coredev);
52void sms_ir_event(struct smscore_device_t *coredev,
53 const char *buf, int len);
54#else
55inline static int sms_ir_init(struct smscore_device_t *coredev) {
56 return 0;
57}
58inline static void sms_ir_exit(struct smscore_device_t *coredev) {};
59inline static void sms_ir_event(struct smscore_device_t *coredev,
60 const char *buf, int len) {};
61#endif
62
63#endif /* __SMS_IR_H__ */
64