aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/Kconfig1
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.h2
-rw-r--r--drivers/media/dvb/dvb-core/demux.h2
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c8
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c17
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.c78
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ringbuffer.h12
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig15
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c553
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.h304
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.c83
-rw-r--r--drivers/media/dvb/dvb-usb/au6610.h22
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c146
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.h3
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h8
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.c38
-rw-r--r--drivers/media/dvb/dvb-usb/gl861.h2
-rw-r--r--drivers/media/dvb/frontends/au8522.c1
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c47
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h1
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.c24
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c1
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c1
-rw-r--r--drivers/media/dvb/frontends/tda10023.c197
-rw-r--r--drivers/media/dvb/frontends/tda1002x.h41
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c2
-rw-r--r--drivers/media/dvb/siano/Kconfig26
-rw-r--r--drivers/media/dvb/siano/Makefile8
-rw-r--r--drivers/media/dvb/siano/sms-cards.c102
-rw-r--r--drivers/media/dvb/siano/sms-cards.h45
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c1251
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h434
-rw-r--r--drivers/media/dvb/siano/smsdvb.c449
-rw-r--r--drivers/media/dvb/siano/smsusb.c459
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/Makefile7
-rw-r--r--drivers/media/dvb/ttpci/av7110.c47
-rw-r--r--drivers/media/dvb/ttpci/av7110.h1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.h3
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c12
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c24
-rw-r--r--drivers/media/dvb/ttpci/budget-core.c4
-rw-r--r--drivers/media/dvb/ttpci/budget-patch.c44
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c22
52 files changed, 4282 insertions, 291 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 7b21b49f1945..8bc1445bd33b 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -21,6 +21,7 @@ source "drivers/media/dvb/dvb-usb/Kconfig"
21source "drivers/media/dvb/ttusb-budget/Kconfig" 21source "drivers/media/dvb/ttusb-budget/Kconfig"
22source "drivers/media/dvb/ttusb-dec/Kconfig" 22source "drivers/media/dvb/ttusb-dec/Kconfig"
23source "drivers/media/dvb/cinergyT2/Kconfig" 23source "drivers/media/dvb/cinergyT2/Kconfig"
24source "drivers/media/dvb/siano/Kconfig"
24 25
25comment "Supported FlexCopII (B2C2) Adapters" 26comment "Supported FlexCopII (B2C2) Adapters"
26 depends on DVB_CORE && (PCI || USB) && I2C 27 depends on DVB_CORE && (PCI || USB) && I2C
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index a7ad0841e6fc..d6ba4d195201 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ cinergyT2/ dvb-usb/ pluto2/ siano/
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h
index 375fd2892a11..d19b59299d78 100644
--- a/drivers/media/dvb/bt8xx/bt878.h
+++ b/drivers/media/dvb/bt8xx/bt878.h
@@ -128,7 +128,7 @@ struct bt878 {
128 dma_addr_t buf_dma; 128 dma_addr_t buf_dma;
129 129
130 u32 risc_size; 130 u32 risc_size;
131 u32 *risc_cpu; 131 __le32 *risc_cpu;
132 dma_addr_t risc_dma; 132 dma_addr_t risc_dma;
133 u32 risc_pos; 133 u32 risc_pos;
134 134
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index b0d347daae47..eb91fd808c16 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -247,7 +247,7 @@ struct dmx_demux {
247 void* priv; /* Pointer to private data of the API client */ 247 void* priv; /* Pointer to private data of the API client */
248 int (*open) (struct dmx_demux* demux); 248 int (*open) (struct dmx_demux* demux);
249 int (*close) (struct dmx_demux* demux); 249 int (*close) (struct dmx_demux* demux);
250 int (*write) (struct dmx_demux* demux, const char* buf, size_t count); 250 int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
251 int (*allocate_ts_feed) (struct dmx_demux* demux, 251 int (*allocate_ts_feed) (struct dmx_demux* demux,
252 struct dmx_ts_feed** feed, 252 struct dmx_ts_feed** feed,
253 dmx_ts_cb callback); 253 dmx_ts_cb callback);
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index df5bef6a2517..1cf9fcb6f514 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -96,7 +96,7 @@ static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src,
96 if (avail > todo) 96 if (avail > todo)
97 avail = todo; 97 avail = todo;
98 98
99 ret = dvb_ringbuffer_read(src, (u8 *)buf, avail, 1); 99 ret = dvb_ringbuffer_read_user(src, buf, avail);
100 if (ret < 0) 100 if (ret < 0)
101 break; 101 break;
102 102
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 588fbe105c27..8e5dd7b1f034 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1357,7 +1357,7 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca,
1357 1357
1358 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); 1358 idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen);
1359 while (idx != -1) { 1359 while (idx != -1) {
1360 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); 1360 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1361 if (connection_id == -1) 1361 if (connection_id == -1)
1362 connection_id = hdr[0]; 1362 connection_id = hdr[0];
1363 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { 1363 if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) {
@@ -1438,7 +1438,7 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
1438 goto exit; 1438 goto exit;
1439 } 1439 }
1440 1440
1441 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2, 0); 1441 dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2);
1442 if (connection_id == -1) 1442 if (connection_id == -1)
1443 connection_id = hdr[0]; 1443 connection_id = hdr[0];
1444 if (hdr[0] == connection_id) { 1444 if (hdr[0] == connection_id) {
@@ -1449,8 +1449,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
1449 fraglen -= 2; 1449 fraglen -= 2;
1450 } 1450 }
1451 1451
1452 if ((status = dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 2, 1452 if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2,
1453 (u8 *)buf + pktlen, fraglen, 1)) < 0) { 1453 buf + pktlen, fraglen)) < 0) {
1454 goto exit; 1454 goto exit;
1455 } 1455 }
1456 pktlen += fraglen; 1456 pktlen += fraglen;
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 934e15fffc56..e2eca0b1fe7c 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1056,16 +1056,27 @@ static int dvbdmx_close(struct dmx_demux *demux)
1056 return 0; 1056 return 0;
1057} 1057}
1058 1058
1059static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) 1059static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count)
1060{ 1060{
1061 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1061 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1062 void *p;
1062 1063
1063 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) 1064 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1064 return -EINVAL; 1065 return -EINVAL;
1065 1066
1066 if (mutex_lock_interruptible(&dvbdemux->mutex)) 1067 p = kmalloc(count, GFP_USER);
1068 if (!p)
1069 return -ENOMEM;
1070 if (copy_from_user(p, buf, count)) {
1071 kfree(p);
1072 return -EFAULT;
1073 }
1074 if (mutex_lock_interruptible(&dvbdemux->mutex)) {
1075 kfree(p);
1067 return -ERESTARTSYS; 1076 return -ERESTARTSYS;
1068 dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count); 1077 }
1078 dvb_dmx_swfilter(dvbdemux, p, count);
1079 kfree(p);
1069 mutex_unlock(&dvbdemux->mutex); 1080 mutex_unlock(&dvbdemux->mutex);
1070 1081
1071 if (signal_pending(current)) 1082 if (signal_pending(current))
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index c2c033722a93..c93019ca519e 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -606,7 +606,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
606 if (priv->ule_dbit) { 606 if (priv->ule_dbit) {
607 /* Set D-bit for CRC32 verification, 607 /* Set D-bit for CRC32 verification,
608 * if it was set originally. */ 608 * if it was set originally. */
609 ulen |= 0x0080; 609 ulen |= htons(0x8000);
610 } 610 }
611 611
612 ule_crc = iov_crc32(ule_crc, iov, 3); 612 ule_crc = iov_crc32(ule_crc, iov, 3);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
index 872985b7912d..584bbd194dc8 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c
@@ -107,35 +107,43 @@ void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
107 wake_up(&rbuf->queue); 107 wake_up(&rbuf->queue);
108} 108}
109 109
110 110ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
111
112ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, int usermem)
113{ 111{
114 size_t todo = len; 112 size_t todo = len;
115 size_t split; 113 size_t split;
116 114
117 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; 115 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
118 if (split > 0) { 116 if (split > 0) {
119 if (!usermem) 117 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
120 memcpy(buf, rbuf->data+rbuf->pread, split); 118 return -EFAULT;
121 else
122 if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
123 return -EFAULT;
124 buf += split; 119 buf += split;
125 todo -= split; 120 todo -= split;
126 rbuf->pread = 0; 121 rbuf->pread = 0;
127 } 122 }
128 if (!usermem) 123 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
129 memcpy(buf, rbuf->data+rbuf->pread, todo); 124 return -EFAULT;
130 else
131 if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
132 return -EFAULT;
133 125
134 rbuf->pread = (rbuf->pread + todo) % rbuf->size; 126 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
135 127
136 return len; 128 return len;
137} 129}
138 130
131void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
132{
133 size_t todo = len;
134 size_t split;
135
136 split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
137 if (split > 0) {
138 memcpy(buf, rbuf->data+rbuf->pread, split);
139 buf += split;
140 todo -= split;
141 rbuf->pread = 0;
142 }
143 memcpy(buf, rbuf->data+rbuf->pread, todo);
144
145 rbuf->pread = (rbuf->pread + todo) % rbuf->size;
146}
139 147
140 148
141ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) 149ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
@@ -171,8 +179,8 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le
171 return status; 179 return status;
172} 180}
173 181
174ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 182ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
175 int offset, u8* buf, size_t len, int usermem) 183 int offset, u8 __user *buf, size_t len)
176{ 184{
177 size_t todo; 185 size_t todo;
178 size_t split; 186 size_t split;
@@ -187,21 +195,40 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
187 todo = len; 195 todo = len;
188 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; 196 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
189 if (split > 0) { 197 if (split > 0) {
190 if (!usermem) 198 if (copy_to_user(buf, rbuf->data+idx, split))
191 memcpy(buf, rbuf->data+idx, split); 199 return -EFAULT;
192 else
193 if (copy_to_user(buf, rbuf->data+idx, split))
194 return -EFAULT;
195 buf += split; 200 buf += split;
196 todo -= split; 201 todo -= split;
197 idx = 0; 202 idx = 0;
198 } 203 }
199 if (!usermem) 204 if (copy_to_user(buf, rbuf->data+idx, todo))
200 memcpy(buf, rbuf->data+idx, todo); 205 return -EFAULT;
201 else 206
202 if (copy_to_user(buf, rbuf->data+idx, todo)) 207 return len;
203 return -EFAULT; 208}
204 209
210ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
211 int offset, u8* buf, size_t len)
212{
213 size_t todo;
214 size_t split;
215 size_t pktlen;
216
217 pktlen = rbuf->data[idx] << 8;
218 pktlen |= rbuf->data[(idx + 1) % rbuf->size];
219 if (offset > pktlen) return -EINVAL;
220 if ((offset + len) > pktlen) len = pktlen - offset;
221
222 idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
223 todo = len;
224 split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
225 if (split > 0) {
226 memcpy(buf, rbuf->data+idx, split);
227 buf += split;
228 todo -= split;
229 idx = 0;
230 }
231 memcpy(buf, rbuf->data+idx, todo);
205 return len; 232 return len;
206} 233}
207 234
@@ -266,5 +293,6 @@ EXPORT_SYMBOL(dvb_ringbuffer_empty);
266EXPORT_SYMBOL(dvb_ringbuffer_free); 293EXPORT_SYMBOL(dvb_ringbuffer_free);
267EXPORT_SYMBOL(dvb_ringbuffer_avail); 294EXPORT_SYMBOL(dvb_ringbuffer_avail);
268EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); 295EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
296EXPORT_SYMBOL(dvb_ringbuffer_read_user);
269EXPORT_SYMBOL(dvb_ringbuffer_read); 297EXPORT_SYMBOL(dvb_ringbuffer_read);
270EXPORT_SYMBOL(dvb_ringbuffer_write); 298EXPORT_SYMBOL(dvb_ringbuffer_write);
diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
index 890826262966..41f04dae69b6 100644
--- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
+++ b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h
@@ -61,7 +61,7 @@ struct dvb_ringbuffer {
61** *** read min. 1000, max. <bufsize> bytes *** 61** *** read min. 1000, max. <bufsize> bytes ***
62** avail = dvb_ringbuffer_avail(rbuf); 62** avail = dvb_ringbuffer_avail(rbuf);
63** if (avail >= 1000) 63** if (avail >= 1000)
64** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize), 0); 64** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
65** else 65** else
66** ... 66** ...
67** 67**
@@ -114,8 +114,10 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
114** <usermem> specifies whether <buf> resides in user space 114** <usermem> specifies whether <buf> resides in user space
115** returns number of bytes transferred or -EFAULT 115** returns number of bytes transferred or -EFAULT
116*/ 116*/
117extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, 117extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
118 size_t len, int usermem); 118 u8 __user *buf, size_t len);
119extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
120 u8 *buf, size_t len);
119 121
120 122
121/* write routines & macros */ 123/* write routines & macros */
@@ -157,8 +159,10 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
157 * <usermem> Set to 1 if <buf> is in userspace. 159 * <usermem> Set to 1 if <buf> is in userspace.
158 * returns Number of bytes read, or -EFAULT. 160 * returns Number of bytes read, or -EFAULT.
159 */ 161 */
162extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
163 int offset, u8 __user *buf, size_t len);
160extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, 164extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
161 int offset, u8* buf, size_t len, int usermem); 165 int offset, u8 *buf, size_t len);
162 166
163/** 167/**
164 * Dispose of a packet in the ring buffer. 168 * Dispose of a packet in the ring buffer.
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index f00a0eb40420..a577c0f89f67 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -76,6 +76,7 @@ config DVB_USB_DIB0700
76 select DVB_DIB3000MC 76 select DVB_DIB3000MC
77 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE 77 select MEDIA_TUNER_MT2060 if !DVB_FE_CUSTOMISE
78 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE 78 select MEDIA_TUNER_MT2266 if !DVB_FE_CUSTOMISE
79 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
79 select DVB_TUNER_DIB0070 80 select DVB_TUNER_DIB0070
80 help 81 help
81 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The 82 Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
@@ -107,6 +108,8 @@ config DVB_USB_CXUSB
107 select DVB_MT352 if !DVB_FE_CUSTOMISE 108 select DVB_MT352 if !DVB_FE_CUSTOMISE
108 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 109 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
109 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE 110 select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
111 select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMISE
112 select MEDIA_TUNER_MXL5005S if !DVB_FE_CUSTOMISE
110 help 113 help
111 Say Y here to support the Conexant USB2.0 hybrid reference design. 114 Say Y here to support the Conexant USB2.0 hybrid reference design.
112 Currently, only DVB and ATSC modes are supported, analog mode 115 Currently, only DVB and ATSC modes are supported, analog mode
@@ -120,6 +123,8 @@ config DVB_USB_M920X
120 depends on DVB_USB 123 depends on DVB_USB
121 select DVB_MT352 if !DVB_FE_CUSTOMISE 124 select DVB_MT352 if !DVB_FE_CUSTOMISE
122 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE 125 select MEDIA_TUNER_QT1010 if !DVB_FE_CUSTOMISE
126 select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
127 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
123 help 128 help
124 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. 129 Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
125 Currently, only devices with a product id of 130 Currently, only devices with a product id of
@@ -241,3 +246,13 @@ config DVB_USB_AF9005_REMOTE
241 Say Y here to support the default remote control decoding for the 246 Say Y here to support the default remote control decoding for the
242 Afatech AF9005 based receiver. 247 Afatech AF9005 based receiver.
243 248
249config DVB_USB_ANYSEE
250 tristate "Anysee DVB-T/C USB2.0 support"
251 depends on DVB_USB
252 select DVB_PLL if !DVB_FE_CUSTOMISE
253 select DVB_MT352 if !DVB_FE_CUSTOMISE
254 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
255 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
256 help
257 Say Y here to support the Anysee E30, Anysee E30 Plus or
258 Anysee E30 C Plus DVB USB2.0 receiver.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index c6511a6c0ab8..44c11e45e564 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -61,6 +61,9 @@ obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o
61dvb-usb-af9005-remote-objs = af9005-remote.o 61dvb-usb-af9005-remote-objs = af9005-remote.o
62obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o 62obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
63 63
64dvb-usb-anysee-objs = anysee.o
65obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
66
64EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 67EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
65# due to tuner-xc3028 68# due to tuner-xc3028
66EXTRA_CFLAGS += -Idrivers/media/common/tuners 69EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
new file mode 100644
index 000000000000..adfd4fc82efd
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -0,0 +1,553 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
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 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#include "anysee.h"
35#include "tda1002x.h"
36#include "mt352.h"
37#include "mt352_priv.h"
38#include "zl10353.h"
39
40/* debug */
41static int dvb_usb_anysee_debug;
42module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
44DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
45
46struct mutex anysee_usb_mutex;
47
48static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
49 u8 *rbuf, u8 rlen)
50{
51 struct anysee_state *state = d->priv;
52 int act_len, ret;
53 u8 buf[64];
54
55 if (slen > sizeof(buf))
56 slen = sizeof(buf);
57 memcpy(&buf[0], sbuf, slen);
58 buf[60] = state->seq++;
59
60 if (mutex_lock_interruptible(&anysee_usb_mutex) < 0)
61 return -EAGAIN;
62
63 /* We need receive one message more after dvb_usb_generic_rw due
64 to weird transaction flow, which is 1 x send + 2 x receive. */
65 ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0);
66
67 if (!ret) {
68 /* receive 2nd answer */
69 ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev,
70 d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf),
71 &act_len, 2000);
72 if (ret)
73 err("%s: recv bulk message failed: %d", __func__, ret);
74 else {
75 deb_xfer("<<< ");
76 debug_dump(buf, act_len, deb_xfer);
77 }
78 }
79
80 /* read request, copy returned data to return buf */
81 if (!ret && rbuf && rlen)
82 memcpy(rbuf, buf, rlen);
83
84 mutex_unlock(&anysee_usb_mutex);
85
86 return ret;
87}
88
89static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
90{
91 u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01};
92 int ret;
93 ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1);
94 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val);
95 return ret;
96}
97
98static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val)
99{
100 u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val};
101 deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val);
102 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
103}
104
105static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
106{
107 u8 buf[] = {CMD_GET_HW_INFO};
108 return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3);
109}
110
111static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
112{
113 u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00};
114 deb_info("%s: onoff:%02x\n", __func__, onoff);
115 return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0);
116}
117
118static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval)
119{
120 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval};
121 deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval);
122 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
123}
124
125static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff)
126{
127 u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff};
128 deb_info("%s: onoff:%02x\n", __func__, onoff);
129 return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
130}
131
132static int anysee_init(struct dvb_usb_device *d)
133{
134 int ret;
135 /* LED light */
136 ret = anysee_led_ctrl(d, 0x01, 0x03);
137 if (ret)
138 return ret;
139
140 /* enable IR */
141 ret = anysee_ir_ctrl(d, 1);
142 if (ret)
143 return ret;
144
145 return 0;
146}
147
148/* I2C */
149static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
150 int num)
151{
152 struct dvb_usb_device *d = i2c_get_adapdata(adap);
153 int ret, inc, i = 0;
154
155 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
156 return -EAGAIN;
157
158 while (i < num) {
159 if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
160 u8 buf[6];
161 buf[0] = CMD_I2C_READ;
162 buf[1] = msg[i].addr + 1;
163 buf[2] = msg[i].buf[0];
164 buf[3] = 0x00;
165 buf[4] = 0x00;
166 buf[5] = 0x01;
167 ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
168 msg[i+1].len);
169 inc = 2;
170 } else {
171 u8 buf[4+msg[i].len];
172 buf[0] = CMD_I2C_WRITE;
173 buf[1] = msg[i].addr;
174 buf[2] = msg[i].len;
175 buf[3] = 0x01;
176 memcpy(&buf[4], msg[i].buf, msg[i].len);
177 ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
178 inc = 1;
179 }
180 if (ret)
181 return ret;
182
183 i += inc;
184 }
185
186 mutex_unlock(&d->i2c_mutex);
187
188 return i;
189}
190
191static u32 anysee_i2c_func(struct i2c_adapter *adapter)
192{
193 return I2C_FUNC_I2C;
194}
195
196static struct i2c_algorithm anysee_i2c_algo = {
197 .master_xfer = anysee_master_xfer,
198 .functionality = anysee_i2c_func,
199};
200
201static int anysee_mt352_demod_init(struct dvb_frontend *fe)
202{
203 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 };
204 static u8 reset [] = { RESET, 0x80 };
205 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
206 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 };
207 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
208 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
209
210 mt352_write(fe, clock_config, sizeof(clock_config));
211 udelay(200);
212 mt352_write(fe, reset, sizeof(reset));
213 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
214
215 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
216 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
217 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
218
219 return 0;
220}
221
222/* Callbacks for DVB USB */
223static struct tda10023_config anysee_tda10023_config = {
224 .demod_address = 0x1a,
225 .invert = 0,
226 .xtal = 16000000,
227 .pll_m = 11,
228 .pll_p = 3,
229 .pll_n = 1,
230 .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
231 .deltaf = 0xfeeb,
232};
233
234static struct mt352_config anysee_mt352_config = {
235 .demod_address = 0x1e,
236 .demod_init = anysee_mt352_demod_init,
237};
238
239static struct zl10353_config anysee_zl10353_config = {
240 .demod_address = 0x1e,
241 .parallel_ts = 1,
242};
243
244static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
245{
246 int ret;
247 struct anysee_state *state = adap->dev->priv;
248 u8 hw_info[3];
249 u8 io_d; /* IO port D */
250
251 /* check which hardware we have
252 We must do this call two times to get reliable values (hw bug). */
253 ret = anysee_get_hw_info(adap->dev, hw_info);
254 if (ret)
255 return ret;
256 ret = anysee_get_hw_info(adap->dev, hw_info);
257 if (ret)
258 return ret;
259
260 /* Meaning of these info bytes are guessed. */
261 info("firmware version:%d.%d.%d hardware id:%d",
262 0, hw_info[1], hw_info[2], hw_info[0]);
263
264 ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */
265 if (ret)
266 return ret;
267 deb_info("%s: IO port D:%02x\n", __func__, io_d);
268
269 /* Select demod using trial and error method. */
270
271 /* Try to attach demodulator in following order:
272 model demod hw firmware
273 1. E30 MT352 02 0.2.1
274 2. E30 ZL10353 02 0.2.1
275 3. E30 Plus ZL10353 06 0.1.0
276 4. E30C Plus TDA10023 0a 0.1.0 rev 0.2
277 4. E30C Plus TDA10023 0f 0.1.2 rev 0.4
278 */
279
280 /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
281 adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
282 &adap->dev->i2c_adap);
283 if (adap->fe != NULL) {
284 state->tuner = DVB_PLL_THOMSON_DTT7579;
285 return 0;
286 }
287
288 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
289 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
290 &adap->dev->i2c_adap);
291 if (adap->fe != NULL) {
292 state->tuner = DVB_PLL_THOMSON_DTT7579;
293 return 0;
294 }
295
296 /* connect demod on IO port D for TDA10023 & ZL10353 */
297 ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
298 if (ret)
299 return ret;
300
301 /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
302 adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
303 &adap->dev->i2c_adap);
304 if (adap->fe != NULL) {
305 state->tuner = DVB_PLL_THOMSON_DTT7579;
306 return 0;
307 }
308
309 /* IO port E - E30C rev 0.4 board requires this */
310 ret = anysee_write_reg(adap->dev, 0xb1, 0xa7);
311 if (ret)
312 return ret;
313
314 /* Philips TDA10023 DVB-C demod */
315 adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
316 &adap->dev->i2c_adap, 0x48);
317 if (adap->fe != NULL) {
318 state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
319 return 0;
320 }
321
322 /* return IO port D to init value for safe */
323 ret = anysee_write_reg(adap->dev, 0xb0, io_d);
324 if (ret)
325 return ret;
326
327 err("Unkown Anysee version: %02x %02x %02x. "\
328 "Please report the <linux-dvb@linuxtv.org>.",
329 hw_info[0], hw_info[1], hw_info[2]);
330
331 return -ENODEV;
332}
333
334static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
335{
336 struct anysee_state *state = adap->dev->priv;
337 deb_info("%s: \n", __func__);
338
339 switch (state->tuner) {
340 case DVB_PLL_THOMSON_DTT7579:
341 /* Thomson dtt7579 (not sure) PLL inside of:
342 Samsung DNOS404ZH102A NIM
343 Samsung DNOS404ZH103A NIM */
344 dvb_attach(dvb_pll_attach, adap->fe, 0x61,
345 NULL, DVB_PLL_THOMSON_DTT7579);
346 break;
347 case DVB_PLL_SAMSUNG_DTOS403IH102A:
348 /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */
349 dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
350 &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
351 break;
352 }
353
354 return 0;
355}
356
357static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
358{
359 u8 buf[] = {CMD_GET_IR_CODE};
360 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
361 u8 ircode[2];
362 int i, ret;
363
364 ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2);
365 if (ret)
366 return ret;
367
368 *event = 0;
369 *state = REMOTE_NO_KEY_PRESSED;
370
371 for (i = 0; i < d->props.rc_key_map_size; i++) {
372 if (keymap[i].custom == ircode[0] &&
373 keymap[i].data == ircode[1]) {
374 *event = keymap[i].event;
375 *state = REMOTE_KEY_PRESSED;
376 return 0;
377 }
378 }
379 return 0;
380}
381
382static struct dvb_usb_rc_key anysee_rc_keys[] = {
383 { 0x01, 0x00, KEY_0 },
384 { 0x01, 0x01, KEY_1 },
385 { 0x01, 0x02, KEY_2 },
386 { 0x01, 0x03, KEY_3 },
387 { 0x01, 0x04, KEY_4 },
388 { 0x01, 0x05, KEY_5 },
389 { 0x01, 0x06, KEY_6 },
390 { 0x01, 0x07, KEY_7 },
391 { 0x01, 0x08, KEY_8 },
392 { 0x01, 0x09, KEY_9 },
393 { 0x01, 0x0a, KEY_POWER },
394 { 0x01, 0x0b, KEY_DOCUMENTS }, /* * */
395 { 0x01, 0x19, KEY_FAVORITES },
396 { 0x01, 0x20, KEY_SLEEP },
397 { 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */
398 { 0x01, 0x22, KEY_ZOOM },
399 { 0x01, 0x47, KEY_TEXT },
400 { 0x01, 0x16, KEY_TV }, /* TV / radio select */
401 { 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */
402 { 0x01, 0x1a, KEY_SUBTITLE },
403 { 0x01, 0x1b, KEY_CAMERA }, /* screenshot */
404 { 0x01, 0x42, KEY_MUTE },
405 { 0x01, 0x0e, KEY_MENU },
406 { 0x01, 0x0f, KEY_EPG },
407 { 0x01, 0x17, KEY_INFO },
408 { 0x01, 0x10, KEY_EXIT },
409 { 0x01, 0x13, KEY_VOLUMEUP },
410 { 0x01, 0x12, KEY_VOLUMEDOWN },
411 { 0x01, 0x11, KEY_CHANNELUP },
412 { 0x01, 0x14, KEY_CHANNELDOWN },
413 { 0x01, 0x15, KEY_OK },
414 { 0x01, 0x1d, KEY_RED },
415 { 0x01, 0x1f, KEY_GREEN },
416 { 0x01, 0x1c, KEY_YELLOW },
417 { 0x01, 0x44, KEY_BLUE },
418 { 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */
419 { 0x01, 0x48, KEY_STOP },
420 { 0x01, 0x50, KEY_PLAY },
421 { 0x01, 0x51, KEY_PAUSE },
422 { 0x01, 0x49, KEY_RECORD },
423 { 0x01, 0x18, KEY_PREVIOUS }, /* |<< */
424 { 0x01, 0x0d, KEY_NEXT }, /* >>| */
425 { 0x01, 0x24, KEY_PROG1 }, /* F1 */
426 { 0x01, 0x25, KEY_PROG2 }, /* F2 */
427};
428
429/* DVB USB Driver stuff */
430static struct dvb_usb_device_properties anysee_properties;
431
432static int anysee_probe(struct usb_interface *intf,
433 const struct usb_device_id *id)
434{
435 struct dvb_usb_device *d;
436 struct usb_host_interface *alt;
437 int ret;
438
439 mutex_init(&anysee_usb_mutex);
440
441 /* There is one interface with two alternate settings.
442 Alternate setting 0 is for bulk transfer.
443 Alternate setting 1 is for isochronous transfer.
444 We use bulk transfer (alternate setting 0). */
445 if (intf->num_altsetting < 1)
446 return -ENODEV;
447
448 ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
449 adapter_nr);
450 if (ret)
451 return ret;
452
453 alt = usb_altnum_to_altsetting(intf, 0);
454 if (alt == NULL) {
455 deb_info("%s: no alt found!\n", __func__);
456 return -ENODEV;
457 }
458
459 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
460 alt->desc.bAlternateSetting);
461 if (ret)
462 return ret;
463
464 if (d)
465 ret = anysee_init(d);
466
467 return ret;
468}
469
470static struct usb_device_id anysee_table [] = {
471 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
472 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
473 { } /* Terminating entry */
474};
475MODULE_DEVICE_TABLE(usb, anysee_table);
476
477static struct dvb_usb_device_properties anysee_properties = {
478 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
479
480 .usb_ctrl = DEVICE_SPECIFIC,
481
482 .size_of_priv = sizeof(struct anysee_state),
483
484 .num_adapters = 1,
485 .adapter = {
486 {
487 .streaming_ctrl = anysee_streaming_ctrl,
488 .frontend_attach = anysee_frontend_attach,
489 .tuner_attach = anysee_tuner_attach,
490 .stream = {
491 .type = USB_BULK,
492 .count = 8,
493 .endpoint = 0x82,
494 .u = {
495 .bulk = {
496 .buffersize = 512,
497 }
498 }
499 },
500 }
501 },
502
503 .rc_key_map = anysee_rc_keys,
504 .rc_key_map_size = ARRAY_SIZE(anysee_rc_keys),
505 .rc_query = anysee_rc_query,
506 .rc_interval = 200, /* windows driver uses 500ms */
507
508 .i2c_algo = &anysee_i2c_algo,
509
510 .generic_bulk_ctrl_endpoint = 1,
511
512 .num_device_descs = 1,
513 .devices = {
514 {
515 .name = "Anysee DVB USB2.0",
516 .cold_ids = {NULL},
517 .warm_ids = {&anysee_table[0],
518 &anysee_table[1], NULL},
519 },
520 }
521};
522
523static struct usb_driver anysee_driver = {
524 .name = "dvb_usb_anysee",
525 .probe = anysee_probe,
526 .disconnect = dvb_usb_device_exit,
527 .id_table = anysee_table,
528};
529
530/* module stuff */
531static int __init anysee_module_init(void)
532{
533 int ret;
534
535 ret = usb_register(&anysee_driver);
536 if (ret)
537 err("%s: usb_register failed. Error number %d", __func__, ret);
538
539 return ret;
540}
541
542static void __exit anysee_module_exit(void)
543{
544 /* deregister this driver from the USB subsystem */
545 usb_deregister(&anysee_driver);
546}
547
548module_init(anysee_module_init);
549module_exit(anysee_module_exit);
550
551MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
552MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0");
553MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h
new file mode 100644
index 000000000000..7ca01ff6e13c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/anysee.h
@@ -0,0 +1,304 @@
1/*
2 * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver
3 *
4 * Copyright (C) 2007 Antti Palosaari <crope@iki.fi>
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 * TODO:
21 * - add smart card reader support for Conditional Access (CA)
22 *
23 * Card reader in Anysee is nothing more than ISO 7816 card reader.
24 * There is no hardware CAM in any Anysee device sold.
25 * In my understanding it should be implemented by making own module
26 * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This
27 * module registers serial interface that can be used to communicate
28 * with any ISO 7816 smart card.
29 *
30 * Any help according to implement serial smart card reader support
31 * is highly welcome!
32 */
33
34#ifndef _DVB_USB_ANYSEE_H_
35#define _DVB_USB_ANYSEE_H_
36
37#define DVB_USB_LOG_PREFIX "anysee"
38#include "dvb-usb.h"
39
40#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args)
41#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args)
42#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args)
43#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args)
44#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args)
45#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args)
46
47enum cmd {
48 CMD_I2C_READ = 0x33,
49 CMD_I2C_WRITE = 0x31,
50 CMD_REG_READ = 0xb0,
51 CMD_REG_WRITE = 0xb1,
52 CMD_STREAMING_CTRL = 0x12,
53 CMD_LED_AND_IR_CTRL = 0x16,
54 CMD_GET_IR_CODE = 0x41,
55 CMD_GET_HW_INFO = 0x19,
56 CMD_SMARTCARD = 0x34,
57};
58
59struct anysee_state {
60 u8 tuner;
61 u8 seq;
62};
63
64#endif
65
66/***************************************************************************
67 * USB API description (reverse engineered)
68 ***************************************************************************
69
70Transaction flow:
71=================
72BULK[00001] >>> REQUEST PACKET 64 bytes
73BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY)
74BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY)
75
76General reply packet(s) are always used if not own reply defined.
77
78============================================================================
79| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY)
80============================================================================
81| 00 | reply data (if any) from previous transaction
82| | Just same reply packet as returned during previous transaction.
83| | Needed only if reply is missed in previous transaction.
84| | Just skip normally.
85----------------------------------------------------------------------------
86| 01-59 | don't care
87----------------------------------------------------------------------------
88| 60 | packet sequence number
89----------------------------------------------------------------------------
90| 61-63 | don't care
91----------------------------------------------------------------------------
92
93============================================================================
94| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY)
95============================================================================
96| 00 | reply data (if any)
97----------------------------------------------------------------------------
98| 01-59 | don't care
99----------------------------------------------------------------------------
100| 60 | packet sequence number
101----------------------------------------------------------------------------
102| 61-63 | don't care
103----------------------------------------------------------------------------
104
105============================================================================
106| 00-63 | I2C WRITE REQUEST PACKET
107============================================================================
108| 00 | 0x31 I2C write command
109----------------------------------------------------------------------------
110| 01 | i2c address
111----------------------------------------------------------------------------
112| 02 | data length
113| | 0x02 (for typical I2C reg / val pair)
114----------------------------------------------------------------------------
115| 03 | 0x01
116----------------------------------------------------------------------------
117| 04- | data
118----------------------------------------------------------------------------
119| -59 | don't care
120----------------------------------------------------------------------------
121| 60 | packet sequence number
122----------------------------------------------------------------------------
123| 61-63 | don't care
124----------------------------------------------------------------------------
125
126============================================================================
127| 00-63 | I2C READ REQUEST PACKET
128============================================================================
129| 00 | 0x33 I2C read command
130----------------------------------------------------------------------------
131| 01 | i2c address + 1
132----------------------------------------------------------------------------
133| 02 | register
134----------------------------------------------------------------------------
135| 03 | 0x00
136----------------------------------------------------------------------------
137| 04 | 0x00
138----------------------------------------------------------------------------
139| 05 | 0x01
140----------------------------------------------------------------------------
141| 06-59 | don't care
142----------------------------------------------------------------------------
143| 60 | packet sequence number
144----------------------------------------------------------------------------
145| 61-63 | don't care
146----------------------------------------------------------------------------
147
148============================================================================
149| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET
150============================================================================
151| 00 | 0xb1 register write command
152----------------------------------------------------------------------------
153| 01-02 | register
154----------------------------------------------------------------------------
155| 03 | 0x01
156----------------------------------------------------------------------------
157| 04 | value
158----------------------------------------------------------------------------
159| 05-59 | don't care
160----------------------------------------------------------------------------
161| 60 | packet sequence number
162----------------------------------------------------------------------------
163| 61-63 | don't care
164----------------------------------------------------------------------------
165
166============================================================================
167| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET
168============================================================================
169| 00 | 0xb0 register read command
170----------------------------------------------------------------------------
171| 01-02 | register
172----------------------------------------------------------------------------
173| 03 | 0x01
174----------------------------------------------------------------------------
175| 04-59 | don't care
176----------------------------------------------------------------------------
177| 60 | packet sequence number
178----------------------------------------------------------------------------
179| 61-63 | don't care
180----------------------------------------------------------------------------
181
182============================================================================
183| 00-63 | LED CONTROL REQUEST PACKET
184============================================================================
185| 00 | 0x16 LED and IR control command
186----------------------------------------------------------------------------
187| 01 | 0x01 (LED)
188----------------------------------------------------------------------------
189| 03 | 0x00 blink
190| | 0x01 lights continuously
191----------------------------------------------------------------------------
192| 04 | blink interval
193| | 0x00 fastest (looks like LED lights continuously)
194| | 0xff slowest
195----------------------------------------------------------------------------
196| 05-59 | don't care
197----------------------------------------------------------------------------
198| 60 | packet sequence number
199----------------------------------------------------------------------------
200| 61-63 | don't care
201----------------------------------------------------------------------------
202
203============================================================================
204| 00-63 | IR CONTROL REQUEST PACKET
205============================================================================
206| 00 | 0x16 LED and IR control command
207----------------------------------------------------------------------------
208| 01 | 0x02 (IR)
209----------------------------------------------------------------------------
210| 03 | 0x00 IR disabled
211| | 0x01 IR enabled
212----------------------------------------------------------------------------
213| 04-59 | don't care
214----------------------------------------------------------------------------
215| 60 | packet sequence number
216----------------------------------------------------------------------------
217| 61-63 | don't care
218----------------------------------------------------------------------------
219
220============================================================================
221| 00-63 | STREAMING CONTROL REQUEST PACKET
222============================================================================
223| 00 | 0x12 streaming control command
224----------------------------------------------------------------------------
225| 01 | 0x00 streaming disabled
226| | 0x01 streaming enabled
227----------------------------------------------------------------------------
228| 02 | 0x00
229----------------------------------------------------------------------------
230| 03-59 | don't care
231----------------------------------------------------------------------------
232| 60 | packet sequence number
233----------------------------------------------------------------------------
234| 61-63 | don't care
235----------------------------------------------------------------------------
236
237============================================================================
238| 00-63 | REMOTE CONTROL REQUEST PACKET
239============================================================================
240| 00 | 0x41 remote control command
241----------------------------------------------------------------------------
242| 01-59 | don't care
243----------------------------------------------------------------------------
244| 60 | packet sequence number
245----------------------------------------------------------------------------
246| 61-63 | don't care
247----------------------------------------------------------------------------
248
249============================================================================
250| 00-63 | REMOTE CONTROL REPLY PACKET
251============================================================================
252| 00 | 0x00 code not received
253| | 0x01 code received
254----------------------------------------------------------------------------
255| 01 | remote control code
256----------------------------------------------------------------------------
257| 02-59 | don't care
258----------------------------------------------------------------------------
259| 60 | packet sequence number
260----------------------------------------------------------------------------
261| 61-63 | don't care
262----------------------------------------------------------------------------
263
264============================================================================
265| 00-63 | GET HARDWARE INFO REQUEST PACKET
266============================================================================
267| 00 | 0x19 get hardware info command
268----------------------------------------------------------------------------
269| 01-59 | don't care
270----------------------------------------------------------------------------
271| 60 | packet sequence number
272----------------------------------------------------------------------------
273| 61-63 | don't care
274----------------------------------------------------------------------------
275
276============================================================================
277| 00-63 | GET HARDWARE INFO REPLY PACKET
278============================================================================
279| 00 | hardware id
280----------------------------------------------------------------------------
281| 01-02 | firmware version
282----------------------------------------------------------------------------
283| 03-59 | don't care
284----------------------------------------------------------------------------
285| 60 | packet sequence number
286----------------------------------------------------------------------------
287| 61-63 | don't care
288----------------------------------------------------------------------------
289
290============================================================================
291| 00-63 | SMART CARD READER PACKET
292============================================================================
293| 00 | 0x34 smart card reader command
294----------------------------------------------------------------------------
295| xx |
296----------------------------------------------------------------------------
297| xx-59 | don't care
298----------------------------------------------------------------------------
299| 60 | packet sequence number
300----------------------------------------------------------------------------
301| 61-63 | don't care
302----------------------------------------------------------------------------
303
304*/
diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c
index 2ccb90fa60c8..eb34cc3894e0 100644
--- a/drivers/media/dvb/dvb-usb/au6610.c
+++ b/drivers/media/dvb/dvb-usb/au6610.c
@@ -1,24 +1,31 @@
1/* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver 1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
2 * 3 *
3 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi> 4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
4 * 5 *
5 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify
6 * under the terms of the GNU General Public License as published by the Free 7 * it under the terms of the GNU General Public License as published by
7 * Software Foundation, version 2. 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
8 * 10 *
9 * see Documentation/dvb/README.dvb-usb for more information 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.
10 */ 19 */
11 20
12#include "au6610.h" 21#include "au6610.h"
13
14#include "zl10353.h" 22#include "zl10353.h"
15#include "qt1010.h" 23#include "qt1010.h"
16 24
17/* debug */ 25/* debug */
18static int dvb_usb_au6610_debug; 26static int dvb_usb_au6610_debug;
19module_param_named(debug, dvb_usb_au6610_debug, int, 0644); 27module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
20MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); 28MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 29DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23 30
24static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, 31static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
@@ -42,9 +49,8 @@ static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
42 } 49 }
43 50
44 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, 51 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
45 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, usb_buf, 52 USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
46 sizeof(usb_buf), AU6610_USB_TIMEOUT); 53 usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT);
47
48 if (ret < 0) 54 if (ret < 0)
49 return ret; 55 return ret;
50 56
@@ -116,15 +122,6 @@ static struct i2c_algorithm au6610_i2c_algo = {
116}; 122};
117 123
118/* Callbacks for DVB USB */ 124/* Callbacks for DVB USB */
119static int au6610_identify_state(struct usb_device *udev,
120 struct dvb_usb_device_properties *props,
121 struct dvb_usb_device_description **desc,
122 int *cold)
123{
124 *cold = 0;
125 return 0;
126}
127
128static struct zl10353_config au6610_zl10353_config = { 125static struct zl10353_config au6610_zl10353_config = {
129 .demod_address = 0x0f, 126 .demod_address = 0x0f,
130 .no_tuner = 1, 127 .no_tuner = 1,
@@ -133,12 +130,12 @@ static struct zl10353_config au6610_zl10353_config = {
133 130
134static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) 131static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
135{ 132{
136 if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, 133 adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
137 &adap->dev->i2c_adap)) != NULL) { 134 &adap->dev->i2c_adap);
138 return 0; 135 if (adap->fe == NULL)
139 } 136 return -ENODEV;
140 137
141 return -EIO; 138 return 0;
142} 139}
143 140
144static struct qt1010_config au6610_qt1010_config = { 141static struct qt1010_config au6610_qt1010_config = {
@@ -171,7 +168,7 @@ static int au6610_probe(struct usb_interface *intf,
171 alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING); 168 alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
172 169
173 if (alt == NULL) { 170 if (alt == NULL) {
174 deb_rc("no alt found!\n"); 171 deb_info("%s: no alt found!\n", __func__);
175 return -ENODEV; 172 return -ENODEV;
176 } 173 }
177 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, 174 ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
@@ -181,18 +178,19 @@ static int au6610_probe(struct usb_interface *intf,
181 return ret; 178 return ret;
182} 179}
183 180
184
185static struct usb_device_id au6610_table [] = { 181static struct usb_device_id au6610_table [] = {
186 { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) }, 182 { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) },
187 { } /* Terminating entry */ 183 { } /* Terminating entry */
188}; 184};
189MODULE_DEVICE_TABLE (usb, au6610_table); 185MODULE_DEVICE_TABLE(usb, au6610_table);
190 186
191static struct dvb_usb_device_properties au6610_properties = { 187static struct dvb_usb_device_properties au6610_properties = {
192 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 188 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
189
193 .usb_ctrl = DEVICE_SPECIFIC, 190 .usb_ctrl = DEVICE_SPECIFIC,
194 .size_of_priv = 0, 191
195 .identify_state = au6610_identify_state, 192 .size_of_priv = 0,
193
196 .num_adapters = 1, 194 .num_adapters = 1,
197 .adapter = { 195 .adapter = {
198 { 196 {
@@ -206,20 +204,22 @@ static struct dvb_usb_device_properties au6610_properties = {
206 .u = { 204 .u = {
207 .isoc = { 205 .isoc = {
208 .framesperurb = 40, 206 .framesperurb = 40,
209 .framesize = 942, /* maximum packet size */ 207 .framesize = 942,
210 .interval = 1.25, /* 125 us */ 208 .interval = 1,
211 } 209 }
212 } 210 }
213 }, 211 },
214 } 212 }
215 }, 213 },
214
216 .i2c_algo = &au6610_i2c_algo, 215 .i2c_algo = &au6610_i2c_algo,
216
217 .num_device_descs = 1, 217 .num_device_descs = 1,
218 .devices = { 218 .devices = {
219 { 219 {
220 "Sigmatek DVB-110 DVB-T USB2.0", 220 .name = "Sigmatek DVB-110 DVB-T USB2.0",
221 { &au6610_table[0], NULL }, 221 .cold_ids = {NULL},
222 { NULL }, 222 .warm_ids = {&au6610_table[0], NULL},
223 }, 223 },
224 } 224 }
225}; 225};
@@ -236,12 +236,11 @@ static int __init au6610_module_init(void)
236{ 236{
237 int ret; 237 int ret;
238 238
239 if ((ret = usb_register(&au6610_driver))) { 239 ret = usb_register(&au6610_driver);
240 if (ret)
240 err("usb_register failed. Error number %d", ret); 241 err("usb_register failed. Error number %d", ret);
241 return ret;
242 }
243 242
244 return 0; 243 return ret;
245} 244}
246 245
247static void __exit au6610_module_exit(void) 246static void __exit au6610_module_exit(void)
@@ -250,10 +249,10 @@ static void __exit au6610_module_exit(void)
250 usb_deregister(&au6610_driver); 249 usb_deregister(&au6610_driver);
251} 250}
252 251
253module_init (au6610_module_init); 252module_init(au6610_module_init);
254module_exit (au6610_module_exit); 253module_exit(au6610_module_exit);
255 254
256MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 255MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
257MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610"); 256MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0");
258MODULE_VERSION("0.1"); 257MODULE_VERSION("0.1");
259MODULE_LICENSE("GPL"); 258MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h
index 4161b054c713..7849abe2c614 100644
--- a/drivers/media/dvb/dvb-usb/au6610.h
+++ b/drivers/media/dvb/dvb-usb/au6610.h
@@ -1,10 +1,30 @@
1/*
2 * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0.
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
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
1#ifndef _DVB_USB_AU6610_H_ 21#ifndef _DVB_USB_AU6610_H_
2#define _DVB_USB_AU6610_H_ 22#define _DVB_USB_AU6610_H_
3 23
4#define DVB_USB_LOG_PREFIX "au6610" 24#define DVB_USB_LOG_PREFIX "au6610"
5#include "dvb-usb.h" 25#include "dvb-usb.h"
6 26
7#define deb_rc(args...) dprintk(dvb_usb_au6610_debug,0x01,args) 27#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args)
8 28
9#define AU6610_REQ_I2C_WRITE 0x14 29#define AU6610_REQ_I2C_WRITE 0x14
10#define AU6610_REQ_I2C_READ 0x13 30#define AU6610_REQ_I2C_READ 0x13
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 0286156704f2..578afce6884c 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -35,6 +35,7 @@
35#include "zl10353.h" 35#include "zl10353.h"
36#include "tuner-xc2028.h" 36#include "tuner-xc2028.h"
37#include "tuner-simple.h" 37#include "tuner-simple.h"
38#include "mxl5005s.h"
38 39
39/* debug */ 40/* debug */
40static int dvb_usb_cxusb_debug; 41static int dvb_usb_cxusb_debug;
@@ -43,9 +44,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_ST
43 44
44DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 45DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
45 46
46#define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) 47#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args)
47#define deb_i2c(args...) if (d->udev->descriptor.idVendor == USB_VID_MEDION) \ 48#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
48 dprintk(dvb_usb_cxusb_debug,0x01,args)
49 49
50static int cxusb_ctrl_msg(struct dvb_usb_device *d, 50static int cxusb_ctrl_msg(struct dvb_usb_device *d,
51 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) 51 u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
@@ -202,6 +202,46 @@ static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff)
202 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); 202 return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0);
203} 203}
204 204
205static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
206{
207 int ret;
208 if (!onoff)
209 return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0);
210 if (d->state == DVB_USB_STATE_INIT &&
211 usb_set_interface(d->udev, 0, 0) < 0)
212 err("set interface failed");
213 do; while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) &&
214 !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) &&
215 !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0);
216 if (!ret) {
217 /* FIXME: We don't know why, but we need to configure the
218 * lgdt3303 with the register settings below on resume */
219 int i;
220 u8 buf, bufs[] = {
221 0x0e, 0x2, 0x00, 0x7f,
222 0x0e, 0x2, 0x02, 0xfe,
223 0x0e, 0x2, 0x02, 0x01,
224 0x0e, 0x2, 0x00, 0x03,
225 0x0e, 0x2, 0x0d, 0x40,
226 0x0e, 0x2, 0x0e, 0x87,
227 0x0e, 0x2, 0x0f, 0x8e,
228 0x0e, 0x2, 0x10, 0x01,
229 0x0e, 0x2, 0x14, 0xd7,
230 0x0e, 0x2, 0x47, 0x88,
231 };
232 msleep(20);
233 for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
234 ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
235 bufs+i, 4, &buf, 1);
236 if (ret)
237 break;
238 if (buf != 0x8)
239 return -EREMOTEIO;
240 }
241 }
242 return ret;
243}
244
205static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) 245static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff)
206{ 246{
207 u8 b = 0; 247 u8 b = 0;
@@ -233,6 +273,16 @@ static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
233 return 0; 273 return 0;
234} 274}
235 275
276static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
277{
278 if (onoff)
279 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0);
280 else
281 cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF,
282 NULL, 0, NULL, 0);
283 return 0;
284}
285
236static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 286static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
237{ 287{
238 struct dvb_usb_rc_key *keymap = d->props.rc_key_map; 288 struct dvb_usb_rc_key *keymap = d->props.rc_key_map;
@@ -423,6 +473,12 @@ static struct lgdt330x_config cxusb_lgdt3303_config = {
423 .demod_chip = LGDT3303, 473 .demod_chip = LGDT3303,
424}; 474};
425 475
476static struct lgdt330x_config cxusb_aver_lgdt3303_config = {
477 .demod_address = 0x0e,
478 .demod_chip = LGDT3303,
479 .clock_polarity_flip = 2,
480};
481
426static struct mt352_config cxusb_dee1601_config = { 482static struct mt352_config cxusb_dee1601_config = {
427 .demod_address = 0x0f, 483 .demod_address = 0x0f,
428 .demod_init = cxusb_dee1601_demod_init, 484 .demod_init = cxusb_dee1601_demod_init,
@@ -453,6 +509,24 @@ static struct mt352_config cxusb_mt352_xc3028_config = {
453 .demod_init = cxusb_mt352_demod_init, 509 .demod_init = cxusb_mt352_demod_init,
454}; 510};
455 511
512/* FIXME: needs tweaking */
513static struct mxl5005s_config aver_a868r_tuner = {
514 .i2c_address = 0x63,
515 .if_freq = 6000000UL,
516 .xtal_freq = CRYSTAL_FREQ_16000000HZ,
517 .agc_mode = MXL_SINGLE_AGC,
518 .tracking_filter = MXL_TF_C,
519 .rssi_enable = MXL_RSSI_ENABLE,
520 .cap_select = MXL_CAP_SEL_ENABLE,
521 .div_out = MXL_DIV_OUT_4,
522 .clock_out = MXL_CLOCK_OUT_DISABLE,
523 .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
524 .top = MXL5005S_TOP_25P2,
525 .mod_mode = MXL_DIGITAL_MODE,
526 .if_mode = MXL_ZERO_IF,
527 .AgcMasterByte = 0x00,
528};
529
456/* Callbacks for DVB USB */ 530/* Callbacks for DVB USB */
457static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) 531static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap)
458{ 532{
@@ -533,6 +607,13 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap)
533 return 0; 607 return 0;
534} 608}
535 609
610static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
611{
612 dvb_attach(mxl5005s_attach, adap->fe,
613 &adap->dev->i2c_adap, &aver_a868r_tuner);
614 return 0;
615}
616
536static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) 617static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap)
537{ 618{
538 u8 b; 619 u8 b;
@@ -562,6 +643,16 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
562 return -EIO; 643 return -EIO;
563} 644}
564 645
646static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap)
647{
648 adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config,
649 &adap->dev->i2c_adap);
650 if (adap->fe != NULL)
651 return 0;
652
653 return -EIO;
654}
655
565static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) 656static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap)
566{ 657{
567 /* used in both lgz201 and th7579 */ 658 /* used in both lgz201 and th7579 */
@@ -736,6 +827,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties;
736static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; 827static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties;
737static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; 828static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties;
738static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; 829static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties;
830static struct dvb_usb_device_properties cxusb_aver_a868r_properties;
739 831
740static int cxusb_probe(struct usb_interface *intf, 832static int cxusb_probe(struct usb_interface *intf,
741 const struct usb_device_id *id) 833 const struct usb_device_id *id)
@@ -756,7 +848,10 @@ static int cxusb_probe(struct usb_interface *intf,
756 THIS_MODULE, NULL, adapter_nr) || 848 THIS_MODULE, NULL, adapter_nr) ||
757 0 == dvb_usb_device_init(intf, 849 0 == dvb_usb_device_init(intf,
758 &cxusb_bluebird_nano2_needsfirmware_properties, 850 &cxusb_bluebird_nano2_needsfirmware_properties,
759 THIS_MODULE, NULL, adapter_nr)) 851 THIS_MODULE, NULL, adapter_nr) ||
852 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties,
853 THIS_MODULE, NULL, adapter_nr) ||
854 0)
760 return 0; 855 return 0;
761 856
762 return -EINVAL; 857 return -EINVAL;
@@ -779,6 +874,7 @@ static struct usb_device_id cxusb_table [] = {
779 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, 874 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) },
780 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, 875 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) },
781 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, 876 { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) },
877 { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) },
782 {} /* Terminating entry */ 878 {} /* Terminating entry */
783}; 879};
784MODULE_DEVICE_TABLE (usb, cxusb_table); 880MODULE_DEVICE_TABLE (usb, cxusb_table);
@@ -1182,6 +1278,48 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope
1182 } 1278 }
1183}; 1279};
1184 1280
1281static struct dvb_usb_device_properties cxusb_aver_a868r_properties = {
1282 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1283
1284 .usb_ctrl = CYPRESS_FX2,
1285
1286 .size_of_priv = sizeof(struct cxusb_state),
1287
1288 .num_adapters = 1,
1289 .adapter = {
1290 {
1291 .streaming_ctrl = cxusb_aver_streaming_ctrl,
1292 .frontend_attach = cxusb_aver_lgdt3303_frontend_attach,
1293 .tuner_attach = cxusb_mxl5003s_tuner_attach,
1294 /* parameter for the MPEG2-data transfer */
1295 .stream = {
1296 .type = USB_BULK,
1297 .count = 5,
1298 .endpoint = 0x04,
1299 .u = {
1300 .bulk = {
1301 .buffersize = 8192,
1302 }
1303 }
1304 },
1305
1306 },
1307 },
1308 .power_ctrl = cxusb_aver_power_ctrl,
1309
1310 .i2c_algo = &cxusb_i2c_algo,
1311
1312 .generic_bulk_ctrl_endpoint = 0x01,
1313
1314 .num_device_descs = 1,
1315 .devices = {
1316 { "AVerMedia AVerTVHD Volar (A868R)",
1317 { NULL },
1318 { &cxusb_table[16], NULL },
1319 },
1320 }
1321};
1322
1185static struct usb_driver cxusb_driver = { 1323static struct usb_driver cxusb_driver = {
1186 .name = "dvb_usb_cxusb", 1324 .name = "dvb_usb_cxusb",
1187 .probe = cxusb_probe, 1325 .probe = cxusb_probe,
diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h
index 4768a2c35517..1a51eafd31b9 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.h
+++ b/drivers/media/dvb/dvb-usb/cxusb.h
@@ -20,6 +20,9 @@
20#define CMD_STREAMING_ON 0x36 20#define CMD_STREAMING_ON 0x36
21#define CMD_STREAMING_OFF 0x37 21#define CMD_STREAMING_OFF 0x37
22 22
23#define CMD_AVER_STREAM_ON 0x18
24#define CMD_AVER_STREAM_OFF 0x19
25
23#define CMD_GET_IR_CODE 0x47 26#define CMD_GET_IR_CODE 0x47
24 27
25#define CMD_ANALOG 0x50 28#define CMD_ANALOG 0x50
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index c4d40fe01d57..3dd20bfbed32 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1117,6 +1117,7 @@ struct usb_device_id dib0700_usb_id_table[] = {
1117 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, 1117 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
1118 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, 1118 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) },
1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, 1119 { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) },
1120 { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) },
1120 { 0 } /* Terminating entry */ 1121 { 0 } /* Terminating entry */
1121}; 1122};
1122MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1123MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1372,7 +1373,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1372 } 1373 }
1373 }, 1374 },
1374 1375
1375 .num_device_descs = 2, 1376 .num_device_descs = 3,
1376 .devices = { 1377 .devices = {
1377 { "DiBcom STK7070PD reference design", 1378 { "DiBcom STK7070PD reference design",
1378 { &dib0700_usb_id_table[17], NULL }, 1379 { &dib0700_usb_id_table[17], NULL },
@@ -1381,6 +1382,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1381 { "Pinnacle PCTV Dual DVB-T Diversity Stick", 1382 { "Pinnacle PCTV Dual DVB-T Diversity Stick",
1382 { &dib0700_usb_id_table[18], NULL }, 1383 { &dib0700_usb_id_table[18], NULL },
1383 { NULL }, 1384 { NULL },
1385 },
1386 { "Hauppauge Nova-TD Stick (52009)",
1387 { &dib0700_usb_id_table[35], NULL },
1388 { NULL },
1384 } 1389 }
1385 } 1390 }
1386 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 1391 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 23428cd30756..326f7608954b 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -20,11 +20,7 @@ int dvb_usb_i2c_init(struct dvb_usb_device *d)
20 } 20 }
21 21
22 strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); 22 strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name));
23#ifdef I2C_ADAP_CLASS_TV_DIGITAL
24 d->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL,
25#else
26 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, 23 d->i2c_adap.class = I2C_CLASS_TV_DIGITAL,
27#endif
28 d->i2c_adap.algo = d->props.i2c_algo; 24 d->i2c_adap.algo = d->props.i2c_algo;
29 d->i2c_adap.algo_data = NULL; 25 d->i2c_adap.algo_data = NULL;
30 d->i2c_adap.dev.parent = &d->udev->dev; 26 d->i2c_adap.dev.parent = &d->udev->dev;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 34245d1b7dd9..e5238b31e946 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -14,6 +14,7 @@
14#define USB_VID_AFATECH 0x15a4 14#define USB_VID_AFATECH 0x15a4
15#define USB_VID_ALCOR_MICRO 0x058f 15#define USB_VID_ALCOR_MICRO 0x058f
16#define USB_VID_ALINK 0x05e3 16#define USB_VID_ALINK 0x05e3
17#define USB_VID_AMT 0x1c73
17#define USB_VID_ANCHOR 0x0547 18#define USB_VID_ANCHOR 0x0547
18#define USB_VID_ANSONIC 0x10b9 19#define USB_VID_ANSONIC 0x10b9
19#define USB_VID_ANUBIS_ELECTRONIC 0x10fd 20#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
@@ -57,6 +58,7 @@
57#define USB_PID_AFATECH_AF9005 0x9020 58#define USB_PID_AFATECH_AF9005 0x9020
58#define USB_VID_ALINK_DTU 0xf170 59#define USB_VID_ALINK_DTU 0xf170
59#define USB_PID_ANSONIC_DVBT_USB 0x6000 60#define USB_PID_ANSONIC_DVBT_USB 0x6000
61#define USB_PID_ANYSEE 0x861f
60#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 62#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001
61#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 63#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002
62#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 64#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800
@@ -132,9 +134,15 @@
132#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 134#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070
133#define USB_PID_HAUPPAUGE_MYTV_T 0x7080 135#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
134#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 136#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
137#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
135#define USB_PID_AVERMEDIA_EXPRESS 0xb568 138#define USB_PID_AVERMEDIA_EXPRESS 0xb568
136#define USB_PID_AVERMEDIA_VOLAR 0xa807 139#define USB_PID_AVERMEDIA_VOLAR 0xa807
137#define USB_PID_AVERMEDIA_VOLAR_2 0xb808 140#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
141#define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868
142#define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228
143#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039
144#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039
145#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039
138#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 146#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
139#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a 147#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
140#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 148#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058
diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c
index 037f7ffb47b2..6f596ed41761 100644
--- a/drivers/media/dvb/dvb-usb/gl861.c
+++ b/drivers/media/dvb/dvb-usb/gl861.c
@@ -1,8 +1,8 @@
1/* DVB USB compliant linux driver for GL861 USB2.0 devices. 1/* DVB USB compliant linux driver for GL861 USB2.0 devices.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify it 3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the Free 4 * under the terms of the GNU General Public License as published by the
5 * Software Foundation, version 2. 5 * Free Software Foundation, version 2.
6 * 6 *
7 * see Documentation/dvb/README.dvb-usb for more information 7 * see Documentation/dvb/README.dvb-usb for more information
8 */ 8 */
@@ -13,9 +13,9 @@
13 13
14/* debug */ 14/* debug */
15static int dvb_usb_gl861_debug; 15static int dvb_usb_gl861_debug;
16module_param_named(debug,dvb_usb_gl861_debug, int, 0644); 16module_param_named(debug, dvb_usb_gl861_debug, int, 0644);
17MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); 17MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))."
18 18 DVB_USB_DEBUG_STATUS);
19DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 19DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
20 20
21static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, 21static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
@@ -70,7 +70,7 @@ static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
70 /* write/read request */ 70 /* write/read request */
71 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { 71 if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
72 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, 72 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
73 msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) 73 msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
74 break; 74 break;
75 i++; 75 i++;
76 } else 76 } else
@@ -102,12 +102,13 @@ static struct zl10353_config gl861_zl10353_config = {
102 102
103static int gl861_frontend_attach(struct dvb_usb_adapter *adap) 103static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
104{ 104{
105 if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
106 &adap->dev->i2c_adap)) != NULL) {
107 return 0;
108 }
109 105
110 return -EIO; 106 adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
107 &adap->dev->i2c_adap);
108 if (adap->fe == NULL)
109 return -EIO;
110
111 return 0;
111} 112}
112 113
113static struct qt1010_config gl861_qt1010_config = { 114static struct qt1010_config gl861_qt1010_config = {
@@ -156,7 +157,7 @@ static struct usb_device_id gl861_table [] = {
156 { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) }, 157 { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) },
157 { } /* Terminating entry */ 158 { } /* Terminating entry */
158}; 159};
159MODULE_DEVICE_TABLE (usb, gl861_table); 160MODULE_DEVICE_TABLE(usb, gl861_table);
160 161
161static struct dvb_usb_device_properties gl861_properties = { 162static struct dvb_usb_device_properties gl861_properties = {
162 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 163 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
@@ -180,7 +181,7 @@ static struct dvb_usb_device_properties gl861_properties = {
180 } 181 }
181 } 182 }
182 }, 183 },
183 }}, 184 } },
184 .i2c_algo = &gl861_i2c_algo, 185 .i2c_algo = &gl861_i2c_algo,
185 186
186 .num_device_descs = 2, 187 .num_device_descs = 2,
@@ -210,12 +211,11 @@ static int __init gl861_module_init(void)
210{ 211{
211 int ret; 212 int ret;
212 213
213 if ((ret = usb_register(&gl861_driver))) { 214 ret = usb_register(&gl861_driver);
215 if (ret)
214 err("usb_register failed. Error number %d", ret); 216 err("usb_register failed. Error number %d", ret);
215 return ret;
216 }
217 217
218 return 0; 218 return ret;
219} 219}
220 220
221static void __exit gl861_module_exit(void) 221static void __exit gl861_module_exit(void)
@@ -224,8 +224,8 @@ static void __exit gl861_module_exit(void)
224 usb_deregister(&gl861_driver); 224 usb_deregister(&gl861_driver);
225} 225}
226 226
227module_init (gl861_module_init); 227module_init(gl861_module_init);
228module_exit (gl861_module_exit); 228module_exit(gl861_module_exit);
229 229
230MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>"); 230MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
231MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); 231MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h
index 72a51afd5ee3..c54855e2c233 100644
--- a/drivers/media/dvb/dvb-usb/gl861.h
+++ b/drivers/media/dvb/dvb-usb/gl861.h
@@ -4,7 +4,7 @@
4#define DVB_USB_LOG_PREFIX "gl861" 4#define DVB_USB_LOG_PREFIX "gl861"
5#include "dvb-usb.h" 5#include "dvb-usb.h"
6 6
7#define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args) 7#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args)
8 8
9#define GL861_WRITE 0x40 9#define GL861_WRITE 0x40
10#define GL861_READ 0xc0 10#define GL861_READ 0xc0
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 03900d241a76..f7b71657f0f6 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "au8522.h" 29#include "au8522.h"
31 30
32struct au8522_state { 31struct au8522_state {
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index a054894ff481..ea058153ebfa 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -343,6 +343,52 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
343 } 343 }
344}; 344};
345 345
346static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf,
347 const struct dvb_frontend_parameters *params)
348{
349 struct dvb_pll_priv *priv = fe->tuner_priv;
350 struct i2c_msg msg = {
351 .addr = priv->pll_i2c_address,
352 .flags = 0,
353 .buf = buf,
354 .len = 4
355 };
356 int result;
357
358 if (fe->ops.i2c_gate_ctrl)
359 fe->ops.i2c_gate_ctrl(fe, 1);
360
361 result = i2c_transfer(priv->i2c, &msg, 1);
362 if (result != 1)
363 printk(KERN_ERR "%s: i2c_transfer failed:%d",
364 __func__, result);
365
366 buf[2] = 0x9e;
367 buf[3] = 0x90;
368
369 return;
370}
371
372/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
373static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
374 .name = "Samsung DTOS403IH102A",
375 .min = 44250000,
376 .max = 858000000,
377 .iffreq = 36125000,
378 .count = 8,
379 .set = samsung_dtos403ih102a_set,
380 .entries = {
381 { 135000000, 62500, 0xbe, 0x01 },
382 { 177000000, 62500, 0xf6, 0x01 },
383 { 370000000, 62500, 0xbe, 0x02 },
384 { 450000000, 62500, 0xf6, 0x02 },
385 { 466000000, 62500, 0xfe, 0x02 },
386 { 538000000, 62500, 0xbe, 0x08 },
387 { 826000000, 62500, 0xf6, 0x08 },
388 { 999999999, 62500, 0xfe, 0x08 },
389 }
390};
391
346/* ----------------------------------------------------------- */ 392/* ----------------------------------------------------------- */
347 393
348static struct dvb_pll_desc *pll_list[] = { 394static struct dvb_pll_desc *pll_list[] = {
@@ -360,6 +406,7 @@ static struct dvb_pll_desc *pll_list[] = {
360 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, 406 [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
361 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, 407 [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
362 [DVB_PLL_OPERA1] = &dvb_pll_opera1, 408 [DVB_PLL_OPERA1] = &dvb_pll_opera1,
409 [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
363}; 410};
364 411
365/* ----------------------------------------------------------- */ 412/* ----------------------------------------------------------- */
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 872ca29e7cf3..05239f579ccf 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -22,6 +22,7 @@
22#define DVB_PLL_SAMSUNG_TBMV 11 22#define DVB_PLL_SAMSUNG_TBMV 11
23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12 23#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
24#define DVB_PLL_OPERA1 13 24#define DVB_PLL_OPERA1 13
25#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
25 26
26/** 27/**
27 * Attach a dvb-pll to the supplied frontend structure. 28 * Attach a dvb-pll to the supplied frontend structure.
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c
index f0195c8272f4..056387b41a8f 100644
--- a/drivers/media/dvb/frontends/lgdt330x.c
+++ b/drivers/media/dvb/frontends/lgdt330x.c
@@ -226,11 +226,16 @@ static int lgdt330x_init(struct dvb_frontend* fe)
226 0x4c, 0x14 226 0x4c, 0x14
227 }; 227 };
228 228
229 static u8 flip_lgdt3303_init_data[] = { 229 static u8 flip_1_lgdt3303_init_data[] = {
230 0x4c, 0x14, 230 0x4c, 0x14,
231 0x87, 0xf3 231 0x87, 0xf3
232 }; 232 };
233 233
234 static u8 flip_2_lgdt3303_init_data[] = {
235 0x4c, 0x14,
236 0x87, 0xda
237 };
238
234 struct lgdt330x_state* state = fe->demodulator_priv; 239 struct lgdt330x_state* state = fe->demodulator_priv;
235 char *chip_name; 240 char *chip_name;
236 int err; 241 int err;
@@ -243,10 +248,19 @@ static int lgdt330x_init(struct dvb_frontend* fe)
243 break; 248 break;
244 case LGDT3303: 249 case LGDT3303:
245 chip_name = "LGDT3303"; 250 chip_name = "LGDT3303";
246 if (state->config->clock_polarity_flip) { 251 switch (state->config->clock_polarity_flip) {
247 err = i2c_write_demod_bytes(state, flip_lgdt3303_init_data, 252 case 2:
248 sizeof(flip_lgdt3303_init_data)); 253 err = i2c_write_demod_bytes(state,
249 } else { 254 flip_2_lgdt3303_init_data,
255 sizeof(flip_2_lgdt3303_init_data));
256 break;
257 case 1:
258 err = i2c_write_demod_bytes(state,
259 flip_1_lgdt3303_init_data,
260 sizeof(flip_1_lgdt3303_init_data));
261 break;
262 case 0:
263 default:
250 err = i2c_write_demod_bytes(state, lgdt3303_init_data, 264 err = i2c_write_demod_bytes(state, lgdt3303_init_data,
251 sizeof(lgdt3303_init_data)); 265 sizeof(lgdt3303_init_data));
252 } 266 }
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index b999ec424ff7..5ddb2dca305c 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "s5h1409.h" 29#include "s5h1409.h"
31 30
32struct s5h1409_state { 31struct s5h1409_state {
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index eb5bfc99d4e9..cff360ce1ba3 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include "dvb_frontend.h" 28#include "dvb_frontend.h"
29#include "dvb-pll.h"
30#include "s5h1411.h" 29#include "s5h1411.h"
31 30
32struct s5h1411_state { 31struct s5h1411_state {
diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c
index c6ff5b82ff80..a3c34eecdee9 100644
--- a/drivers/media/dvb/frontends/tda10023.c
+++ b/drivers/media/dvb/frontends/tda10023.c
@@ -38,75 +38,29 @@
38#include "dvb_frontend.h" 38#include "dvb_frontend.h"
39#include "tda1002x.h" 39#include "tda1002x.h"
40 40
41#define REG0_INIT_VAL 0x23
41 42
42struct tda10023_state { 43struct tda10023_state {
43 struct i2c_adapter* i2c; 44 struct i2c_adapter* i2c;
44 /* configuration settings */ 45 /* configuration settings */
45 const struct tda1002x_config* config; 46 const struct tda10023_config *config;
46 struct dvb_frontend frontend; 47 struct dvb_frontend frontend;
47 48
48 u8 pwm; 49 u8 pwm;
49 u8 reg0; 50 u8 reg0;
50};
51 51
52 /* clock settings */
53 u32 xtal;
54 u8 pll_m;
55 u8 pll_p;
56 u8 pll_n;
57 u32 sysclk;
58};
52 59
53#define dprintk(x...) 60#define dprintk(x...)
54 61
55static int verbose; 62static int verbose;
56 63
57#define XTAL 28920000UL
58#define PLL_M 8UL
59#define PLL_P 4UL
60#define PLL_N 1UL
61#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
62
63static u8 tda10023_inittab[]={
64 // reg mask val
65 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
66 0xff,0x64,0x00, // Sleep 100ms
67 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
68 0xff,0x64,0x00, // Sleep 100ms
69 0x28,0xff,PLL_M-1, // PLL1 M=8
70 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
71 0x00,0xff,0x23, // GPR FSAMPLING=1
72 0x2a,0xff,0x08, // PLL3 PSACLK=1
73 0xff,0x64,0x00, // Sleep 100ms
74 0x1f,0xff,0x00, // RESET
75 0xff,0x64,0x00, // Sleep 100ms
76 0xe6,0x0c,0x04, // RSCFG_IND
77 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
78
79 0x0e,0xff,0x82, // GAIN1
80 0x03,0x08,0x08, // CLKCONF DYN=1
81 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
82 0x01,0xff,0x30, // AGCREF
83 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
84 0x1b,0xff,0xc8, // ADC TWOS=1
85 0x3b,0xff,0xff, // IFMAX
86 0x3c,0xff,0x00, // IFMIN
87 0x34,0xff,0x00, // PWMREF
88 0x35,0xff,0xff, // TUNMAX
89 0x36,0xff,0x00, // TUNMIN
90 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
91 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
92 0x37,0xff,0xf6, // DELTAF_LSB
93 0x38,0xff,0xff, // DELTAF_MSB
94 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
95 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
96 0x04,0x10,0x00, // SWRAMP=1
97 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
98 0x2b,0x01,0xa1, // INTS1
99 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
100 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
101 0xc4,0xff,0x00,
102 0xc3,0x30,0x00,
103 0xb5,0xff,0x19, // ERAGC_THD
104 0x00,0x03,0x01, // GPR, CLBS soft reset
105 0x00,0x03,0x03, // GPR, CLBS soft reset
106 0xff,0x64,0x00, // Sleep 100ms
107 0xff,0xff,0xff
108};
109
110static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) 64static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
111{ 65{
112 u8 b0 [] = { reg }; 66 u8 b0 [] = { reg };
@@ -219,30 +173,34 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
219 s16 SFIL=0; 173 s16 SFIL=0;
220 u16 NDEC = 0; 174 u16 NDEC = 0;
221 175
222 if (sr < (u32)(SYSCLK/98.40)) { 176 /* avoid floating point operations multiplying syscloc and divider
177 by 10 */
178 u32 sysclk_x_10 = state->sysclk * 10;
179
180 if (sr < (u32)(sysclk_x_10/984)) {
223 NDEC=3; 181 NDEC=3;
224 SFIL=1; 182 SFIL=1;
225 } else if (sr<(u32)(SYSCLK/64.0)) { 183 } else if (sr < (u32)(sysclk_x_10/640)) {
226 NDEC=3; 184 NDEC=3;
227 SFIL=0; 185 SFIL=0;
228 } else if (sr<(u32)(SYSCLK/49.2)) { 186 } else if (sr < (u32)(sysclk_x_10/492)) {
229 NDEC=2; 187 NDEC=2;
230 SFIL=1; 188 SFIL=1;
231 } else if (sr<(u32)(SYSCLK/32.0)) { 189 } else if (sr < (u32)(sysclk_x_10/320)) {
232 NDEC=2; 190 NDEC=2;
233 SFIL=0; 191 SFIL=0;
234 } else if (sr<(u32)(SYSCLK/24.6)) { 192 } else if (sr < (u32)(sysclk_x_10/246)) {
235 NDEC=1; 193 NDEC=1;
236 SFIL=1; 194 SFIL=1;
237 } else if (sr<(u32)(SYSCLK/16.0)) { 195 } else if (sr < (u32)(sysclk_x_10/160)) {
238 NDEC=1; 196 NDEC=1;
239 SFIL=0; 197 SFIL=0;
240 } else if (sr<(u32)(SYSCLK/12.3)) { 198 } else if (sr < (u32)(sysclk_x_10/123)) {
241 NDEC=0; 199 NDEC=0;
242 SFIL=1; 200 SFIL=1;
243 } 201 }
244 202
245 BDRI=SYSCLK*16; 203 BDRI = (state->sysclk)*16;
246 BDRI>>=NDEC; 204 BDRI>>=NDEC;
247 BDRI +=sr/2; 205 BDRI +=sr/2;
248 BDRI /=sr; 206 BDRI /=sr;
@@ -255,11 +213,12 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
255 213
256 BDRX=1<<(24+NDEC); 214 BDRX=1<<(24+NDEC);
257 BDRX*=sr; 215 BDRX*=sr;
258 do_div(BDRX,SYSCLK); // BDRX/=SYSCLK; 216 do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
259 217
260 BDR=(s32)BDRX; 218 BDR=(s32)BDRX;
261 } 219 }
262// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC); 220 dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
221 sr, BDR, BDRI, NDEC);
263 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); 222 tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
264 tda10023_writereg (state, 0x0a, BDR&255); 223 tda10023_writereg (state, 0x0a, BDR&255);
265 tda10023_writereg (state, 0x0b, (BDR>>8)&255); 224 tda10023_writereg (state, 0x0b, (BDR>>8)&255);
@@ -272,8 +231,67 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
272static int tda10023_init (struct dvb_frontend *fe) 231static int tda10023_init (struct dvb_frontend *fe)
273{ 232{
274 struct tda10023_state* state = fe->demodulator_priv; 233 struct tda10023_state* state = fe->demodulator_priv;
234 u8 tda10023_inittab[] = {
235/* reg mask val */
236/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */
237/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
238/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */
239/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
240 /* PLL1 */
241/* 012 */ 0x28, 0xff, (state->pll_m-1),
242 /* PLL2 */
243/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
244 /* GPR FSAMPLING=1 */
245/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
246/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */
247/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
248/* 027 */ 0x1f, 0xff, 0x00, /* RESET */
249/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
250/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */
251/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */
252
253/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */
254/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */
255/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
256 PPWMTUN=0 PPWMIF=0 */
257/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */
258/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */
259/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */
260/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */
261/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */
262/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */
263/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */
264/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */
265/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
266/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */
267/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */
268/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */
269/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */
270/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
271/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */
272/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /*
273 INTP1 POCLKP=1 FEL=1 MFS=0 */
274/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */
275/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
276/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */
277/* 105 */ 0xc4, 0xff, 0x00,
278/* 108 */ 0xc3, 0x30, 0x00,
279/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */
280/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */
281/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */
282/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
283/* 123 */ 0xff, 0xff, 0xff
284};
285 dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
286
287 /* override default values if set in config */
288 if (state->config->deltaf) {
289 tda10023_inittab[80] = (state->config->deltaf & 0xff);
290 tda10023_inittab[83] = (state->config->deltaf >> 8);
291 }
275 292
276 dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num); 293 if (state->config->output_mode)
294 tda10023_inittab[95] = state->config->output_mode;
277 295
278 tda10023_writetab(state, tda10023_inittab); 296 tda10023_writetab(state, tda10023_inittab);
279 297
@@ -460,12 +478,11 @@ static void tda10023_release(struct dvb_frontend* fe)
460 478
461static struct dvb_frontend_ops tda10023_ops; 479static struct dvb_frontend_ops tda10023_ops;
462 480
463struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 481struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
464 struct i2c_adapter* i2c, 482 struct i2c_adapter *i2c,
465 u8 pwm) 483 u8 pwm)
466{ 484{
467 struct tda10023_state* state = NULL; 485 struct tda10023_state* state = NULL;
468 int i;
469 486
470 /* allocate memory for the internal state */ 487 /* allocate memory for the internal state */
471 state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); 488 state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL);
@@ -474,22 +491,40 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
474 /* setup the state */ 491 /* setup the state */
475 state->config = config; 492 state->config = config;
476 state->i2c = i2c; 493 state->i2c = i2c;
477 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
478 state->pwm = pwm;
479 for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) {
480 if (tda10023_inittab[i] == 0x00) {
481 state->reg0 = tda10023_inittab[i+2];
482 break;
483 }
484 }
485 494
486 // Wakeup if in standby 495 /* wakeup if in standby */
487 tda10023_writereg (state, 0x00, 0x33); 496 tda10023_writereg (state, 0x00, 0x33);
488 /* check if the demod is there */ 497 /* check if the demod is there */
489 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; 498 if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
490 499
491 /* create dvb_frontend */ 500 /* create dvb_frontend */
492 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); 501 memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
502 state->pwm = pwm;
503 state->reg0 = REG0_INIT_VAL;
504 if (state->config->xtal) {
505 state->xtal = state->config->xtal;
506 state->pll_m = state->config->pll_m;
507 state->pll_p = state->config->pll_p;
508 state->pll_n = state->config->pll_n;
509 } else {
510 /* set default values if not defined in config */
511 state->xtal = 28920000;
512 state->pll_m = 8;
513 state->pll_p = 4;
514 state->pll_n = 1;
515 }
516
517 /* calc sysclk */
518 state->sysclk = (state->xtal * state->pll_m / \
519 (state->pll_n * state->pll_p));
520
521 state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
522 state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
523
524 dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
525 __func__, state->xtal, state->pll_m, state->pll_p,
526 state->pll_n);
527
493 state->frontend.demodulator_priv = state; 528 state->frontend.demodulator_priv = state;
494 return &state->frontend; 529 return &state->frontend;
495 530
@@ -504,10 +539,10 @@ static struct dvb_frontend_ops tda10023_ops = {
504 .name = "Philips TDA10023 DVB-C", 539 .name = "Philips TDA10023 DVB-C",
505 .type = FE_QAM, 540 .type = FE_QAM,
506 .frequency_stepsize = 62500, 541 .frequency_stepsize = 62500,
507 .frequency_min = 47000000, 542 .frequency_min = 47000000,
508 .frequency_max = 862000000, 543 .frequency_max = 862000000,
509 .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */ 544 .symbol_rate_min = 0, /* set in tda10023_attach */
510 .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */ 545 .symbol_rate_max = 0, /* set in tda10023_attach */
511 .caps = 0x400 | //FE_CAN_QAM_4 546 .caps = 0x400 | //FE_CAN_QAM_4
512 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | 547 FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
513 FE_CAN_QAM_128 | FE_CAN_QAM_256 | 548 FE_CAN_QAM_128 | FE_CAN_QAM_256 |
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
index 1bcc0d44b90b..04d19418bf20 100644
--- a/drivers/media/dvb/frontends/tda1002x.h
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -26,13 +26,37 @@
26 26
27#include <linux/dvb/frontend.h> 27#include <linux/dvb/frontend.h>
28 28
29struct tda1002x_config 29struct tda1002x_config {
30{
31 /* the demodulator's i2c address */ 30 /* the demodulator's i2c address */
32 u8 demod_address; 31 u8 demod_address;
33 u8 invert; 32 u8 invert;
34}; 33};
35 34
35enum tda10023_output_mode {
36 TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0,
37 TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1,
38 TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0,
39 TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */
40};
41
42struct tda10023_config {
43 /* the demodulator's i2c address */
44 u8 demod_address;
45 u8 invert;
46
47 /* clock settings */
48 u32 xtal; /* defaults: 28920000 */
49 u8 pll_m; /* defaults: 8 */
50 u8 pll_p; /* defaults: 4 */
51 u8 pll_n; /* defaults: 1 */
52
53 /* MPEG2 TS output mode */
54 u8 output_mode;
55
56 /* input freq offset + baseband conversion type */
57 u16 deltaf;
58};
59
36#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) 60#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
37extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, 61extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
38 struct i2c_adapter* i2c, u8 pwm); 62 struct i2c_adapter* i2c, u8 pwm);
@@ -45,12 +69,15 @@ static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config*
45} 69}
46#endif // CONFIG_DVB_TDA10021 70#endif // CONFIG_DVB_TDA10021
47 71
48#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) 72#if defined(CONFIG_DVB_TDA10023) || \
49extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 73 (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
50 struct i2c_adapter* i2c, u8 pwm); 74extern struct dvb_frontend *tda10023_attach(
75 const struct tda10023_config *config,
76 struct i2c_adapter *i2c, u8 pwm);
51#else 77#else
52static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config, 78static inline struct dvb_frontend *tda10023_attach(
53 struct i2c_adapter* i2c, u8 pwm) 79 const struct tda10023_config *config,
80 struct i2c_adapter *i2c, u8 pwm)
54{ 81{
55 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
56 return NULL; 83 return NULL;
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 960ed5763ae1..1360403b88b6 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -234,7 +234,7 @@ static void pluto_reset_ts(struct pluto *pluto, int reenable)
234 234
235static void pluto_set_dma_addr(struct pluto *pluto) 235static void pluto_set_dma_addr(struct pluto *pluto)
236{ 236{
237 pluto_writereg(pluto, REG_PCAR, cpu_to_le32(pluto->dma_addr)); 237 pluto_writereg(pluto, REG_PCAR, pluto->dma_addr);
238} 238}
239 239
240static int __devinit pluto_dma_map(struct pluto *pluto) 240static int __devinit pluto_dma_map(struct pluto *pluto)
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
new file mode 100644
index 000000000000..dd863f261672
--- /dev/null
+++ b/drivers/media/dvb/siano/Kconfig
@@ -0,0 +1,26 @@
1#
2# Siano Mobile Silicon Digital TV device configuration
3#
4
5config DVB_SIANO_SMS1XXX
6 tristate "Siano SMS1XXX USB dongle support"
7 depends on DVB_CORE && USB
8 ---help---
9 Choose Y here if you have a USB dongle with a SMS1XXX chipset.
10
11 To compile this driver as a module, choose M here: the
12 module will be called sms1xxx.
13
14config DVB_SIANO_SMS1XXX_SMS_IDS
15 bool "Enable support for Siano Mobile Silicon default USB IDs"
16 depends on DVB_SIANO_SMS1XXX
17 default y
18 ---help---
19 Choose Y here if you have a USB dongle with a SMS1XXX chipset
20 that uses Siano Mobile Silicon's default usb vid:pid.
21
22 Choose N here if you would prefer to use Siano's external driver.
23
24 Further documentation on this driver can be found on the WWW at
25 <http://www.siano-ms.com/>.
26
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
new file mode 100644
index 000000000000..ee0737af98c0
--- /dev/null
+++ b/drivers/media/dvb/siano/Makefile
@@ -0,0 +1,8 @@
1sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
2
3obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
6
7EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
8
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
new file mode 100644
index 000000000000..e7a8ac0c4049
--- /dev/null
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -0,0 +1,102 @@
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 3 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
22struct usb_device_id smsusb_id_table[] = {
23#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
24 { USB_DEVICE(0x187f, 0x0010),
25 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
26 { USB_DEVICE(0x187f, 0x0100),
27 .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
28 { USB_DEVICE(0x187f, 0x0200),
29 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
30 { USB_DEVICE(0x187f, 0x0201),
31 .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
32 { USB_DEVICE(0x187f, 0x0300),
33 .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
34#endif
35 { USB_DEVICE(0x2040, 0x1700),
36 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
37 { USB_DEVICE(0x2040, 0x1800),
38 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
39 { USB_DEVICE(0x2040, 0x1801),
40 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
41 { USB_DEVICE(0x2040, 0x5500),
42 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
43 { USB_DEVICE(0x2040, 0x5580),
44 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
45 { USB_DEVICE(0x2040, 0x5590),
46 .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
47 { } /* Terminating entry */
48};
49MODULE_DEVICE_TABLE(usb, smsusb_id_table);
50
51static struct sms_board sms_boards[] = {
52 [SMS_BOARD_UNKNOWN] = {
53 .name = "Unknown board",
54 },
55 [SMS1XXX_BOARD_SIANO_STELLAR] = {
56 .name = "Siano Stellar Digital Receiver",
57 .type = SMS_STELLAR,
58 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
59 },
60 [SMS1XXX_BOARD_SIANO_NOVA_A] = {
61 .name = "Siano Nova A Digital Receiver",
62 .type = SMS_NOVA_A0,
63 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
64 },
65 [SMS1XXX_BOARD_SIANO_NOVA_B] = {
66 .name = "Siano Nova B Digital Receiver",
67 .type = SMS_NOVA_B0,
68 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
69 },
70 [SMS1XXX_BOARD_SIANO_VEGA] = {
71 .name = "Siano Vega Digital Receiver",
72 .type = SMS_VEGA,
73 },
74 [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
75 .name = "Hauppauge Catamount",
76 .type = SMS_STELLAR,
77 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
78 },
79 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
80 .name = "Hauppauge Okemo-A",
81 .type = SMS_NOVA_A0,
82 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
83 },
84 [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
85 .name = "Hauppauge Okemo-B",
86 .type = SMS_NOVA_B0,
87 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
88 },
89 [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
90 .name = "Hauppauge WinTV-Nova-T-MiniStick",
91 .type = SMS_NOVA_B0,
92 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-01.fw",
93 },
94};
95
96struct sms_board *sms_get_board(int id)
97{
98 BUG_ON(id >= ARRAY_SIZE(sms_boards));
99
100 return &sms_boards[id];
101}
102
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
new file mode 100644
index 000000000000..83b39bc203fe
--- /dev/null
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -0,0 +1,45 @@
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 3 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
26#define SMS_BOARD_UNKNOWN 0
27#define SMS1XXX_BOARD_SIANO_STELLAR 1
28#define SMS1XXX_BOARD_SIANO_NOVA_A 2
29#define SMS1XXX_BOARD_SIANO_NOVA_B 3
30#define SMS1XXX_BOARD_SIANO_VEGA 4
31#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5
32#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6
33#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7
34#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8
35
36struct sms_board {
37 enum sms_device_type_st type;
38 char *name, *fw[DEVICE_MODE_MAX];
39};
40
41struct sms_board *sms_get_board(int id);
42
43extern struct usb_device_id smsusb_id_table[];
44
45#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
new file mode 100644
index 000000000000..b4b8ed795c95
--- /dev/null
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -0,0 +1,1251 @@
1/*
2 * Siano core API module
3 *
4 * This file contains implementation for the interface to sms core component
5 *
6 * author: Anatoly Greenblat
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 3 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
32#include <linux/firmware.h>
33
34#include "smscoreapi.h"
35#include "sms-cards.h"
36
37int sms_debug;
38module_param_named(debug, sms_debug, int, 0644);
39MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
40
41struct smscore_device_notifyee_t {
42 struct list_head entry;
43 hotplug_t hotplug;
44};
45
46struct smscore_idlist_t {
47 struct list_head entry;
48 int id;
49 int data_type;
50};
51
52struct smscore_client_t {
53 struct list_head entry;
54 struct smscore_device_t *coredev;
55 void *context;
56 struct list_head idlist;
57 onresponse_t onresponse_handler;
58 onremove_t onremove_handler;
59};
60
61struct smscore_device_t {
62 struct list_head entry;
63
64 struct list_head clients;
65 struct list_head subclients;
66 spinlock_t clientslock;
67
68 struct list_head buffers;
69 spinlock_t bufferslock;
70 int num_buffers;
71
72 void *common_buffer;
73 int common_buffer_size;
74 dma_addr_t common_buffer_phys;
75
76 void *context;
77 struct device *device;
78
79 char devpath[32];
80 unsigned long device_flags;
81
82 setmode_t setmode_handler;
83 detectmode_t detectmode_handler;
84 sendrequest_t sendrequest_handler;
85 preload_t preload_handler;
86 postload_t postload_handler;
87
88 int mode, modes_supported;
89
90 struct completion version_ex_done, data_download_done, trigger_done;
91 struct completion init_device_done, reload_start_done, resume_done;
92
93 int board_id;
94};
95
96void smscore_set_board_id(struct smscore_device_t *core, int id)
97{
98 core->board_id = id;
99}
100
101int smscore_get_board_id(struct smscore_device_t *core)
102{
103 return core->board_id;
104}
105
106struct smscore_registry_entry_t {
107 struct list_head entry;
108 char devpath[32];
109 int mode;
110 enum sms_device_type_st type;
111};
112
113struct list_head g_smscore_notifyees;
114struct list_head g_smscore_devices;
115struct mutex g_smscore_deviceslock;
116
117struct list_head g_smscore_registry;
118struct mutex g_smscore_registrylock;
119
120static int default_mode = 4;
121
122module_param(default_mode, int, 0644);
123MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
124
125static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
126{
127 struct smscore_registry_entry_t *entry;
128 struct list_head *next;
129
130 kmutex_lock(&g_smscore_registrylock);
131 for (next = g_smscore_registry.next;
132 next != &g_smscore_registry;
133 next = next->next) {
134 entry = (struct smscore_registry_entry_t *) next;
135 if (!strcmp(entry->devpath, devpath)) {
136 kmutex_unlock(&g_smscore_registrylock);
137 return entry;
138 }
139 }
140 entry = (struct smscore_registry_entry_t *)
141 kmalloc(sizeof(struct smscore_registry_entry_t),
142 GFP_KERNEL);
143 if (entry) {
144 entry->mode = default_mode;
145 strcpy(entry->devpath, devpath);
146 list_add(&entry->entry, &g_smscore_registry);
147 } else
148 sms_err("failed to create smscore_registry.");
149 kmutex_unlock(&g_smscore_registrylock);
150 return entry;
151}
152
153int smscore_registry_getmode(char *devpath)
154{
155 struct smscore_registry_entry_t *entry;
156
157 entry = smscore_find_registry(devpath);
158 if (entry)
159 return entry->mode;
160 else
161 sms_err("No registry found.");
162
163 return default_mode;
164}
165
166static enum sms_device_type_st smscore_registry_gettype(char *devpath)
167{
168 struct smscore_registry_entry_t *entry;
169
170 entry = smscore_find_registry(devpath);
171 if (entry)
172 return entry->type;
173 else
174 sms_err("No registry found.");
175
176 return -1;
177}
178
179void smscore_registry_setmode(char *devpath, int mode)
180{
181 struct smscore_registry_entry_t *entry;
182
183 entry = smscore_find_registry(devpath);
184 if (entry)
185 entry->mode = mode;
186 else
187 sms_err("No registry found.");
188}
189
190static void smscore_registry_settype(char *devpath,
191 enum sms_device_type_st type)
192{
193 struct smscore_registry_entry_t *entry;
194
195 entry = smscore_find_registry(devpath);
196 if (entry)
197 entry->type = type;
198 else
199 sms_err("No registry found.");
200}
201
202
203static void list_add_locked(struct list_head *new, struct list_head *head,
204 spinlock_t *lock)
205{
206 unsigned long flags;
207
208 spin_lock_irqsave(lock, flags);
209
210 list_add(new, head);
211
212 spin_unlock_irqrestore(lock, flags);
213}
214
215/**
216 * register a client callback that called when device plugged in/unplugged
217 * NOTE: if devices exist callback is called immediately for each device
218 *
219 * @param hotplug callback
220 *
221 * @return 0 on success, <0 on error.
222 */
223int smscore_register_hotplug(hotplug_t hotplug)
224{
225 struct smscore_device_notifyee_t *notifyee;
226 struct list_head *next, *first;
227 int rc = 0;
228
229 kmutex_lock(&g_smscore_deviceslock);
230
231 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
232 GFP_KERNEL);
233 if (notifyee) {
234 /* now notify callback about existing devices */
235 first = &g_smscore_devices;
236 for (next = first->next;
237 next != first && !rc;
238 next = next->next) {
239 struct smscore_device_t *coredev =
240 (struct smscore_device_t *) next;
241 rc = hotplug(coredev, coredev->device, 1);
242 }
243
244 if (rc >= 0) {
245 notifyee->hotplug = hotplug;
246 list_add(&notifyee->entry, &g_smscore_notifyees);
247 } else
248 kfree(notifyee);
249 } else
250 rc = -ENOMEM;
251
252 kmutex_unlock(&g_smscore_deviceslock);
253
254 return rc;
255}
256
257/**
258 * unregister a client callback that called when device plugged in/unplugged
259 *
260 * @param hotplug callback
261 *
262 */
263void smscore_unregister_hotplug(hotplug_t hotplug)
264{
265 struct list_head *next, *first;
266
267 kmutex_lock(&g_smscore_deviceslock);
268
269 first = &g_smscore_notifyees;
270
271 for (next = first->next; next != first;) {
272 struct smscore_device_notifyee_t *notifyee =
273 (struct smscore_device_notifyee_t *) next;
274 next = next->next;
275
276 if (notifyee->hotplug == hotplug) {
277 list_del(&notifyee->entry);
278 kfree(notifyee);
279 }
280 }
281
282 kmutex_unlock(&g_smscore_deviceslock);
283}
284
285static void smscore_notify_clients(struct smscore_device_t *coredev)
286{
287 struct smscore_client_t *client;
288
289 /* the client must call smscore_unregister_client from remove handler */
290 while (!list_empty(&coredev->clients)) {
291 client = (struct smscore_client_t *) coredev->clients.next;
292 client->onremove_handler(client->context);
293 }
294}
295
296static int smscore_notify_callbacks(struct smscore_device_t *coredev,
297 struct device *device, int arrival)
298{
299 struct list_head *next, *first;
300 int rc = 0;
301
302 /* note: must be called under g_deviceslock */
303
304 first = &g_smscore_notifyees;
305
306 for (next = first->next; next != first; next = next->next) {
307 rc = ((struct smscore_device_notifyee_t *) next)->
308 hotplug(coredev, device, arrival);
309 if (rc < 0)
310 break;
311 }
312
313 return rc;
314}
315
316static struct
317smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
318 dma_addr_t common_buffer_phys)
319{
320 struct smscore_buffer_t *cb =
321 kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
322 if (!cb) {
323 sms_info("kmalloc(...) failed");
324 return NULL;
325 }
326
327 cb->p = buffer;
328 cb->offset_in_common = buffer - (u8 *) common_buffer;
329 cb->phys = common_buffer_phys + cb->offset_in_common;
330
331 return cb;
332}
333
334/**
335 * creates coredev object for a device, prepares buffers,
336 * creates buffer mappings, notifies registered hotplugs about new device.
337 *
338 * @param params device pointer to struct with device specific parameters
339 * and handlers
340 * @param coredev pointer to a value that receives created coredev object
341 *
342 * @return 0 on success, <0 on error.
343 */
344int smscore_register_device(struct smsdevice_params_t *params,
345 struct smscore_device_t **coredev)
346{
347 struct smscore_device_t *dev;
348 u8 *buffer;
349
350 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
351 if (!dev) {
352 sms_info("kzalloc(...) failed");
353 return -ENOMEM;
354 }
355
356 /* init list entry so it could be safe in smscore_unregister_device */
357 INIT_LIST_HEAD(&dev->entry);
358
359 /* init queues */
360 INIT_LIST_HEAD(&dev->clients);
361 INIT_LIST_HEAD(&dev->buffers);
362
363 /* init locks */
364 spin_lock_init(&dev->clientslock);
365 spin_lock_init(&dev->bufferslock);
366
367 /* init completion events */
368 init_completion(&dev->version_ex_done);
369 init_completion(&dev->data_download_done);
370 init_completion(&dev->trigger_done);
371 init_completion(&dev->init_device_done);
372 init_completion(&dev->reload_start_done);
373 init_completion(&dev->resume_done);
374
375 /* alloc common buffer */
376 dev->common_buffer_size = params->buffer_size * params->num_buffers;
377 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
378 &dev->common_buffer_phys,
379 GFP_KERNEL | GFP_DMA);
380 if (!dev->common_buffer) {
381 smscore_unregister_device(dev);
382 return -ENOMEM;
383 }
384
385 /* prepare dma buffers */
386 for (buffer = dev->common_buffer;
387 dev->num_buffers < params->num_buffers;
388 dev->num_buffers++, buffer += params->buffer_size) {
389 struct smscore_buffer_t *cb =
390 smscore_createbuffer(buffer, dev->common_buffer,
391 dev->common_buffer_phys);
392 if (!cb) {
393 smscore_unregister_device(dev);
394 return -ENOMEM;
395 }
396
397 smscore_putbuffer(dev, cb);
398 }
399
400 sms_info("allocated %d buffers", dev->num_buffers);
401
402 dev->mode = DEVICE_MODE_NONE;
403 dev->context = params->context;
404 dev->device = params->device;
405 dev->setmode_handler = params->setmode_handler;
406 dev->detectmode_handler = params->detectmode_handler;
407 dev->sendrequest_handler = params->sendrequest_handler;
408 dev->preload_handler = params->preload_handler;
409 dev->postload_handler = params->postload_handler;
410
411 dev->device_flags = params->flags;
412 strcpy(dev->devpath, params->devpath);
413
414 smscore_registry_settype(dev->devpath, params->device_type);
415
416 /* add device to devices list */
417 kmutex_lock(&g_smscore_deviceslock);
418 list_add(&dev->entry, &g_smscore_devices);
419 kmutex_unlock(&g_smscore_deviceslock);
420
421 *coredev = dev;
422
423 sms_info("device %p created", dev);
424
425 return 0;
426}
427
428/**
429 * sets initial device mode and notifies client hotplugs that device is ready
430 *
431 * @param coredev pointer to a coredev object returned by
432 * smscore_register_device
433 *
434 * @return 0 on success, <0 on error.
435 */
436int smscore_start_device(struct smscore_device_t *coredev)
437{
438 int rc = smscore_set_device_mode(
439 coredev, smscore_registry_getmode(coredev->devpath));
440 if (rc < 0) {
441 sms_info("set device mode faile , rc %d", rc);
442 return rc;
443 }
444
445 kmutex_lock(&g_smscore_deviceslock);
446
447 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
448
449 sms_info("device %p started, rc %d", coredev, rc);
450
451 kmutex_unlock(&g_smscore_deviceslock);
452
453 return rc;
454}
455
456static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
457 void *buffer, size_t size,
458 struct completion *completion)
459{
460 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
461 if (rc < 0) {
462 sms_info("sendrequest returned error %d", rc);
463 return rc;
464 }
465
466 return wait_for_completion_timeout(completion,
467 msecs_to_jiffies(10000)) ?
468 0 : -ETIME;
469}
470
471static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
472 void *buffer, size_t size)
473{
474 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
475 struct SmsMsgHdr_ST *msg;
476 u32 mem_address = firmware->StartAddress;
477 u8 *payload = firmware->Payload;
478 int rc = 0;
479
480 sms_info("loading FW to addr 0x%x size %d",
481 mem_address, firmware->Length);
482 if (coredev->preload_handler) {
483 rc = coredev->preload_handler(coredev->context);
484 if (rc < 0)
485 return rc;
486 }
487
488 /* PAGE_SIZE buffer shall be enough and dma aligned */
489 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
490 if (!msg)
491 return -ENOMEM;
492
493 if (coredev->mode != DEVICE_MODE_NONE) {
494 sms_debug("sending reload command.");
495 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
496 sizeof(struct SmsMsgHdr_ST));
497 rc = smscore_sendrequest_and_wait(coredev, msg,
498 msg->msgLength,
499 &coredev->reload_start_done);
500 mem_address = *(u32 *) &payload[20];
501 }
502
503 while (size && rc >= 0) {
504 struct SmsDataDownload_ST *DataMsg =
505 (struct SmsDataDownload_ST *) msg;
506 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
507
508 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
509 (u16)(sizeof(struct SmsMsgHdr_ST) +
510 sizeof(u32) + payload_size));
511
512 DataMsg->MemAddr = mem_address;
513 memcpy(DataMsg->Payload, payload, payload_size);
514
515 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
516 (coredev->mode == DEVICE_MODE_NONE))
517 rc = coredev->sendrequest_handler(
518 coredev->context, DataMsg,
519 DataMsg->xMsgHeader.msgLength);
520 else
521 rc = smscore_sendrequest_and_wait(
522 coredev, DataMsg,
523 DataMsg->xMsgHeader.msgLength,
524 &coredev->data_download_done);
525
526 payload += payload_size;
527 size -= payload_size;
528 mem_address += payload_size;
529 }
530
531 if (rc >= 0) {
532 if (coredev->mode == DEVICE_MODE_NONE) {
533 struct SmsMsgData_ST *TriggerMsg =
534 (struct SmsMsgData_ST *) msg;
535
536 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
537 sizeof(struct SmsMsgHdr_ST) +
538 sizeof(u32) * 5);
539
540 TriggerMsg->msgData[0] = firmware->StartAddress;
541 /* Entry point */
542 TriggerMsg->msgData[1] = 5; /* Priority */
543 TriggerMsg->msgData[2] = 0x200; /* Stack size */
544 TriggerMsg->msgData[3] = 0; /* Parameter */
545 TriggerMsg->msgData[4] = 4; /* Task ID */
546
547 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
548 rc = coredev->sendrequest_handler(
549 coredev->context, TriggerMsg,
550 TriggerMsg->xMsgHeader.msgLength);
551 msleep(100);
552 } else
553 rc = smscore_sendrequest_and_wait(
554 coredev, TriggerMsg,
555 TriggerMsg->xMsgHeader.msgLength,
556 &coredev->trigger_done);
557 } else {
558 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
559 sizeof(struct SmsMsgHdr_ST));
560
561 rc = coredev->sendrequest_handler(coredev->context,
562 msg, msg->msgLength);
563 }
564 msleep(500);
565 }
566
567 sms_debug("rc=%d, postload=%p ", rc,
568 coredev->postload_handler);
569
570 kfree(msg);
571
572 return ((rc >= 0) && coredev->postload_handler) ?
573 coredev->postload_handler(coredev->context) :
574 rc;
575}
576
577/**
578 * loads specified firmware into a buffer and calls device loadfirmware_handler
579 *
580 * @param coredev pointer to a coredev object returned by
581 * smscore_register_device
582 * @param filename null-terminated string specifies firmware file name
583 * @param loadfirmware_handler device handler that loads firmware
584 *
585 * @return 0 on success, <0 on error.
586 */
587static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
588 char *filename,
589 loadfirmware_t loadfirmware_handler)
590{
591 int rc = -ENOENT;
592 const struct firmware *fw;
593 u8 *fw_buffer;
594
595 if (loadfirmware_handler == NULL && !(coredev->device_flags &
596 SMS_DEVICE_FAMILY2))
597 return -EINVAL;
598
599 rc = request_firmware(&fw, filename, coredev->device);
600 if (rc < 0) {
601 sms_info("failed to open \"%s\"", filename);
602 return rc;
603 }
604 sms_info("read FW %s, size=%zd", filename, fw->size);
605 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
606 GFP_KERNEL | GFP_DMA);
607 if (fw_buffer) {
608 memcpy(fw_buffer, fw->data, fw->size);
609
610 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
611 smscore_load_firmware_family2(coredev,
612 fw_buffer,
613 fw->size) :
614 loadfirmware_handler(coredev->context,
615 fw_buffer, fw->size);
616
617 kfree(fw_buffer);
618 } else {
619 sms_info("failed to allocate firmware buffer");
620 rc = -ENOMEM;
621 }
622
623 release_firmware(fw);
624
625 return rc;
626}
627
628/**
629 * notifies all clients registered with the device, notifies hotplugs,
630 * frees all buffers and coredev object
631 *
632 * @param coredev pointer to a coredev object returned by
633 * smscore_register_device
634 *
635 * @return 0 on success, <0 on error.
636 */
637void smscore_unregister_device(struct smscore_device_t *coredev)
638{
639 struct smscore_buffer_t *cb;
640 int num_buffers = 0;
641 int retry = 0;
642
643 kmutex_lock(&g_smscore_deviceslock);
644
645 smscore_notify_clients(coredev);
646 smscore_notify_callbacks(coredev, NULL, 0);
647
648 /* at this point all buffers should be back
649 * onresponse must no longer be called */
650
651 while (1) {
652 while ((cb = smscore_getbuffer(coredev))) {
653 kfree(cb);
654 num_buffers++;
655 }
656 if (num_buffers == coredev->num_buffers)
657 break;
658 if (++retry > 10) {
659 sms_info("exiting although "
660 "not all buffers released.");
661 break;
662 }
663
664 sms_info("waiting for %d buffer(s)",
665 coredev->num_buffers - num_buffers);
666 msleep(100);
667 }
668
669 sms_info("freed %d buffers", num_buffers);
670
671 if (coredev->common_buffer)
672 dma_free_coherent(NULL, coredev->common_buffer_size,
673 coredev->common_buffer,
674 coredev->common_buffer_phys);
675
676 list_del(&coredev->entry);
677 kfree(coredev);
678
679 kmutex_unlock(&g_smscore_deviceslock);
680
681 sms_info("device %p destroyed", coredev);
682}
683
684static int smscore_detect_mode(struct smscore_device_t *coredev)
685{
686 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
687 GFP_KERNEL | GFP_DMA);
688 struct SmsMsgHdr_ST *msg =
689 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
690 int rc;
691
692 if (!buffer)
693 return -ENOMEM;
694
695 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
696 sizeof(struct SmsMsgHdr_ST));
697
698 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
699 &coredev->version_ex_done);
700 if (rc == -ETIME) {
701 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
702
703 if (wait_for_completion_timeout(&coredev->resume_done,
704 msecs_to_jiffies(5000))) {
705 rc = smscore_sendrequest_and_wait(
706 coredev, msg, msg->msgLength,
707 &coredev->version_ex_done);
708 if (rc < 0)
709 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
710 "second try, rc %d", rc);
711 } else
712 rc = -ETIME;
713 }
714
715 kfree(buffer);
716
717 return rc;
718}
719
720static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
721 /*Stellar NOVA A0 Nova B0 VEGA*/
722 /*DVBT*/
723 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
724 /*DVBH*/
725 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
726 /*TDMB*/
727 {"none", "tdmb_nova_12mhz.inp", "none", "none"},
728 /*DABIP*/
729 {"none", "none", "none", "none"},
730 /*BDA*/
731 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
732 /*ISDBT*/
733 {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"},
734 /*ISDBTBDA*/
735 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
736 /*CMMB*/
737 {"none", "none", "none", "cmmb_vega_12mhz.inp"}
738};
739
740static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
741 int mode, enum sms_device_type_st type)
742{
743 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
744 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
745}
746
747/**
748 * calls device handler to change mode of operation
749 * NOTE: stellar/usb may disconnect when changing mode
750 *
751 * @param coredev pointer to a coredev object returned by
752 * smscore_register_device
753 * @param mode requested mode of operation
754 *
755 * @return 0 on success, <0 on error.
756 */
757int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
758{
759 void *buffer;
760 int rc = 0;
761 enum sms_device_type_st type;
762
763 sms_debug("set device mode to %d", mode);
764 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
765 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
766 sms_err("invalid mode specified %d", mode);
767 return -EINVAL;
768 }
769
770 smscore_registry_setmode(coredev->devpath, mode);
771
772 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
773 rc = smscore_detect_mode(coredev);
774 if (rc < 0) {
775 sms_err("mode detect failed %d", rc);
776 return rc;
777 }
778 }
779
780 if (coredev->mode == mode) {
781 sms_info("device mode %d already set", mode);
782 return 0;
783 }
784
785 if (!(coredev->modes_supported & (1 << mode))) {
786 char *fw_filename;
787
788 type = smscore_registry_gettype(coredev->devpath);
789 fw_filename = sms_get_fw_name(coredev, mode, type);
790
791 rc = smscore_load_firmware_from_file(coredev,
792 fw_filename, NULL);
793 if (rc < 0) {
794 sms_warn("error %d loading firmware: %s, "
795 "trying again with default firmware",
796 rc, fw_filename);
797
798 /* try again with the default firmware */
799 fw_filename = smscore_fw_lkup[mode][type];
800 rc = smscore_load_firmware_from_file(coredev,
801 fw_filename, NULL);
802
803 if (rc < 0) {
804 sms_warn("error %d loading "
805 "firmware: %s", rc,
806 fw_filename);
807 return rc;
808 }
809 }
810 sms_log("firmware download success: %s", fw_filename);
811 } else
812 sms_info("mode %d supported by running "
813 "firmware", mode);
814
815 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
816 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
817 if (buffer) {
818 struct SmsMsgData_ST *msg =
819 (struct SmsMsgData_ST *)
820 SMS_ALIGN_ADDRESS(buffer);
821
822 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
823 sizeof(struct SmsMsgData_ST));
824 msg->msgData[0] = mode;
825
826 rc = smscore_sendrequest_and_wait(
827 coredev, msg, msg->xMsgHeader.msgLength,
828 &coredev->init_device_done);
829
830 kfree(buffer);
831 } else {
832 sms_err("Could not allocate buffer for "
833 "init device message.");
834 rc = -ENOMEM;
835 }
836 } else {
837 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
838 sms_err("invalid mode specified %d", mode);
839 return -EINVAL;
840 }
841
842 smscore_registry_setmode(coredev->devpath, mode);
843
844 if (coredev->detectmode_handler)
845 coredev->detectmode_handler(coredev->context,
846 &coredev->mode);
847
848 if (coredev->mode != mode && coredev->setmode_handler)
849 rc = coredev->setmode_handler(coredev->context, mode);
850 }
851
852 if (rc >= 0) {
853 coredev->mode = mode;
854 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
855 }
856
857 if (rc != 0)
858 sms_err("return error code %d.", rc);
859 return rc;
860}
861
862/**
863 * calls device handler to get current mode of operation
864 *
865 * @param coredev pointer to a coredev object returned by
866 * smscore_register_device
867 *
868 * @return current mode
869 */
870int smscore_get_device_mode(struct smscore_device_t *coredev)
871{
872 return coredev->mode;
873}
874
875/**
876 * find client by response id & type within the clients list.
877 * return client handle or NULL.
878 *
879 * @param coredev pointer to a coredev object returned by
880 * smscore_register_device
881 * @param data_type client data type (SMS_DONT_CARE for all types)
882 * @param id client id (SMS_DONT_CARE for all id)
883 *
884 */
885static struct
886smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
887 int data_type, int id)
888{
889 struct smscore_client_t *client = NULL;
890 struct list_head *next, *first;
891 unsigned long flags;
892 struct list_head *firstid, *nextid;
893
894
895 spin_lock_irqsave(&coredev->clientslock, flags);
896 first = &coredev->clients;
897 for (next = first->next;
898 (next != first) && !client;
899 next = next->next) {
900 firstid = &((struct smscore_client_t *)next)->idlist;
901 for (nextid = firstid->next;
902 nextid != firstid;
903 nextid = nextid->next) {
904 if ((((struct smscore_idlist_t *)nextid)->id == id) &&
905 (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
906 (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
907 client = (struct smscore_client_t *) next;
908 break;
909 }
910 }
911 }
912 spin_unlock_irqrestore(&coredev->clientslock, flags);
913 return client;
914}
915
916/**
917 * find client by response id/type, call clients onresponse handler
918 * return buffer to pool on error
919 *
920 * @param coredev pointer to a coredev object returned by
921 * smscore_register_device
922 * @param cb pointer to response buffer descriptor
923 *
924 */
925void smscore_onresponse(struct smscore_device_t *coredev,
926 struct smscore_buffer_t *cb)
927{
928 struct SmsMsgHdr_ST *phdr =
929 (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset);
930 struct smscore_client_t *client =
931 smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
932 int rc = -EBUSY;
933
934 static unsigned long last_sample_time; /* = 0; */
935 static int data_total; /* = 0; */
936 unsigned long time_now = jiffies_to_msecs(jiffies);
937
938 if (!last_sample_time)
939 last_sample_time = time_now;
940
941 if (time_now - last_sample_time > 10000) {
942 sms_debug("\ndata rate %d bytes/secs",
943 (int)((data_total * 1000) /
944 (time_now - last_sample_time)));
945
946 last_sample_time = time_now;
947 data_total = 0;
948 }
949
950 data_total += cb->size;
951 /* If no client registered for type & id,
952 * check for control client where type is not registered */
953 if (client)
954 rc = client->onresponse_handler(client->context, cb);
955
956 if (rc < 0) {
957 switch (phdr->msgType) {
958 case MSG_SMS_GET_VERSION_EX_RES:
959 {
960 struct SmsVersionRes_ST *ver =
961 (struct SmsVersionRes_ST *) phdr;
962 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
963 "id %d prots 0x%x ver %d.%d",
964 ver->FirmwareId, ver->SupportedProtocols,
965 ver->RomVersionMajor, ver->RomVersionMinor);
966
967 coredev->mode = ver->FirmwareId == 255 ?
968 DEVICE_MODE_NONE : ver->FirmwareId;
969 coredev->modes_supported = ver->SupportedProtocols;
970
971 complete(&coredev->version_ex_done);
972 break;
973 }
974 case MSG_SMS_INIT_DEVICE_RES:
975 sms_debug("MSG_SMS_INIT_DEVICE_RES");
976 complete(&coredev->init_device_done);
977 break;
978 case MSG_SW_RELOAD_START_RES:
979 sms_debug("MSG_SW_RELOAD_START_RES");
980 complete(&coredev->reload_start_done);
981 break;
982 case MSG_SMS_DATA_DOWNLOAD_RES:
983 complete(&coredev->data_download_done);
984 break;
985 case MSG_SW_RELOAD_EXEC_RES:
986 sms_debug("MSG_SW_RELOAD_EXEC_RES");
987 break;
988 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
989 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
990 complete(&coredev->trigger_done);
991 break;
992 case MSG_SMS_SLEEP_RESUME_COMP_IND:
993 complete(&coredev->resume_done);
994 break;
995 default:
996 break;
997 }
998 smscore_putbuffer(coredev, cb);
999 }
1000}
1001
1002/**
1003 * return pointer to next free buffer descriptor from core pool
1004 *
1005 * @param coredev pointer to a coredev object returned by
1006 * smscore_register_device
1007 *
1008 * @return pointer to descriptor on success, NULL on error.
1009 */
1010struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1011{
1012 struct smscore_buffer_t *cb = NULL;
1013 unsigned long flags;
1014
1015 spin_lock_irqsave(&coredev->bufferslock, flags);
1016
1017 if (!list_empty(&coredev->buffers)) {
1018 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1019 list_del(&cb->entry);
1020 }
1021
1022 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1023
1024 return cb;
1025}
1026
1027/**
1028 * return buffer descriptor to a pool
1029 *
1030 * @param coredev pointer to a coredev object returned by
1031 * smscore_register_device
1032 * @param cb pointer buffer descriptor
1033 *
1034 */
1035void smscore_putbuffer(struct smscore_device_t *coredev,
1036 struct smscore_buffer_t *cb)
1037{
1038 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1039}
1040
1041static int smscore_validate_client(struct smscore_device_t *coredev,
1042 struct smscore_client_t *client,
1043 int data_type, int id)
1044{
1045 struct smscore_idlist_t *listentry;
1046 struct smscore_client_t *registered_client;
1047
1048 if (!client) {
1049 sms_err("bad parameter.");
1050 return -EFAULT;
1051 }
1052 registered_client = smscore_find_client(coredev, data_type, id);
1053 if (registered_client == client)
1054 return 0;
1055
1056 if (registered_client) {
1057 sms_err("The msg ID already registered to another client.");
1058 return -EEXIST;
1059 }
1060 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1061 if (!listentry) {
1062 sms_err("Can't allocate memory for client id.");
1063 return -ENOMEM;
1064 }
1065 listentry->id = id;
1066 listentry->data_type = data_type;
1067 list_add_locked(&listentry->entry, &client->idlist,
1068 &coredev->clientslock);
1069 return 0;
1070}
1071
1072/**
1073 * creates smsclient object, check that id is taken by another client
1074 *
1075 * @param coredev pointer to a coredev object from clients hotplug
1076 * @param initial_id all messages with this id would be sent to this client
1077 * @param data_type all messages of this type would be sent to this client
1078 * @param onresponse_handler client handler that is called to
1079 * process incoming messages
1080 * @param onremove_handler client handler that is called when device is removed
1081 * @param context client-specific context
1082 * @param client pointer to a value that receives created smsclient object
1083 *
1084 * @return 0 on success, <0 on error.
1085 */
1086int smscore_register_client(struct smscore_device_t *coredev,
1087 struct smsclient_params_t *params,
1088 struct smscore_client_t **client)
1089{
1090 struct smscore_client_t *newclient;
1091 /* check that no other channel with same parameters exists */
1092 if (smscore_find_client(coredev, params->data_type,
1093 params->initial_id)) {
1094 sms_err("Client already exist.");
1095 return -EEXIST;
1096 }
1097
1098 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1099 if (!newclient) {
1100 sms_err("Failed to allocate memory for client.");
1101 return -ENOMEM;
1102 }
1103
1104 INIT_LIST_HEAD(&newclient->idlist);
1105 newclient->coredev = coredev;
1106 newclient->onresponse_handler = params->onresponse_handler;
1107 newclient->onremove_handler = params->onremove_handler;
1108 newclient->context = params->context;
1109 list_add_locked(&newclient->entry, &coredev->clients,
1110 &coredev->clientslock);
1111 smscore_validate_client(coredev, newclient, params->data_type,
1112 params->initial_id);
1113 *client = newclient;
1114 sms_debug("%p %d %d", params->context, params->data_type,
1115 params->initial_id);
1116
1117 return 0;
1118}
1119
1120/**
1121 * frees smsclient object and all subclients associated with it
1122 *
1123 * @param client pointer to smsclient object returned by
1124 * smscore_register_client
1125 *
1126 */
1127void smscore_unregister_client(struct smscore_client_t *client)
1128{
1129 struct smscore_device_t *coredev = client->coredev;
1130 unsigned long flags;
1131
1132 spin_lock_irqsave(&coredev->clientslock, flags);
1133
1134
1135 while (!list_empty(&client->idlist)) {
1136 struct smscore_idlist_t *identry =
1137 (struct smscore_idlist_t *) client->idlist.next;
1138 list_del(&identry->entry);
1139 kfree(identry);
1140 }
1141
1142 sms_info("%p", client->context);
1143
1144 list_del(&client->entry);
1145 kfree(client);
1146
1147 spin_unlock_irqrestore(&coredev->clientslock, flags);
1148}
1149
1150/**
1151 * verifies that source id is not taken by another client,
1152 * calls device handler to send requests to the device
1153 *
1154 * @param client pointer to smsclient object returned by
1155 * smscore_register_client
1156 * @param buffer pointer to a request buffer
1157 * @param size size (in bytes) of request buffer
1158 *
1159 * @return 0 on success, <0 on error.
1160 */
1161int smsclient_sendrequest(struct smscore_client_t *client,
1162 void *buffer, size_t size)
1163{
1164 struct smscore_device_t *coredev;
1165 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1166 int rc;
1167
1168 if (client == NULL) {
1169 sms_err("Got NULL client");
1170 return -EINVAL;
1171 }
1172
1173 coredev = client->coredev;
1174
1175 /* check that no other channel with same id exists */
1176 if (coredev == NULL) {
1177 sms_err("Got NULL coredev");
1178 return -EINVAL;
1179 }
1180
1181 rc = smscore_validate_client(client->coredev, client, 0,
1182 phdr->msgSrcId);
1183 if (rc < 0)
1184 return rc;
1185
1186 return coredev->sendrequest_handler(coredev->context, buffer, size);
1187}
1188
1189
1190int smscore_module_init(void)
1191{
1192 int rc = 0;
1193
1194 INIT_LIST_HEAD(&g_smscore_notifyees);
1195 INIT_LIST_HEAD(&g_smscore_devices);
1196 kmutex_init(&g_smscore_deviceslock);
1197
1198 INIT_LIST_HEAD(&g_smscore_registry);
1199 kmutex_init(&g_smscore_registrylock);
1200
1201 /* USB Register */
1202 rc = smsusb_register();
1203
1204 /* DVB Register */
1205 rc = smsdvb_register();
1206
1207 sms_debug("rc %d", rc);
1208
1209 return rc;
1210}
1211
1212void smscore_module_exit(void)
1213{
1214
1215 kmutex_lock(&g_smscore_deviceslock);
1216 while (!list_empty(&g_smscore_notifyees)) {
1217 struct smscore_device_notifyee_t *notifyee =
1218 (struct smscore_device_notifyee_t *)
1219 g_smscore_notifyees.next;
1220
1221 list_del(&notifyee->entry);
1222 kfree(notifyee);
1223 }
1224 kmutex_unlock(&g_smscore_deviceslock);
1225
1226 kmutex_lock(&g_smscore_registrylock);
1227 while (!list_empty(&g_smscore_registry)) {
1228 struct smscore_registry_entry_t *entry =
1229 (struct smscore_registry_entry_t *)
1230 g_smscore_registry.next;
1231
1232 list_del(&entry->entry);
1233 kfree(entry);
1234 }
1235 kmutex_unlock(&g_smscore_registrylock);
1236
1237 /* DVB UnRegister */
1238 smsdvb_unregister();
1239
1240 /* Unregister USB */
1241 smsusb_unregister();
1242
1243 sms_debug("");
1244}
1245
1246module_init(smscore_module_init);
1247module_exit(smscore_module_exit);
1248
1249MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
1250MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
1251MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
new file mode 100644
index 000000000000..c1f8f1dccb11
--- /dev/null
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -0,0 +1,434 @@
1/*
2 * Driver for the Siano SMS1xxx USB dongle
3 *
4 * author: Anatoly Greenblat
5 *
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as
10 * published by the Free Software Foundation;
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
14 *
15 * See the 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __smscoreapi_h__
23#define __smscoreapi_h__
24
25#include <linux/version.h>
26#include <linux/device.h>
27#include <linux/list.h>
28#include <linux/mm.h>
29#include <linux/scatterlist.h>
30#include <linux/types.h>
31#include <asm/page.h>
32
33#include "dmxdev.h"
34#include "dvbdev.h"
35#include "dvb_demux.h"
36#include "dvb_frontend.h"
37
38#include <linux/mutex.h>
39
40#define kmutex_init(_p_) mutex_init(_p_)
41#define kmutex_lock(_p_) mutex_lock(_p_)
42#define kmutex_trylock(_p_) mutex_trylock(_p_)
43#define kmutex_unlock(_p_) mutex_unlock(_p_)
44
45#ifndef min
46#define min(a, b) (((a) < (b)) ? (a) : (b))
47#endif
48
49#define SMS_ALLOC_ALIGNMENT 128
50#define SMS_DMA_ALIGNMENT 16
51#define SMS_ALIGN_ADDRESS(addr) \
52 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
53
54#define SMS_DEVICE_FAMILY2 1
55#define SMS_ROM_NO_RESPONSE 2
56#define SMS_DEVICE_NOT_READY 0x8000000
57
58enum sms_device_type_st {
59 SMS_STELLAR = 0,
60 SMS_NOVA_A0,
61 SMS_NOVA_B0,
62 SMS_VEGA,
63 SMS_NUM_OF_DEVICE_TYPES
64};
65
66struct smscore_device_t;
67struct smscore_client_t;
68struct smscore_buffer_t;
69
70typedef int (*hotplug_t)(struct smscore_device_t *coredev,
71 struct device *device, int arrival);
72
73typedef int (*setmode_t)(void *context, int mode);
74typedef void (*detectmode_t)(void *context, int *mode);
75typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
76typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
77typedef int (*preload_t)(void *context);
78typedef int (*postload_t)(void *context);
79
80typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
81typedef void (*onremove_t)(void *context);
82
83struct smscore_buffer_t {
84 /* public members, once passed to clients can be changed freely */
85 struct list_head entry;
86 int size;
87 int offset;
88
89 /* private members, read-only for clients */
90 void *p;
91 dma_addr_t phys;
92 unsigned long offset_in_common;
93};
94
95struct smsdevice_params_t {
96 struct device *device;
97
98 int buffer_size;
99 int num_buffers;
100
101 char devpath[32];
102 unsigned long flags;
103
104 setmode_t setmode_handler;
105 detectmode_t detectmode_handler;
106 sendrequest_t sendrequest_handler;
107 preload_t preload_handler;
108 postload_t postload_handler;
109
110 void *context;
111 enum sms_device_type_st device_type;
112};
113
114struct smsclient_params_t {
115 int initial_id;
116 int data_type;
117 onresponse_t onresponse_handler;
118 onremove_t onremove_handler;
119
120 void *context;
121};
122
123/* GPIO definitions for antenna frequency domain control (SMS8021) */
124#define SMS_ANTENNA_GPIO_0 1
125#define SMS_ANTENNA_GPIO_1 0
126
127#define BW_8_MHZ 0
128#define BW_7_MHZ 1
129#define BW_6_MHZ 2
130#define BW_5_MHZ 3
131#define BW_ISDBT_1SEG 4
132#define BW_ISDBT_3SEG 5
133
134#define MSG_HDR_FLAG_SPLIT_MSG 4
135
136#define MAX_GPIO_PIN_NUMBER 31
137
138#define HIF_TASK 11
139#define SMS_HOST_LIB 150
140#define DVBT_BDA_CONTROL_MSG_ID 201
141
142#define SMS_MAX_PAYLOAD_SIZE 240
143#define SMS_TUNE_TIMEOUT 500
144
145#define MSG_SMS_GPIO_CONFIG_REQ 507
146#define MSG_SMS_GPIO_CONFIG_RES 508
147#define MSG_SMS_GPIO_SET_LEVEL_REQ 509
148#define MSG_SMS_GPIO_SET_LEVEL_RES 510
149#define MSG_SMS_GPIO_GET_LEVEL_REQ 511
150#define MSG_SMS_GPIO_GET_LEVEL_RES 512
151#define MSG_SMS_RF_TUNE_REQ 561
152#define MSG_SMS_RF_TUNE_RES 562
153#define MSG_SMS_INIT_DEVICE_REQ 578
154#define MSG_SMS_INIT_DEVICE_RES 579
155#define MSG_SMS_ADD_PID_FILTER_REQ 601
156#define MSG_SMS_ADD_PID_FILTER_RES 602
157#define MSG_SMS_REMOVE_PID_FILTER_REQ 603
158#define MSG_SMS_REMOVE_PID_FILTER_RES 604
159#define MSG_SMS_DAB_CHANNEL 607
160#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
161#define MSG_SMS_GET_PID_FILTER_LIST_RES 609
162#define MSG_SMS_GET_STATISTICS_REQ 615
163#define MSG_SMS_GET_STATISTICS_RES 616
164#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
165#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
166#define MSG_SMS_GET_STATISTICS_EX_REQ 653
167#define MSG_SMS_GET_STATISTICS_EX_RES 654
168#define MSG_SMS_SLEEP_RESUME_COMP_IND 655
169#define MSG_SMS_DATA_DOWNLOAD_REQ 660
170#define MSG_SMS_DATA_DOWNLOAD_RES 661
171#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
172#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
173#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
174#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
175#define MSG_SMS_GET_VERSION_EX_REQ 668
176#define MSG_SMS_GET_VERSION_EX_RES 669
177#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
178#define MSG_SMS_I2C_SET_FREQ_REQ 685
179#define MSG_SMS_GENERIC_I2C_REQ 687
180#define MSG_SMS_GENERIC_I2C_RES 688
181#define MSG_SMS_DVBT_BDA_DATA 693
182#define MSG_SW_RELOAD_REQ 697
183#define MSG_SMS_DATA_MSG 699
184#define MSG_SW_RELOAD_START_REQ 702
185#define MSG_SW_RELOAD_START_RES 703
186#define MSG_SW_RELOAD_EXEC_REQ 704
187#define MSG_SW_RELOAD_EXEC_RES 705
188#define MSG_SMS_SPI_INT_LINE_SET_REQ 710
189#define MSG_SMS_ISDBT_TUNE_REQ 776
190#define MSG_SMS_ISDBT_TUNE_RES 777
191
192#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
193 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
194 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
195} while (0)
196#define SMS_INIT_MSG(ptr, type, len) \
197 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
198
199enum SMS_DEVICE_MODE {
200 DEVICE_MODE_NONE = -1,
201 DEVICE_MODE_DVBT = 0,
202 DEVICE_MODE_DVBH,
203 DEVICE_MODE_DAB_TDMB,
204 DEVICE_MODE_DAB_TDMB_DABIP,
205 DEVICE_MODE_DVBT_BDA,
206 DEVICE_MODE_ISDBT,
207 DEVICE_MODE_ISDBT_BDA,
208 DEVICE_MODE_CMMB,
209 DEVICE_MODE_RAW_TUNER,
210 DEVICE_MODE_MAX,
211};
212
213struct SmsMsgHdr_ST {
214 u16 msgType;
215 u8 msgSrcId;
216 u8 msgDstId;
217 u16 msgLength; /* Length of entire message, including header */
218 u16 msgFlags;
219};
220
221struct SmsMsgData_ST {
222 struct SmsMsgHdr_ST xMsgHeader;
223 u32 msgData[1];
224};
225
226struct SmsDataDownload_ST {
227 struct SmsMsgHdr_ST xMsgHeader;
228 u32 MemAddr;
229 u8 Payload[SMS_MAX_PAYLOAD_SIZE];
230};
231
232struct SmsVersionRes_ST {
233 struct SmsMsgHdr_ST xMsgHeader;
234
235 u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
236 u8 Step; /* 0 - Step A */
237 u8 MetalFix; /* 0 - Metal 0 */
238
239 u8 FirmwareId; /* 0xFF � ROM, otherwise the
240 * value indicated by
241 * SMSHOSTLIB_DEVICE_MODES_E */
242 u8 SupportedProtocols; /* Bitwise OR combination of
243 * supported protocols */
244
245 u8 VersionMajor;
246 u8 VersionMinor;
247 u8 VersionPatch;
248 u8 VersionFieldPatch;
249
250 u8 RomVersionMajor;
251 u8 RomVersionMinor;
252 u8 RomVersionPatch;
253 u8 RomVersionFieldPatch;
254
255 u8 TextLabel[34];
256};
257
258struct SmsFirmware_ST {
259 u32 CheckSum;
260 u32 Length;
261 u32 StartAddress;
262 u8 Payload[1];
263};
264
265struct SMSHOSTLIB_STATISTICS_ST {
266 u32 Reserved; /* Reserved */
267
268 /* Common parameters */
269 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
270 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
271 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
272
273 /* Reception quality */
274 s32 SNR; /* dB */
275 u32 BER; /* Post Viterbi BER [1E-5] */
276 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
277 u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A,
278 * valid only for DVB-T/H */
279 u32 MFER; /* DVB-H frame error rate in percentage,
280 * 0xFFFFFFFF indicate N/A, valid only for DVB-H */
281 s32 RSSI; /* dBm */
282 s32 InBandPwr; /* In band power in dBM */
283 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
284
285 /* Transmission parameters, valid only for DVB-T/H */
286 u32 Frequency; /* Frequency in Hz */
287 u32 Bandwidth; /* Bandwidth in MHz */
288 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
289 * for DVB-T/H FFT mode carriers in Kilos */
290 u32 ModemState; /* from SMS_DvbModemState_ET */
291 u32 GuardInterval; /* Guard Interval, 1 divided by value */
292 u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */
293 u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */
294 u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */
295 u32 Constellation; /* Constellation from SMS_Constellation_ET */
296
297 /* Burst parameters, valid only for DVB-H */
298 u32 BurstSize; /* Current burst size in bytes */
299 u32 BurstDuration; /* Current burst duration in mSec */
300 u32 BurstCycleTime; /* Current burst cycle time in mSec */
301 u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec,
302 * as calculated by demodulator */
303 u32 NumOfRows; /* Number of rows in MPE table */
304 u32 NumOfPaddCols; /* Number of padding columns in MPE table */
305 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */
306 /* Burst parameters */
307 u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */
308 u32 TotalTSPackets; /* Total number of transport-stream packets */
309 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
310 * errors after MPE RS decoding */
311 u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors
312 * after MPE RS decoding */
313 u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected
314 * by MPE RS decoding */
315
316 /* Common params */
317 u32 BERErrorCount; /* Number of errornous SYNC bits. */
318 u32 BERBitCount; /* Total number of SYNC bits. */
319
320 /* Interface information */
321 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
322
323 /* DAB/T-DMB */
324 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
325
326 /* DVB-H TPS parameters */
327 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
328 * if set to 0xFFFFFFFF cell_id not yet recovered */
329
330};
331
332struct SmsMsgStatisticsInfo_ST {
333 u32 RequestResult;
334
335 struct SMSHOSTLIB_STATISTICS_ST Stat;
336
337 /* Split the calc of the SNR in DAB */
338 u32 Signal; /* dB */
339 u32 Noise; /* dB */
340
341};
342
343
344struct smsdvb_client_t {
345 struct list_head entry;
346
347 struct smscore_device_t *coredev;
348 struct smscore_client_t *smsclient;
349
350 struct dvb_adapter adapter;
351 struct dvb_demux demux;
352 struct dmxdev dmxdev;
353 struct dvb_frontend frontend;
354
355 fe_status_t fe_status;
356 int fe_ber, fe_snr, fe_signal_strength;
357
358 struct completion tune_done, stat_done;
359
360 /* todo: save freq/band instead whole struct */
361 struct dvb_frontend_parameters fe_params;
362
363};
364
365extern void smscore_registry_setmode(char *devpath, int mode);
366extern int smscore_registry_getmode(char *devpath);
367
368extern int smscore_register_hotplug(hotplug_t hotplug);
369extern void smscore_unregister_hotplug(hotplug_t hotplug);
370
371extern int smscore_register_device(struct smsdevice_params_t *params,
372 struct smscore_device_t **coredev);
373extern void smscore_unregister_device(struct smscore_device_t *coredev);
374
375extern int smscore_start_device(struct smscore_device_t *coredev);
376extern int smscore_load_firmware(struct smscore_device_t *coredev,
377 char *filename,
378 loadfirmware_t loadfirmware_handler);
379
380extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
381extern int smscore_get_device_mode(struct smscore_device_t *coredev);
382
383extern int smscore_register_client(struct smscore_device_t *coredev,
384 struct smsclient_params_t *params,
385 struct smscore_client_t **client);
386extern void smscore_unregister_client(struct smscore_client_t *client);
387
388extern int smsclient_sendrequest(struct smscore_client_t *client,
389 void *buffer, size_t size);
390extern void smscore_onresponse(struct smscore_device_t *coredev,
391 struct smscore_buffer_t *cb);
392
393
394extern
395struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
396extern void smscore_putbuffer(struct smscore_device_t *coredev,
397 struct smscore_buffer_t *cb);
398
399void smscore_set_board_id(struct smscore_device_t *core, int id);
400int smscore_get_board_id(struct smscore_device_t *core);
401
402/* smsdvb.c */
403int smsdvb_register(void);
404void smsdvb_unregister(void);
405
406/* smsusb.c */
407int smsusb_register(void);
408void smsusb_unregister(void);
409
410/* ------------------------------------------------------------------------ */
411
412extern int sms_debug;
413
414#define DBG_INFO 1
415#define DBG_ADV 2
416
417#define sms_printk(kern, fmt, arg...) \
418 printk(kern "%s: " fmt "\n", __func__, ##arg)
419
420#define dprintk(kern, lvl, fmt, arg...) do {\
421 if (sms_debug & lvl) \
422 sms_printk(kern, fmt, ##arg); } while (0)
423
424#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
425#define sms_err(fmt, arg...) \
426 sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
427#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
428#define sms_info(fmt, arg...) \
429 dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
430#define sms_debug(fmt, arg...) \
431 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
432
433
434#endif /* __smscoreapi_h__ */
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
new file mode 100644
index 000000000000..6f9c18563867
--- /dev/null
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -0,0 +1,449 @@
1/*
2 * Driver for the Siano SMS1xxx USB dongle
3 *
4 * author: Anatoly Greenblat
5 *
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as
10 * published by the Free Software Foundation;
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
14 *
15 * See the 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/init.h>
24
25#include "smscoreapi.h"
26#include "sms-cards.h"
27
28DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
29
30struct list_head g_smsdvb_clients;
31struct mutex g_smsdvb_clientslock;
32
33static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
34{
35 struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
36 struct SmsMsgHdr_ST *phdr =
37 (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset);
38
39 switch (phdr->msgType) {
40 case MSG_SMS_DVBT_BDA_DATA:
41 dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1),
42 cb->size - sizeof(struct SmsMsgHdr_ST));
43 break;
44
45 case MSG_SMS_RF_TUNE_RES:
46 complete(&client->tune_done);
47 break;
48
49 case MSG_SMS_GET_STATISTICS_RES:
50 {
51 struct SmsMsgStatisticsInfo_ST *p =
52 (struct SmsMsgStatisticsInfo_ST *)(phdr + 1);
53
54 if (p->Stat.IsDemodLocked) {
55 client->fe_status = FE_HAS_SIGNAL |
56 FE_HAS_CARRIER |
57 FE_HAS_VITERBI |
58 FE_HAS_SYNC |
59 FE_HAS_LOCK;
60
61 client->fe_snr = p->Stat.SNR;
62 client->fe_ber = p->Stat.BER;
63
64 if (p->Stat.InBandPwr < -95)
65 client->fe_signal_strength = 0;
66 else if (p->Stat.InBandPwr > -29)
67 client->fe_signal_strength = 100;
68 else
69 client->fe_signal_strength =
70 (p->Stat.InBandPwr + 95) * 3 / 2;
71 } else {
72 client->fe_status = 0;
73 client->fe_snr =
74 client->fe_ber =
75 client->fe_signal_strength = 0;
76 }
77
78 complete(&client->stat_done);
79 break;
80 } }
81
82 smscore_putbuffer(client->coredev, cb);
83
84 return 0;
85}
86
87static void smsdvb_unregister_client(struct smsdvb_client_t *client)
88{
89 /* must be called under clientslock */
90
91 list_del(&client->entry);
92
93 smscore_unregister_client(client->smsclient);
94 dvb_unregister_frontend(&client->frontend);
95 dvb_dmxdev_release(&client->dmxdev);
96 dvb_dmx_release(&client->demux);
97 dvb_unregister_adapter(&client->adapter);
98 kfree(client);
99}
100
101static void smsdvb_onremove(void *context)
102{
103 kmutex_lock(&g_smsdvb_clientslock);
104
105 smsdvb_unregister_client((struct smsdvb_client_t *) context);
106
107 kmutex_unlock(&g_smsdvb_clientslock);
108}
109
110static int smsdvb_start_feed(struct dvb_demux_feed *feed)
111{
112 struct smsdvb_client_t *client =
113 container_of(feed->demux, struct smsdvb_client_t, demux);
114 struct SmsMsgData_ST PidMsg;
115
116 sms_debug("add pid %d(%x)",
117 feed->pid, feed->pid);
118
119 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
120 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
121 PidMsg.xMsgHeader.msgFlags = 0;
122 PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ;
123 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
124 PidMsg.msgData[0] = feed->pid;
125
126 return smsclient_sendrequest(client->smsclient,
127 &PidMsg, sizeof(PidMsg));
128}
129
130static int smsdvb_stop_feed(struct dvb_demux_feed *feed)
131{
132 struct smsdvb_client_t *client =
133 container_of(feed->demux, struct smsdvb_client_t, demux);
134 struct SmsMsgData_ST PidMsg;
135
136 sms_debug("remove pid %d(%x)",
137 feed->pid, feed->pid);
138
139 PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
140 PidMsg.xMsgHeader.msgDstId = HIF_TASK;
141 PidMsg.xMsgHeader.msgFlags = 0;
142 PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ;
143 PidMsg.xMsgHeader.msgLength = sizeof(PidMsg);
144 PidMsg.msgData[0] = feed->pid;
145
146 return smsclient_sendrequest(client->smsclient,
147 &PidMsg, sizeof(PidMsg));
148}
149
150static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
151 void *buffer, size_t size,
152 struct completion *completion)
153{
154 int rc = smsclient_sendrequest(client->smsclient, buffer, size);
155 if (rc < 0)
156 return rc;
157
158 return wait_for_completion_timeout(completion,
159 msecs_to_jiffies(2000)) ?
160 0 : -ETIME;
161}
162
163static int smsdvb_send_statistics_request(struct smsdvb_client_t *client)
164{
165 struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ,
166 DVBT_BDA_CONTROL_MSG_ID,
167 HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 };
168 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
169 &client->stat_done);
170}
171
172static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
173{
174 struct smsdvb_client_t *client =
175 container_of(fe, struct smsdvb_client_t, frontend);
176 int rc = smsdvb_send_statistics_request(client);
177
178 if (!rc)
179 *stat = client->fe_status;
180
181 return rc;
182}
183
184static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
185{
186 struct smsdvb_client_t *client =
187 container_of(fe, struct smsdvb_client_t, frontend);
188 int rc = smsdvb_send_statistics_request(client);
189
190 if (!rc)
191 *ber = client->fe_ber;
192
193 return rc;
194}
195
196static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
197{
198 struct smsdvb_client_t *client =
199 container_of(fe, struct smsdvb_client_t, frontend);
200 int rc = smsdvb_send_statistics_request(client);
201
202 if (!rc)
203 *strength = client->fe_signal_strength;
204
205 return rc;
206}
207
208static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
209{
210 struct smsdvb_client_t *client =
211 container_of(fe, struct smsdvb_client_t, frontend);
212 int rc = smsdvb_send_statistics_request(client);
213
214 if (!rc)
215 *snr = client->fe_snr;
216
217 return rc;
218}
219
220static int smsdvb_get_tune_settings(struct dvb_frontend *fe,
221 struct dvb_frontend_tune_settings *tune)
222{
223 sms_debug("");
224
225 tune->min_delay_ms = 400;
226 tune->step_size = 250000;
227 tune->max_drift = 0;
228 return 0;
229}
230
231static int smsdvb_set_frontend(struct dvb_frontend *fe,
232 struct dvb_frontend_parameters *fep)
233{
234 struct smsdvb_client_t *client =
235 container_of(fe, struct smsdvb_client_t, frontend);
236
237 struct {
238 struct SmsMsgHdr_ST Msg;
239 u32 Data[3];
240 } Msg;
241
242 Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
243 Msg.Msg.msgDstId = HIF_TASK;
244 Msg.Msg.msgFlags = 0;
245 Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ;
246 Msg.Msg.msgLength = sizeof(Msg);
247 Msg.Data[0] = fep->frequency;
248 Msg.Data[2] = 12000000;
249
250 sms_debug("freq %d band %d",
251 fep->frequency, fep->u.ofdm.bandwidth);
252
253 switch (fep->u.ofdm.bandwidth) {
254 case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break;
255 case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break;
256 case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break;
257 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
258 default: return -EINVAL;
259 }
260
261 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
262 &client->tune_done);
263}
264
265static int smsdvb_get_frontend(struct dvb_frontend *fe,
266 struct dvb_frontend_parameters *fep)
267{
268 struct smsdvb_client_t *client =
269 container_of(fe, struct smsdvb_client_t, frontend);
270
271 sms_debug("");
272
273 /* todo: */
274 memcpy(fep, &client->fe_params,
275 sizeof(struct dvb_frontend_parameters));
276 return 0;
277}
278
279static void smsdvb_release(struct dvb_frontend *fe)
280{
281 /* do nothing */
282}
283
284static struct dvb_frontend_ops smsdvb_fe_ops = {
285 .info = {
286 .name = "Siano Mobile Digital SMS1xxx",
287 .type = FE_OFDM,
288 .frequency_min = 44250000,
289 .frequency_max = 867250000,
290 .frequency_stepsize = 250000,
291 .caps = FE_CAN_INVERSION_AUTO |
292 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
293 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
294 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
295 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
296 FE_CAN_GUARD_INTERVAL_AUTO |
297 FE_CAN_RECOVER |
298 FE_CAN_HIERARCHY_AUTO,
299 },
300
301 .release = smsdvb_release,
302
303 .set_frontend = smsdvb_set_frontend,
304 .get_frontend = smsdvb_get_frontend,
305 .get_tune_settings = smsdvb_get_tune_settings,
306
307 .read_status = smsdvb_read_status,
308 .read_ber = smsdvb_read_ber,
309 .read_signal_strength = smsdvb_read_signal_strength,
310 .read_snr = smsdvb_read_snr,
311};
312
313static int smsdvb_hotplug(struct smscore_device_t *coredev,
314 struct device *device, int arrival)
315{
316 struct smsclient_params_t params;
317 struct smsdvb_client_t *client;
318 int rc;
319
320 /* device removal handled by onremove callback */
321 if (!arrival)
322 return 0;
323
324 if (smscore_get_device_mode(coredev) != 4) {
325 sms_err("SMS Device mode is not set for "
326 "DVB operation.");
327 return 0;
328 }
329
330 client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
331 if (!client) {
332 sms_err("kmalloc() failed");
333 return -ENOMEM;
334 }
335
336 /* register dvb adapter */
337 rc = dvb_register_adapter(&client->adapter,
338 sms_get_board(
339 smscore_get_board_id(coredev))->name,
340 THIS_MODULE, device, adapter_nr);
341 if (rc < 0) {
342 sms_err("dvb_register_adapter() failed %d", rc);
343 goto adapter_error;
344 }
345
346 /* init dvb demux */
347 client->demux.dmx.capabilities = DMX_TS_FILTERING;
348 client->demux.filternum = 32; /* todo: nova ??? */
349 client->demux.feednum = 32;
350 client->demux.start_feed = smsdvb_start_feed;
351 client->demux.stop_feed = smsdvb_stop_feed;
352
353 rc = dvb_dmx_init(&client->demux);
354 if (rc < 0) {
355 sms_err("dvb_dmx_init failed %d", rc);
356 goto dvbdmx_error;
357 }
358
359 /* init dmxdev */
360 client->dmxdev.filternum = 32;
361 client->dmxdev.demux = &client->demux.dmx;
362 client->dmxdev.capabilities = 0;
363
364 rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
365 if (rc < 0) {
366 sms_err("dvb_dmxdev_init failed %d", rc);
367 goto dmxdev_error;
368 }
369
370 /* init and register frontend */
371 memcpy(&client->frontend.ops, &smsdvb_fe_ops,
372 sizeof(struct dvb_frontend_ops));
373
374 rc = dvb_register_frontend(&client->adapter, &client->frontend);
375 if (rc < 0) {
376 sms_err("frontend registration failed %d", rc);
377 goto frontend_error;
378 }
379
380 params.initial_id = 1;
381 params.data_type = MSG_SMS_DVBT_BDA_DATA;
382 params.onresponse_handler = smsdvb_onresponse;
383 params.onremove_handler = smsdvb_onremove;
384 params.context = client;
385
386 rc = smscore_register_client(coredev, &params, &client->smsclient);
387 if (rc < 0) {
388 sms_err("smscore_register_client() failed %d", rc);
389 goto client_error;
390 }
391
392 client->coredev = coredev;
393
394 init_completion(&client->tune_done);
395 init_completion(&client->stat_done);
396
397 kmutex_lock(&g_smsdvb_clientslock);
398
399 list_add(&client->entry, &g_smsdvb_clients);
400
401 kmutex_unlock(&g_smsdvb_clientslock);
402
403 sms_info("success");
404
405 return 0;
406
407client_error:
408 dvb_unregister_frontend(&client->frontend);
409
410frontend_error:
411 dvb_dmxdev_release(&client->dmxdev);
412
413dmxdev_error:
414 dvb_dmx_release(&client->demux);
415
416dvbdmx_error:
417 dvb_unregister_adapter(&client->adapter);
418
419adapter_error:
420 kfree(client);
421 return rc;
422}
423
424int smsdvb_register(void)
425{
426 int rc;
427
428 INIT_LIST_HEAD(&g_smsdvb_clients);
429 kmutex_init(&g_smsdvb_clientslock);
430
431 rc = smscore_register_hotplug(smsdvb_hotplug);
432
433 sms_debug("");
434
435 return rc;
436}
437
438void smsdvb_unregister(void)
439{
440 smscore_unregister_hotplug(smsdvb_hotplug);
441
442 kmutex_lock(&g_smsdvb_clientslock);
443
444 while (!list_empty(&g_smsdvb_clients))
445 smsdvb_unregister_client(
446 (struct smsdvb_client_t *) g_smsdvb_clients.next);
447
448 kmutex_unlock(&g_smsdvb_clientslock);
449}
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
new file mode 100644
index 000000000000..c10b1849c6a3
--- /dev/null
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -0,0 +1,459 @@
1/*
2 * Driver for the Siano SMS1xxx USB dongle
3 *
4 * author: Anatoly Greenblat
5 *
6 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 3 as
10 * published by the Free Software Foundation;
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
14 *
15 * See the 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/kernel.h>
23#include <linux/init.h>
24#include <linux/usb.h>
25#include <linux/firmware.h>
26
27#include "smscoreapi.h"
28#include "sms-cards.h"
29
30#define USB1_BUFFER_SIZE 0x1000
31#define USB2_BUFFER_SIZE 0x4000
32
33#define MAX_BUFFERS 50
34#define MAX_URBS 10
35
36struct smsusb_device_t;
37
38struct smsusb_urb_t {
39 struct smscore_buffer_t *cb;
40 struct smsusb_device_t *dev;
41
42 struct urb urb;
43};
44
45struct smsusb_device_t {
46 struct usb_device *udev;
47 struct smscore_device_t *coredev;
48
49 struct smsusb_urb_t surbs[MAX_URBS];
50
51 int response_alignment;
52 int buffer_size;
53};
54
55static int smsusb_submit_urb(struct smsusb_device_t *dev,
56 struct smsusb_urb_t *surb);
57
58static void smsusb_onresponse(struct urb *urb)
59{
60 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
61 struct smsusb_device_t *dev = surb->dev;
62
63 if (urb->status < 0) {
64 sms_err("error, urb status %d, %d bytes",
65 urb->status, urb->actual_length);
66 return;
67 }
68
69 if (urb->actual_length > 0) {
70 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p;
71
72 if (urb->actual_length >= phdr->msgLength) {
73 surb->cb->size = phdr->msgLength;
74
75 if (dev->response_alignment &&
76 (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) {
77
78 surb->cb->offset =
79 dev->response_alignment +
80 ((phdr->msgFlags >> 8) & 3);
81
82 /* sanity check */
83 if (((int) phdr->msgLength +
84 surb->cb->offset) > urb->actual_length) {
85 sms_err("invalid response "
86 "msglen %d offset %d "
87 "size %d",
88 phdr->msgLength,
89 surb->cb->offset,
90 urb->actual_length);
91 goto exit_and_resubmit;
92 }
93
94 /* move buffer pointer and
95 * copy header to its new location */
96 memcpy((char *) phdr + surb->cb->offset,
97 phdr, sizeof(struct SmsMsgHdr_ST));
98 } else
99 surb->cb->offset = 0;
100
101 smscore_onresponse(dev->coredev, surb->cb);
102 surb->cb = NULL;
103 } else {
104 sms_err("invalid response "
105 "msglen %d actual %d",
106 phdr->msgLength, urb->actual_length);
107 }
108 }
109
110exit_and_resubmit:
111 smsusb_submit_urb(dev, surb);
112}
113
114static int smsusb_submit_urb(struct smsusb_device_t *dev,
115 struct smsusb_urb_t *surb)
116{
117 if (!surb->cb) {
118 surb->cb = smscore_getbuffer(dev->coredev);
119 if (!surb->cb) {
120 sms_err("smscore_getbuffer(...) returned NULL");
121 return -ENOMEM;
122 }
123 }
124
125 usb_fill_bulk_urb(
126 &surb->urb,
127 dev->udev,
128 usb_rcvbulkpipe(dev->udev, 0x81),
129 surb->cb->p,
130 dev->buffer_size,
131 smsusb_onresponse,
132 surb
133 );
134 surb->urb.transfer_dma = surb->cb->phys;
135 surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
136
137 return usb_submit_urb(&surb->urb, GFP_ATOMIC);
138}
139
140static void smsusb_stop_streaming(struct smsusb_device_t *dev)
141{
142 int i;
143
144 for (i = 0; i < MAX_URBS; i++) {
145 usb_kill_urb(&dev->surbs[i].urb);
146
147 if (dev->surbs[i].cb) {
148 smscore_putbuffer(dev->coredev, dev->surbs[i].cb);
149 dev->surbs[i].cb = NULL;
150 }
151 }
152}
153
154static int smsusb_start_streaming(struct smsusb_device_t *dev)
155{
156 int i, rc;
157
158 for (i = 0; i < MAX_URBS; i++) {
159 rc = smsusb_submit_urb(dev, &dev->surbs[i]);
160 if (rc < 0) {
161 sms_err("smsusb_submit_urb(...) failed");
162 smsusb_stop_streaming(dev);
163 break;
164 }
165 }
166
167 return rc;
168}
169
170static int smsusb_sendrequest(void *context, void *buffer, size_t size)
171{
172 struct smsusb_device_t *dev = (struct smsusb_device_t *) context;
173 int dummy;
174
175 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
176 buffer, size, &dummy, 1000);
177}
178
179static char *smsusb1_fw_lkup[] = {
180 "dvbt_stellar_usb.inp",
181 "dvbh_stellar_usb.inp",
182 "tdmb_stellar_usb.inp",
183 "none",
184 "dvbt_bda_stellar_usb.inp",
185};
186
187static inline char *sms_get_fw_name(int mode, int board_id)
188{
189 char **fw = sms_get_board(board_id)->fw;
190 return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode];
191}
192
193static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id)
194{
195 const struct firmware *fw;
196 u8 *fw_buffer;
197 int rc, dummy;
198 char *fw_filename;
199
200 if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) {
201 sms_err("invalid firmware id specified %d", id);
202 return -EINVAL;
203 }
204
205 fw_filename = sms_get_fw_name(id, board_id);
206
207 rc = request_firmware(&fw, fw_filename, &udev->dev);
208 if (rc < 0) {
209 sms_warn("failed to open \"%s\" mode %d, "
210 "trying again with default firmware", fw_filename, id);
211
212 fw_filename = smsusb1_fw_lkup[id];
213 rc = request_firmware(&fw, fw_filename, &udev->dev);
214 if (rc < 0) {
215 sms_warn("failed to open \"%s\" mode %d",
216 fw_filename, id);
217
218 return rc;
219 }
220 }
221
222 fw_buffer = kmalloc(fw->size, GFP_KERNEL);
223 if (fw_buffer) {
224 memcpy(fw_buffer, fw->data, fw->size);
225
226 rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2),
227 fw_buffer, fw->size, &dummy, 1000);
228
229 sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc);
230
231 kfree(fw_buffer);
232 } else {
233 sms_err("failed to allocate firmware buffer");
234 rc = -ENOMEM;
235 }
236 sms_info("read FW %s, size=%zd", fw_filename, fw->size);
237
238 release_firmware(fw);
239
240 return rc;
241}
242
243static void smsusb1_detectmode(void *context, int *mode)
244{
245 char *product_string =
246 ((struct smsusb_device_t *) context)->udev->product;
247
248 *mode = DEVICE_MODE_NONE;
249
250 if (!product_string) {
251 product_string = "none";
252 sms_err("product string not found");
253 } else if (strstr(product_string, "DVBH"))
254 *mode = 1;
255 else if (strstr(product_string, "BDA"))
256 *mode = 4;
257 else if (strstr(product_string, "DVBT"))
258 *mode = 0;
259 else if (strstr(product_string, "TDMB"))
260 *mode = 2;
261
262 sms_info("%d \"%s\"", *mode, product_string);
263}
264
265static int smsusb1_setmode(void *context, int mode)
266{
267 struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK,
268 sizeof(struct SmsMsgHdr_ST), 0 };
269
270 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
271 sms_err("invalid firmware id specified %d", mode);
272 return -EINVAL;
273 }
274
275 return smsusb_sendrequest(context, &Msg, sizeof(Msg));
276}
277
278static void smsusb_term_device(struct usb_interface *intf)
279{
280 struct smsusb_device_t *dev =
281 (struct smsusb_device_t *) usb_get_intfdata(intf);
282
283 if (dev) {
284 smsusb_stop_streaming(dev);
285
286 /* unregister from smscore */
287 if (dev->coredev)
288 smscore_unregister_device(dev->coredev);
289
290 kfree(dev);
291
292 sms_info("device %p destroyed", dev);
293 }
294
295 usb_set_intfdata(intf, NULL);
296}
297
298static int smsusb_init_device(struct usb_interface *intf, int board_id)
299{
300 struct smsdevice_params_t params;
301 struct smsusb_device_t *dev;
302 int i, rc;
303
304 /* create device object */
305 dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
306 if (!dev) {
307 sms_err("kzalloc(sizeof(struct smsusb_device_t) failed");
308 return -ENOMEM;
309 }
310
311 memset(&params, 0, sizeof(params));
312 usb_set_intfdata(intf, dev);
313 dev->udev = interface_to_usbdev(intf);
314
315 params.device_type = sms_get_board(board_id)->type;
316
317 switch (params.device_type) {
318 case SMS_STELLAR:
319 dev->buffer_size = USB1_BUFFER_SIZE;
320
321 params.setmode_handler = smsusb1_setmode;
322 params.detectmode_handler = smsusb1_detectmode;
323 break;
324 default:
325 sms_err("Unspecified sms device type!");
326 /* fall-thru */
327 case SMS_NOVA_A0:
328 case SMS_NOVA_B0:
329 case SMS_VEGA:
330 dev->buffer_size = USB2_BUFFER_SIZE;
331 dev->response_alignment =
332 dev->udev->ep_in[1]->desc.wMaxPacketSize -
333 sizeof(struct SmsMsgHdr_ST);
334
335 params.flags |= SMS_DEVICE_FAMILY2;
336 break;
337 }
338
339 params.device = &dev->udev->dev;
340 params.buffer_size = dev->buffer_size;
341 params.num_buffers = MAX_BUFFERS;
342 params.sendrequest_handler = smsusb_sendrequest;
343 params.context = dev;
344 snprintf(params.devpath, sizeof(params.devpath),
345 "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath);
346
347 /* register in smscore */
348 rc = smscore_register_device(&params, &dev->coredev);
349 if (rc < 0) {
350 sms_err("smscore_register_device(...) failed, rc %d", rc);
351 smsusb_term_device(intf);
352 return rc;
353 }
354
355 smscore_set_board_id(dev->coredev, board_id);
356
357 /* initialize urbs */
358 for (i = 0; i < MAX_URBS; i++) {
359 dev->surbs[i].dev = dev;
360 usb_init_urb(&dev->surbs[i].urb);
361 }
362
363 sms_info("smsusb_start_streaming(...).");
364 rc = smsusb_start_streaming(dev);
365 if (rc < 0) {
366 sms_err("smsusb_start_streaming(...) failed");
367 smsusb_term_device(intf);
368 return rc;
369 }
370
371 rc = smscore_start_device(dev->coredev);
372 if (rc < 0) {
373 sms_err("smscore_start_device(...) failed");
374 smsusb_term_device(intf);
375 return rc;
376 }
377
378 sms_info("device %p created", dev);
379
380 return rc;
381}
382
383static int smsusb_probe(struct usb_interface *intf,
384 const struct usb_device_id *id)
385{
386 struct usb_device *udev = interface_to_usbdev(intf);
387 char devpath[32];
388 int i, rc;
389
390 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
391 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
392
393 if (intf->num_altsetting > 0) {
394 rc = usb_set_interface(
395 udev, intf->cur_altsetting->desc.bInterfaceNumber, 0);
396 if (rc < 0) {
397 sms_err("usb_set_interface failed, rc %d", rc);
398 return rc;
399 }
400 }
401
402 sms_info("smsusb_probe %d",
403 intf->cur_altsetting->desc.bInterfaceNumber);
404 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
405 sms_info("endpoint %d %02x %02x %d", i,
406 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
407 intf->cur_altsetting->endpoint[i].desc.bmAttributes,
408 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
409
410 if ((udev->actconfig->desc.bNumInterfaces == 2) &&
411 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
412 sms_err("rom interface 0 is not used");
413 return -ENODEV;
414 }
415
416 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
417 snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
418 udev->bus->busnum, udev->devpath);
419 sms_info("stellar device was found.");
420 return smsusb1_load_firmware(
421 udev, smscore_registry_getmode(devpath),
422 id->driver_info);
423 }
424
425 rc = smsusb_init_device(intf, id->driver_info);
426 sms_info("rc %d", rc);
427 return rc;
428}
429
430static void smsusb_disconnect(struct usb_interface *intf)
431{
432 smsusb_term_device(intf);
433}
434
435static struct usb_driver smsusb_driver = {
436 .name = "sms1xxx",
437 .probe = smsusb_probe,
438 .disconnect = smsusb_disconnect,
439 .id_table = smsusb_id_table,
440};
441
442int smsusb_register(void)
443{
444 int rc = usb_register(&smsusb_driver);
445 if (rc)
446 sms_err("usb_register failed. Error number %d", rc);
447
448 sms_debug("");
449
450 return rc;
451}
452
453void smsusb_unregister(void)
454{
455 sms_debug("");
456 /* Regular USB Cleanup */
457 usb_deregister(&smsusb_driver);
458}
459
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index 07643e010093..87c973ac668b 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -106,6 +106,8 @@ config DVB_BUDGET_CI
106 select DVB_STV0299 if !DVB_FE_CUSTOMISE 106 select DVB_STV0299 if !DVB_FE_CUSTOMISE
107 select DVB_TDA1004X if !DVB_FE_CUSTOMISE 107 select DVB_TDA1004X if !DVB_FE_CUSTOMISE
108 select DVB_LNBP21 if !DVB_FE_CUSTOMISE 108 select DVB_LNBP21 if !DVB_FE_CUSTOMISE
109 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
110 select MEDIA_TUNER_TDA827X if !DVB_FE_CUSTOMISE
109 select VIDEO_IR 111 select VIDEO_IR
110 help 112 help
111 Support for simple SAA7146 based DVB cards 113 Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile
index d7483f1a9b3f..71451237294c 100644
--- a/drivers/media/dvb/ttpci/Makefile
+++ b/drivers/media/dvb/ttpci/Makefile
@@ -3,7 +3,11 @@
3# and the AV7110 DVB device driver 3# and the AV7110 DVB device driver
4# 4#
5 5
6dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o av7110_ir.o 6dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o
7
8ifdef CONFIG_INPUT_EVDEV
9dvb-ttpci-objs += av7110_ir.o
10endif
7 11
8obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o 12obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o
9obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o 13obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o
@@ -14,6 +18,7 @@ obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o
14obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o 18obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o
15 19
16EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 20EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
21EXTRA_CFLAGS += -Idrivers/media/common/tuners
17 22
18hostprogs-y := fdump 23hostprogs-y := fdump
19 24
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index f05d43d8b5cf..0777e8f9544b 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -587,7 +587,7 @@ static void gpioirq(unsigned long data)
587 } 587 }
588 DVB_RINGBUFFER_SKIP(cibuf, 2); 588 DVB_RINGBUFFER_SKIP(cibuf, 2);
589 589
590 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len, 0); 590 dvb_ringbuffer_read(cibuf, av7110->debi_virt, len);
591 591
592 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); 592 iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
593 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); 593 iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
@@ -1198,7 +1198,6 @@ static int start_ts_capture(struct av7110 *budget)
1198 if (budget->feeding1) 1198 if (budget->feeding1)
1199 return ++budget->feeding1; 1199 return ++budget->feeding1;
1200 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH); 1200 memset(budget->grabbing, 0x00, TS_HEIGHT * TS_WIDTH);
1201 budget->tsf = 0xff;
1202 budget->ttbp = 0; 1201 budget->ttbp = 0;
1203 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ 1202 SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */
1204 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ 1203 saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */
@@ -2403,18 +2402,18 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
2403 saa7146_write(dev, MC1, MASK_29); 2402 saa7146_write(dev, MC1, MASK_29);
2404 /* RPS1 timeout disable */ 2403 /* RPS1 timeout disable */
2405 saa7146_write(dev, RPS_TOV1, 0); 2404 saa7146_write(dev, RPS_TOV1, 0);
2406 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B)); 2405 WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
2407 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 2406 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
2408 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 2407 WRITE_RPS1(GPIO3_MSK);
2409 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); 2408 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
2410#if RPS_IRQ 2409#if RPS_IRQ
2411 /* issue RPS1 interrupt to increment counter */ 2410 /* issue RPS1 interrupt to increment counter */
2412 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 2411 WRITE_RPS1(CMD_INTERRUPT);
2413#endif 2412#endif
2414 WRITE_RPS1(cpu_to_le32(CMD_STOP)); 2413 WRITE_RPS1(CMD_STOP);
2415 /* Jump to begin of RPS program as safety measure (p37) */ 2414 /* Jump to begin of RPS program as safety measure (p37) */
2416 WRITE_RPS1(cpu_to_le32(CMD_JUMP)); 2415 WRITE_RPS1(CMD_JUMP);
2417 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); 2416 WRITE_RPS1(dev->d_rps1.dma_handle);
2418 2417
2419#if RPS_IRQ 2418#if RPS_IRQ
2420 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) 2419 /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
@@ -2472,11 +2471,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
2472 get recognized before the main driver is fully loaded */ 2471 get recognized before the main driver is fully loaded */
2473 saa7146_write(dev, GPIO_CTRL, 0x500000); 2472 saa7146_write(dev, GPIO_CTRL, 0x500000);
2474 2473
2475#ifdef I2C_ADAP_CLASS_TV_DIGITAL
2476 av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
2477#else
2478 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; 2474 av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
2479#endif
2480 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); 2475 strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
2481 2476
2482 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ 2477 saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
@@ -2527,28 +2522,28 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
2527 count = 0; 2522 count = 0;
2528 2523
2529 /* Wait Source Line Counter Threshold (p36) */ 2524 /* Wait Source Line Counter Threshold (p36) */
2530 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); 2525 WRITE_RPS1(CMD_PAUSE | EVT_HS);
2531 /* Set GPIO3=1 (p42) */ 2526 /* Set GPIO3=1 (p42) */
2532 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 2527 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
2533 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 2528 WRITE_RPS1(GPIO3_MSK);
2534 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); 2529 WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
2535#if RPS_IRQ 2530#if RPS_IRQ
2536 /* issue RPS1 interrupt */ 2531 /* issue RPS1 interrupt */
2537 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 2532 WRITE_RPS1(CMD_INTERRUPT);
2538#endif 2533#endif
2539 /* Wait reset Source Line Counter Threshold (p36) */ 2534 /* Wait reset Source Line Counter Threshold (p36) */
2540 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); 2535 WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
2541 /* Set GPIO3=0 (p42) */ 2536 /* Set GPIO3=0 (p42) */
2542 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 2537 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
2543 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 2538 WRITE_RPS1(GPIO3_MSK);
2544 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); 2539 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
2545#if RPS_IRQ 2540#if RPS_IRQ
2546 /* issue RPS1 interrupt */ 2541 /* issue RPS1 interrupt */
2547 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 2542 WRITE_RPS1(CMD_INTERRUPT);
2548#endif 2543#endif
2549 /* Jump to begin of RPS program (p37) */ 2544 /* Jump to begin of RPS program (p37) */
2550 WRITE_RPS1(cpu_to_le32(CMD_JUMP)); 2545 WRITE_RPS1(CMD_JUMP);
2551 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); 2546 WRITE_RPS1(dev->d_rps1.dma_handle);
2552 2547
2553 /* Fix VSYNC level */ 2548 /* Fix VSYNC level */
2554 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 2549 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h
index e494e04eeee8..55f23ddcb994 100644
--- a/drivers/media/dvb/ttpci/av7110.h
+++ b/drivers/media/dvb/ttpci/av7110.h
@@ -188,7 +188,6 @@ struct av7110 {
188 struct dvb_net dvb_net1; 188 struct dvb_net dvb_net1;
189 spinlock_t feedlock1; 189 spinlock_t feedlock1;
190 int feeding1; 190 int feeding1;
191 u8 tsf;
192 u32 ttbp; 191 u32 ttbp;
193 unsigned char *grabbing; 192 unsigned char *grabbing;
194 struct saa7146_pgtable pt; 193 struct saa7146_pgtable pt;
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index ec55a968f204..184647ad1c7c 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -269,7 +269,7 @@ int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen)
269 return -1; 269 return -1;
270 } 270 }
271 271
272 dvb_ringbuffer_read(buf, dest, (size_t) blen, 0); 272 dvb_ringbuffer_read(buf, dest, (size_t) blen);
273 273
274 dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", 274 dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n",
275 (unsigned long) buf->pread, (unsigned long) buf->pwrite); 275 (unsigned long) buf->pread, (unsigned long) buf->pwrite);
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index c58e3fc509ed..261135ded481 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -208,7 +208,7 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
208 return -EINVAL; 208 return -EINVAL;
209 DVB_RINGBUFFER_SKIP(cibuf, 2); 209 DVB_RINGBUFFER_SKIP(cibuf, 2);
210 210
211 return dvb_ringbuffer_read(cibuf, (u8 *)buf, len, 1); 211 return dvb_ringbuffer_read_user(cibuf, buf, len);
212} 212}
213 213
214static int dvb_ca_open(struct inode *inode, struct file *file) 214static int dvb_ca_open(struct inode *inode, struct file *file)
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h
index 74d940f75da6..ca99e5c1fc8a 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.h
+++ b/drivers/media/dvb/ttpci/av7110_hw.h
@@ -305,7 +305,6 @@ enum av7110_command_type {
305#define IRQ_STATE (DPRAM_BASE + 0x0F4) 305#define IRQ_STATE (DPRAM_BASE + 0x0F4)
306#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6) 306#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6)
307#define MSGSTATE (DPRAM_BASE + 0x0F8) 307#define MSGSTATE (DPRAM_BASE + 0x0F8)
308#define FILT_STATE (DPRAM_BASE + 0x0FA)
309#define COMMAND (DPRAM_BASE + 0x0FC) 308#define COMMAND (DPRAM_BASE + 0x0FC)
310#define COM_BUFF (DPRAM_BASE + 0x100) 309#define COM_BUFF (DPRAM_BASE + 0x100)
311#define COM_BUFF_SIZE 0x20 310#define COM_BUFF_SIZE 0x20
@@ -332,8 +331,6 @@ enum av7110_command_type {
332 331
333/* firmware status area */ 332/* firmware status area */
334#define STATUS_BASE (DPRAM_BASE + 0x1FC0) 333#define STATUS_BASE (DPRAM_BASE + 0x1FC0)
335#define STATUS_SCR (STATUS_BASE + 0x00)
336#define STATUS_MODES (STATUS_BASE + 0x04)
337#define STATUS_LOOPS (STATUS_BASE + 0x08) 334#define STATUS_LOOPS (STATUS_BASE + 0x08)
338 335
339#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C) 336#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C)
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index b30a5288e484..b7d1f2f18d3a 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -667,6 +667,11 @@ static struct tda1002x_config philips_cu1216_config_altaddress = {
667 .invert = 0, 667 .invert = 0,
668}; 668};
669 669
670static struct tda10023_config philips_cu1216_tda10023_config = {
671 .demod_address = 0x0c,
672 .invert = 1,
673};
674
670static int philips_tu1216_tuner_init(struct dvb_frontend *fe) 675static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
671{ 676{
672 struct budget *budget = (struct budget *) fe->dvb->priv; 677 struct budget *budget = (struct budget *) fe->dvb->priv;
@@ -1019,9 +1024,10 @@ static void frontend_init(struct budget_av *budget_av)
1019 case SUBID_DVBC_KNC1_PLUS_MK3: 1024 case SUBID_DVBC_KNC1_PLUS_MK3:
1020 budget_av->reinitialise_demod = 1; 1025 budget_av->reinitialise_demod = 1;
1021 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; 1026 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1022 fe = dvb_attach(tda10023_attach, &philips_cu1216_config, 1027 fe = dvb_attach(tda10023_attach,
1023 &budget_av->budget.i2c_adap, 1028 &philips_cu1216_tda10023_config,
1024 read_pwm(budget_av)); 1029 &budget_av->budget.i2c_adap,
1030 read_pwm(budget_av));
1025 if (fe) { 1031 if (fe) {
1026 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; 1032 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1027 } 1033 }
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 6530323d5406..060e7c785326 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -46,6 +46,8 @@
46#include "lnbp21.h" 46#include "lnbp21.h"
47#include "bsbe1.h" 47#include "bsbe1.h"
48#include "bsru6.h" 48#include "bsru6.h"
49#include "tda1002x.h"
50#include "tda827x.h"
49 51
50/* 52/*
51 * Regarding DEBIADDR_IR: 53 * Regarding DEBIADDR_IR:
@@ -225,6 +227,7 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
225 break; 227 break;
226 case 0x1010: 228 case 0x1010:
227 case 0x1017: 229 case 0x1017:
230 case 0x101a:
228 /* for the Technotrend 1500 bundled remote */ 231 /* for the Technotrend 1500 bundled remote */
229 ir_input_init(input_dev, &budget_ci->ir.state, 232 ir_input_init(input_dev, &budget_ci->ir.state,
230 IR_TYPE_RC5, ir_codes_tt_1500); 233 IR_TYPE_RC5, ir_codes_tt_1500);
@@ -1056,6 +1059,15 @@ static struct stv0297_config dvbc_philips_tdm1316l_config = {
1056 .stop_during_read = 1, 1059 .stop_during_read = 1,
1057}; 1060};
1058 1061
1062static struct tda10023_config tda10023_config = {
1063 .demod_address = 0xc,
1064 .invert = 0,
1065 .xtal = 16000000,
1066 .pll_m = 11,
1067 .pll_p = 3,
1068 .pll_n = 1,
1069 .deltaf = 0xa511,
1070};
1059 1071
1060 1072
1061 1073
@@ -1126,7 +1138,17 @@ static void frontend_init(struct budget_ci *budget_ci)
1126 budget_ci->budget.dvb_frontend = NULL; 1138 budget_ci->budget.dvb_frontend = NULL;
1127 } 1139 }
1128 } 1140 }
1141 break;
1129 1142
1143 case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
1144 budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
1145 if (budget_ci->budget.dvb_frontend) {
1146 if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
1147 printk(KERN_ERR "%s: No tda827x found!\n", __func__);
1148 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1149 budget_ci->budget.dvb_frontend = NULL;
1150 }
1151 }
1130 break; 1152 break;
1131 } 1153 }
1132 1154
@@ -1216,6 +1238,7 @@ MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC);
1216MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 1238MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT);
1217MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); 1239MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT);
1218MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); 1240MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
1241MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
1219 1242
1220static struct pci_device_id pci_tbl[] = { 1243static struct pci_device_id pci_tbl[] = {
1221 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), 1244 MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1224,6 +1247,7 @@ static struct pci_device_id pci_tbl[] = {
1224 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), 1247 MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011),
1225 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), 1248 MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012),
1226 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), 1249 MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
1250 MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
1227 { 1251 {
1228 .vendor = 0, 1252 .vendor = 0,
1229 } 1253 }
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c
index 18cac4b12ab2..6f4ddb643fee 100644
--- a/drivers/media/dvb/ttpci/budget-core.c
+++ b/drivers/media/dvb/ttpci/budget-core.c
@@ -497,11 +497,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev,
497 if (bi->type != BUDGET_FS_ACTIVY) 497 if (bi->type != BUDGET_FS_ACTIVY)
498 saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ 498 saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */
499 499
500#ifdef I2C_ADAP_CLASS_TV_DIGITAL
501 budget->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
502#else
503 budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; 500 budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
504#endif
505 501
506 strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); 502 strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
507 503
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c
index 9a155396d6ac..39bd0a20f53a 100644
--- a/drivers/media/dvb/ttpci/budget-patch.c
+++ b/drivers/media/dvb/ttpci/budget-patch.c
@@ -431,22 +431,22 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
431 // in budget patch GPIO3 is connected to VSYNC_B 431 // in budget patch GPIO3 is connected to VSYNC_B
432 count = 0; 432 count = 0;
433#if 0 433#if 0
434 WRITE_RPS1(cpu_to_le32(CMD_UPLOAD | 434 WRITE_RPS1(CMD_UPLOAD |
435 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 )); 435 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
436#endif 436#endif
437 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B)); 437 WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
438 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 438 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
439 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 439 WRITE_RPS1(GPIO3_MSK);
440 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); 440 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
441#if RPS_IRQ 441#if RPS_IRQ
442 // issue RPS1 interrupt to increment counter 442 // issue RPS1 interrupt to increment counter
443 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 443 WRITE_RPS1(CMD_INTERRUPT);
444 // at least a NOP is neede between two interrupts 444 // at least a NOP is neede between two interrupts
445 WRITE_RPS1(cpu_to_le32(CMD_NOP)); 445 WRITE_RPS1(CMD_NOP);
446 // interrupt again 446 // interrupt again
447 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 447 WRITE_RPS1(CMD_INTERRUPT);
448#endif 448#endif
449 WRITE_RPS1(cpu_to_le32(CMD_STOP)); 449 WRITE_RPS1(CMD_STOP);
450 450
451#if RPS_IRQ 451#if RPS_IRQ
452 // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) 452 // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53)
@@ -558,28 +558,28 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte
558 558
559 559
560 // Wait Source Line Counter Threshold (p36) 560 // Wait Source Line Counter Threshold (p36)
561 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS)); 561 WRITE_RPS1(CMD_PAUSE | EVT_HS);
562 // Set GPIO3=1 (p42) 562 // Set GPIO3=1 (p42)
563 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 563 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
564 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 564 WRITE_RPS1(GPIO3_MSK);
565 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24)); 565 WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
566#if RPS_IRQ 566#if RPS_IRQ
567 // issue RPS1 interrupt 567 // issue RPS1 interrupt
568 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 568 WRITE_RPS1(CMD_INTERRUPT);
569#endif 569#endif
570 // Wait reset Source Line Counter Threshold (p36) 570 // Wait reset Source Line Counter Threshold (p36)
571 WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS)); 571 WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
572 // Set GPIO3=0 (p42) 572 // Set GPIO3=0 (p42)
573 WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2))); 573 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
574 WRITE_RPS1(cpu_to_le32(GPIO3_MSK)); 574 WRITE_RPS1(GPIO3_MSK);
575 WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24)); 575 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
576#if RPS_IRQ 576#if RPS_IRQ
577 // issue RPS1 interrupt 577 // issue RPS1 interrupt
578 WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT)); 578 WRITE_RPS1(CMD_INTERRUPT);
579#endif 579#endif
580 // Jump to begin of RPS program (p37) 580 // Jump to begin of RPS program (p37)
581 WRITE_RPS1(cpu_to_le32(CMD_JUMP)); 581 WRITE_RPS1(CMD_JUMP);
582 WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle)); 582 WRITE_RPS1(dev->d_rps1.dma_handle);
583 583
584 // Fix VSYNC level 584 // Fix VSYNC level
585 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 585 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index bc2043e44ebd..e6c9cd2e3b94 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/wait.h> 14#include <linux/wait.h>
15#include <linux/fs.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/usb.h> 17#include <linux/usb.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
@@ -990,22 +991,9 @@ static int stc_open(struct inode *inode, struct file *file)
990} 991}
991 992
992static ssize_t stc_read(struct file *file, char *buf, size_t count, 993static ssize_t stc_read(struct file *file, char *buf, size_t count,
993 loff_t * offset) 994 loff_t *offset)
994{ 995{
995 int tc = count; 996 return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192);
996
997 if ((tc + *offset) > 8192)
998 tc = 8192 - *offset;
999
1000 if (tc < 0)
1001 return 0;
1002
1003 if (copy_to_user(buf, stc_firmware + *offset, tc))
1004 return -EFAULT;
1005
1006 *offset += tc;
1007
1008 return tc;
1009} 997}
1010 998
1011static int stc_release(struct inode *inode, struct file *file) 999static int stc_release(struct inode *inode, struct file *file)
@@ -1693,11 +1681,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
1693 1681
1694 i2c_set_adapdata(&ttusb->i2c_adap, ttusb); 1682 i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
1695 1683
1696#ifdef I2C_ADAP_CLASS_TV_DIGITAL
1697 ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
1698#else
1699 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; 1684 ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
1700#endif
1701 ttusb->i2c_adap.algo = &ttusb_dec_algo; 1685 ttusb->i2c_adap.algo = &ttusb_dec_algo;
1702 ttusb->i2c_adap.algo_data = NULL; 1686 ttusb->i2c_adap.algo_data = NULL;
1703 ttusb->i2c_adap.dev.parent = &udev->dev; 1687 ttusb->i2c_adap.dev.parent = &udev->dev;