diff options
Diffstat (limited to 'drivers/media/dvb/dm1105/dm1105.c')
-rw-r--r-- | drivers/media/dvb/dm1105/dm1105.c | 150 |
1 files changed, 134 insertions, 16 deletions
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index 4dbd7d4185af..2d099e271751 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c | |||
@@ -44,6 +44,14 @@ | |||
44 | #include "cx24116.h" | 44 | #include "cx24116.h" |
45 | #include "z0194a.h" | 45 | #include "z0194a.h" |
46 | 46 | ||
47 | #define UNSET (-1U) | ||
48 | |||
49 | #define DM1105_BOARD_NOAUTO UNSET | ||
50 | #define DM1105_BOARD_UNKNOWN 0 | ||
51 | #define DM1105_BOARD_DVBWORLD_2002 1 | ||
52 | #define DM1105_BOARD_DVBWORLD_2004 2 | ||
53 | #define DM1105_BOARD_AXESS_DM05 3 | ||
54 | |||
47 | /* ----------------------------------------------- */ | 55 | /* ----------------------------------------------- */ |
48 | /* | 56 | /* |
49 | * PCI ID's | 57 | * PCI ID's |
@@ -153,20 +161,105 @@ | |||
153 | 161 | ||
154 | /* GPIO's for LNB power control */ | 162 | /* GPIO's for LNB power control */ |
155 | #define DM1105_LNB_MASK 0x00000000 | 163 | #define DM1105_LNB_MASK 0x00000000 |
164 | #define DM1105_LNB_OFF 0x00020000 | ||
156 | #define DM1105_LNB_13V 0x00010100 | 165 | #define DM1105_LNB_13V 0x00010100 |
157 | #define DM1105_LNB_18V 0x00000100 | 166 | #define DM1105_LNB_18V 0x00000100 |
158 | 167 | ||
159 | /* GPIO's for LNB power control for Axess DM05 */ | 168 | /* GPIO's for LNB power control for Axess DM05 */ |
160 | #define DM05_LNB_MASK 0x00000000 | 169 | #define DM05_LNB_MASK 0x00000000 |
170 | #define DM05_LNB_OFF 0x00020000/* actually 13v */ | ||
161 | #define DM05_LNB_13V 0x00020000 | 171 | #define DM05_LNB_13V 0x00020000 |
162 | #define DM05_LNB_18V 0x00030000 | 172 | #define DM05_LNB_18V 0x00030000 |
163 | 173 | ||
174 | static unsigned int card[] = {[0 ... 3] = UNSET }; | ||
175 | module_param_array(card, int, NULL, 0444); | ||
176 | MODULE_PARM_DESC(card, "card type"); | ||
177 | |||
164 | static int ir_debug; | 178 | static int ir_debug; |
165 | module_param(ir_debug, int, 0644); | 179 | module_param(ir_debug, int, 0644); |
166 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); | 180 | MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); |
167 | 181 | ||
182 | static unsigned int dm1105_devcount; | ||
183 | |||
168 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 184 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); |
169 | 185 | ||
186 | struct dm1105_board { | ||
187 | char *name; | ||
188 | }; | ||
189 | |||
190 | struct dm1105_subid { | ||
191 | u16 subvendor; | ||
192 | u16 subdevice; | ||
193 | u32 card; | ||
194 | }; | ||
195 | |||
196 | static const struct dm1105_board dm1105_boards[] = { | ||
197 | [DM1105_BOARD_UNKNOWN] = { | ||
198 | .name = "UNKNOWN/GENERIC", | ||
199 | }, | ||
200 | [DM1105_BOARD_DVBWORLD_2002] = { | ||
201 | .name = "DVBWorld PCI 2002", | ||
202 | }, | ||
203 | [DM1105_BOARD_DVBWORLD_2004] = { | ||
204 | .name = "DVBWorld PCI 2004", | ||
205 | }, | ||
206 | [DM1105_BOARD_AXESS_DM05] = { | ||
207 | .name = "Axess/EasyTv DM05", | ||
208 | }, | ||
209 | }; | ||
210 | |||
211 | static const struct dm1105_subid dm1105_subids[] = { | ||
212 | { | ||
213 | .subvendor = 0x0000, | ||
214 | .subdevice = 0x2002, | ||
215 | .card = DM1105_BOARD_DVBWORLD_2002, | ||
216 | }, { | ||
217 | .subvendor = 0x0001, | ||
218 | .subdevice = 0x2002, | ||
219 | .card = DM1105_BOARD_DVBWORLD_2002, | ||
220 | }, { | ||
221 | .subvendor = 0x0000, | ||
222 | .subdevice = 0x2004, | ||
223 | .card = DM1105_BOARD_DVBWORLD_2004, | ||
224 | }, { | ||
225 | .subvendor = 0x0001, | ||
226 | .subdevice = 0x2004, | ||
227 | .card = DM1105_BOARD_DVBWORLD_2004, | ||
228 | }, { | ||
229 | .subvendor = 0x195d, | ||
230 | .subdevice = 0x1105, | ||
231 | .card = DM1105_BOARD_AXESS_DM05, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | static void dm1105_card_list(struct pci_dev *pci) | ||
236 | { | ||
237 | int i; | ||
238 | |||
239 | if (0 == pci->subsystem_vendor && | ||
240 | 0 == pci->subsystem_device) { | ||
241 | printk(KERN_ERR | ||
242 | "dm1105: Your board has no valid PCI Subsystem ID\n" | ||
243 | "dm1105: and thus can't be autodetected\n" | ||
244 | "dm1105: Please pass card=<n> insmod option to\n" | ||
245 | "dm1105: workaround that. Redirect complaints to\n" | ||
246 | "dm1105: the vendor of the TV card. Best regards,\n" | ||
247 | "dm1105: -- tux\n"); | ||
248 | } else { | ||
249 | printk(KERN_ERR | ||
250 | "dm1105: Your board isn't known (yet) to the driver.\n" | ||
251 | "dm1105: You can try to pick one of the existing\n" | ||
252 | "dm1105: card configs via card=<n> insmod option.\n" | ||
253 | "dm1105: Updating to the latest version might help\n" | ||
254 | "dm1105: as well.\n"); | ||
255 | } | ||
256 | printk(KERN_ERR "Here is a list of valid choices for the card=<n> " | ||
257 | "insmod option:\n"); | ||
258 | for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++) | ||
259 | printk(KERN_ERR "dm1105: card=%d -> %s\n", | ||
260 | i, dm1105_boards[i].name); | ||
261 | } | ||
262 | |||
170 | /* infrared remote control */ | 263 | /* infrared remote control */ |
171 | struct infrared { | 264 | struct infrared { |
172 | struct input_dev *input_dev; | 265 | struct input_dev *input_dev; |
@@ -193,6 +286,8 @@ struct dm1105dvb { | |||
193 | struct dvb_frontend *fe; | 286 | struct dvb_frontend *fe; |
194 | struct dvb_net dvbnet; | 287 | struct dvb_net dvbnet; |
195 | unsigned int full_ts_users; | 288 | unsigned int full_ts_users; |
289 | unsigned int boardnr; | ||
290 | int nr; | ||
196 | 291 | ||
197 | /* i2c */ | 292 | /* i2c */ |
198 | struct i2c_adapter i2c_adap; | 293 | struct i2c_adapter i2c_adap; |
@@ -211,7 +306,6 @@ struct dm1105dvb { | |||
211 | unsigned int PacketErrorCount; | 306 | unsigned int PacketErrorCount; |
212 | unsigned int dmarst; | 307 | unsigned int dmarst; |
213 | spinlock_t lock; | 308 | spinlock_t lock; |
214 | |||
215 | }; | 309 | }; |
216 | 310 | ||
217 | #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) | 311 | #define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) |
@@ -326,16 +420,20 @@ static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) | |||
326 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | 420 | static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) |
327 | { | 421 | { |
328 | struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); | 422 | struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); |
329 | u32 lnb_mask, lnb_13v, lnb_18v; | 423 | u32 lnb_mask, lnb_13v, lnb_18v, lnb_off; |
330 | 424 | ||
331 | switch (dm1105dvb->pdev->subsystem_device) { | 425 | switch (dm1105dvb->boardnr) { |
332 | case PCI_DEVICE_ID_DM05: | 426 | case DM1105_BOARD_AXESS_DM05: |
333 | lnb_mask = DM05_LNB_MASK; | 427 | lnb_mask = DM05_LNB_MASK; |
428 | lnb_off = DM05_LNB_OFF; | ||
334 | lnb_13v = DM05_LNB_13V; | 429 | lnb_13v = DM05_LNB_13V; |
335 | lnb_18v = DM05_LNB_18V; | 430 | lnb_18v = DM05_LNB_18V; |
336 | break; | 431 | break; |
432 | case DM1105_BOARD_DVBWORLD_2002: | ||
433 | case DM1105_BOARD_DVBWORLD_2004: | ||
337 | default: | 434 | default: |
338 | lnb_mask = DM1105_LNB_MASK; | 435 | lnb_mask = DM1105_LNB_MASK; |
436 | lnb_off = DM1105_LNB_OFF; | ||
339 | lnb_13v = DM1105_LNB_13V; | 437 | lnb_13v = DM1105_LNB_13V; |
340 | lnb_18v = DM1105_LNB_18V; | 438 | lnb_18v = DM1105_LNB_18V; |
341 | } | 439 | } |
@@ -343,8 +441,10 @@ static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volta | |||
343 | outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); | 441 | outl(lnb_mask, dm_io_mem(DM1105_GPIOCTR)); |
344 | if (voltage == SEC_VOLTAGE_18) | 442 | if (voltage == SEC_VOLTAGE_18) |
345 | outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); | 443 | outl(lnb_18v , dm_io_mem(DM1105_GPIOVAL)); |
346 | else | 444 | else if (voltage == SEC_VOLTAGE_13) |
347 | outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); | 445 | outl(lnb_13v, dm_io_mem(DM1105_GPIOVAL)); |
446 | else | ||
447 | outl(lnb_off, dm_io_mem(DM1105_GPIOVAL)); | ||
348 | 448 | ||
349 | return 0; | 449 | return 0; |
350 | } | 450 | } |
@@ -477,7 +577,7 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) | |||
477 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) | 577 | int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) |
478 | { | 578 | { |
479 | struct input_dev *input_dev; | 579 | struct input_dev *input_dev; |
480 | IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec; | 580 | struct ir_scancode_table *ir_codes = &ir_codes_dm1105_nec_table; |
481 | int ir_type = IR_TYPE_OTHER; | 581 | int ir_type = IR_TYPE_OTHER; |
482 | int err = -ENOMEM; | 582 | int err = -ENOMEM; |
483 | 583 | ||
@@ -589,8 +689,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) | |||
589 | { | 689 | { |
590 | int ret; | 690 | int ret; |
591 | 691 | ||
592 | switch (dm1105dvb->pdev->subsystem_device) { | 692 | switch (dm1105dvb->boardnr) { |
593 | case PCI_DEVICE_ID_DW2004: | 693 | case DM1105_BOARD_DVBWORLD_2004: |
594 | dm1105dvb->fe = dvb_attach( | 694 | dm1105dvb->fe = dvb_attach( |
595 | cx24116_attach, &serit_sp2633_config, | 695 | cx24116_attach, &serit_sp2633_config, |
596 | &dm1105dvb->i2c_adap); | 696 | &dm1105dvb->i2c_adap); |
@@ -598,6 +698,8 @@ static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) | |||
598 | dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; | 698 | dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; |
599 | 699 | ||
600 | break; | 700 | break; |
701 | case DM1105_BOARD_DVBWORLD_2002: | ||
702 | case DM1105_BOARD_AXESS_DM05: | ||
601 | default: | 703 | default: |
602 | dm1105dvb->fe = dvb_attach( | 704 | dm1105dvb->fe = dvb_attach( |
603 | stv0299_attach, &sharp_z0194a_config, | 705 | stv0299_attach, &sharp_z0194a_config, |
@@ -676,11 +778,31 @@ static int __devinit dm1105_probe(struct pci_dev *pdev, | |||
676 | struct dvb_demux *dvbdemux; | 778 | struct dvb_demux *dvbdemux; |
677 | struct dmx_demux *dmx; | 779 | struct dmx_demux *dmx; |
678 | int ret = -ENOMEM; | 780 | int ret = -ENOMEM; |
781 | int i; | ||
679 | 782 | ||
680 | dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); | 783 | dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); |
681 | if (!dm1105dvb) | 784 | if (!dm1105dvb) |
682 | return -ENOMEM; | 785 | return -ENOMEM; |
683 | 786 | ||
787 | /* board config */ | ||
788 | dm1105dvb->nr = dm1105_devcount; | ||
789 | dm1105dvb->boardnr = UNSET; | ||
790 | if (card[dm1105dvb->nr] < ARRAY_SIZE(dm1105_boards)) | ||
791 | dm1105dvb->boardnr = card[dm1105dvb->nr]; | ||
792 | for (i = 0; UNSET == dm1105dvb->boardnr && | ||
793 | i < ARRAY_SIZE(dm1105_subids); i++) | ||
794 | if (pdev->subsystem_vendor == | ||
795 | dm1105_subids[i].subvendor && | ||
796 | pdev->subsystem_device == | ||
797 | dm1105_subids[i].subdevice) | ||
798 | dm1105dvb->boardnr = dm1105_subids[i].card; | ||
799 | |||
800 | if (UNSET == dm1105dvb->boardnr) { | ||
801 | dm1105dvb->boardnr = DM1105_BOARD_UNKNOWN; | ||
802 | dm1105_card_list(pdev); | ||
803 | } | ||
804 | |||
805 | dm1105_devcount++; | ||
684 | dm1105dvb->pdev = pdev; | 806 | dm1105dvb->pdev = pdev; |
685 | dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; | 807 | dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; |
686 | dm1105dvb->PacketErrorCount = 0; | 808 | dm1105dvb->PacketErrorCount = 0; |
@@ -853,6 +975,7 @@ static void __devexit dm1105_remove(struct pci_dev *pdev) | |||
853 | pci_release_regions(pdev); | 975 | pci_release_regions(pdev); |
854 | pci_disable_device(pdev); | 976 | pci_disable_device(pdev); |
855 | pci_set_drvdata(pdev, NULL); | 977 | pci_set_drvdata(pdev, NULL); |
978 | dm1105_devcount--; | ||
856 | kfree(dm1105dvb); | 979 | kfree(dm1105dvb); |
857 | } | 980 | } |
858 | 981 | ||
@@ -861,17 +984,12 @@ static struct pci_device_id dm1105_id_table[] __devinitdata = { | |||
861 | .vendor = PCI_VENDOR_ID_TRIGEM, | 984 | .vendor = PCI_VENDOR_ID_TRIGEM, |
862 | .device = PCI_DEVICE_ID_DM1105, | 985 | .device = PCI_DEVICE_ID_DM1105, |
863 | .subvendor = PCI_ANY_ID, | 986 | .subvendor = PCI_ANY_ID, |
864 | .subdevice = PCI_DEVICE_ID_DW2002, | 987 | .subdevice = PCI_ANY_ID, |
865 | }, { | ||
866 | .vendor = PCI_VENDOR_ID_TRIGEM, | ||
867 | .device = PCI_DEVICE_ID_DM1105, | ||
868 | .subvendor = PCI_ANY_ID, | ||
869 | .subdevice = PCI_DEVICE_ID_DW2004, | ||
870 | }, { | 988 | }, { |
871 | .vendor = PCI_VENDOR_ID_AXESS, | 989 | .vendor = PCI_VENDOR_ID_AXESS, |
872 | .device = PCI_DEVICE_ID_DM05, | 990 | .device = PCI_DEVICE_ID_DM05, |
873 | .subvendor = PCI_VENDOR_ID_AXESS, | 991 | .subvendor = PCI_ANY_ID, |
874 | .subdevice = PCI_DEVICE_ID_DM05, | 992 | .subdevice = PCI_ANY_ID, |
875 | }, { | 993 | }, { |
876 | /* empty */ | 994 | /* empty */ |
877 | }, | 995 | }, |