[PATCH] dvb: budget-av: CI fixes

- remove enable_ci, ci interface is assumed to be present if the saa7113
is not found.
- reduce the delay when checking for saa7113
- clean up the cam reset according to specifications
- turn off Vcc to the cam slot if cam is removed or fails reset
- remove cam reset in ciintf_init
- clean up printks (KERN_)
- move gpio setting into saa7113_init
- clean up unreadable frontend_init
(Kenneth Aafloy)

Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Johannes Stezenbach and committed by
Linus Torvalds
b82a96a7 43f1a8f8

+118 -98
+118 -98
drivers/media/dvb/ttpci/budget-av.c
··· 59 struct dvb_ca_en50221 ca; 60 }; 61 62 - static int enable_ci = 0; 63 - 64 65 /**************************************************************************** 66 * INITIALIZATION ··· 192 { 193 struct budget_av *budget_av = (struct budget_av *) ca->data; 194 struct saa7146_dev *saa = budget_av->budget.dev; 195 - int max = 20; 196 197 if (slot != 0) 198 return -EINVAL; 199 200 dprintk(1, "ciintf_slot_reset\n"); 201 202 - /* reset the card */ 203 - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); 204 - msleep(100); 205 - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); 206 207 - while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) 208 msleep(100); 209 210 - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); 211 return 0; 212 } 213 ··· 257 { 258 struct budget_av *budget_av = (struct budget_av *) ca->data; 259 struct saa7146_dev *saa = budget_av->budget.dev; 260 - int cam = 0; 261 262 if (slot != 0) 263 return -EINVAL; ··· 264 if (!budget_av->slot_status) { 265 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 266 udelay(1); 267 - cam = saa7146_read(saa, PSR) & MASK_06; 268 - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 269 - 270 - if (cam) 271 budget_av->slot_status = 1; 272 } else if (!open) { 273 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); 274 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) 275 budget_av->slot_status = 0; 276 } 277 278 if (budget_av->slot_status == 1) ··· 294 295 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); 296 297 - /* setup GPIOs */ 298 - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); 299 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); 300 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 301 - 302 - /* Reset the card */ 303 - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); 304 - msleep(50); 305 - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); 306 - msleep(100); 307 308 /* Enable DEBI pins */ 309 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); ··· 313 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; 314 budget_av->ca.poll_slot_status = ciintf_poll_slot_status; 315 budget_av->ca.data = budget_av; 316 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, 317 &budget_av->ca, 0, 1)) != 0) { 318 - printk("budget_av: CI interface detected, but initialisation failed.\n"); 319 goto error; 320 } 321 - // success! 322 - printk("ciintf_init: CI interface initialised\n"); 323 budget_av->budget.ci_present = 1; 324 return 0; 325 ··· 378 static int saa7113_init(struct budget_av *budget_av) 379 { 380 struct budget *budget = &budget_av->budget; 381 const u8 *data = saa7113_tab; 382 383 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { 384 dprintk(1, "saa7113 not found on KNC card\n"); ··· 718 return pwm; 719 } 720 721 722 static void frontend_init(struct budget_av *budget_av) 723 { 724 - switch (budget_av->budget.dev->pci->subsystem_device) { 725 - case 0x0011: // KNC1 DVB-S Plus budget with AV IN (stv0299/Philips SU1278(tsa5059)) 726 - saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend 727 - case 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059)) 728 - case 0x0010: // KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059)) 729 - budget_av->budget.dvb_frontend = 730 - stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap); 731 - if (budget_av->budget.dvb_frontend != NULL) { 732 break; 733 - } 734 break; 735 736 - case 0x0021: // KNC1 DVB-C Plus budget with AV IN (tda10021/Philips CU1216(tua6034)) 737 - saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend 738 - case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034)) 739 - budget_av->budget.dvb_frontend = 740 - tda10021_attach(&philips_cu1216_config, 741 - &budget_av->budget.i2c_adap, read_pwm(budget_av)); 742 - if (budget_av->budget.dvb_frontend != NULL) { 743 - break; 744 - } 745 break; 746 747 - case 0x0031: // KNC1 DVB-T Plus budget with AV IN (tda10046/Philips TU1216(tda6651tt)) 748 - saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend 749 - case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt)) 750 - budget_av->budget.dvb_frontend = 751 - tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap); 752 - if (budget_av->budget.dvb_frontend != NULL) { 753 - break; 754 - } 755 break; 756 757 - case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059)) 758 - budget_av->budget.dvb_frontend = 759 - stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap); 760 - if (budget_av->budget.dvb_frontend != NULL) { 761 - break; 762 - } 763 break; 764 765 - case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034)) 766 - budget_av->budget.dvb_frontend = 767 - tda10021_attach(&philips_cu1216_config, 768 - &budget_av->budget.i2c_adap, read_pwm(budget_av)); 769 - if (budget_av->budget.dvb_frontend) { 770 - break; 771 - } 772 break; 773 774 - case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt)) 775 - budget_av->budget.dvb_frontend = 776 - tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap); 777 - if (budget_av->budget.dvb_frontend) { 778 - break; 779 - } 780 break; 781 } 782 783 - if (budget_av->budget.dvb_frontend == NULL) { 784 - printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 785 - budget_av->budget.dev->pci->vendor, 786 - budget_av->budget.dev->pci->device, 787 - budget_av->budget.dev->pci->subsystem_vendor, 788 - budget_av->budget.dev->pci->subsystem_device); 789 - } else { 790 - if (dvb_register_frontend 791 - (&budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) { 792 - printk("budget-av: Frontend registration failed!\n"); 793 - if (budget_av->budget.dvb_frontend->ops->release) 794 - budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); 795 - budget_av->budget.dvb_frontend = NULL; 796 - } 797 } 798 } 799 ··· 858 859 memset(budget_av, 0, sizeof(struct budget_av)); 860 861 budget_av->budget.ci_present = 0; 862 863 dev->ext_priv = budget_av; ··· 873 saa7146_write(dev, DD1_INIT, 0x07000600); 874 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); 875 876 - saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI); 877 - msleep(500); 878 - 879 - if (0 == saa7113_init(budget_av)) { 880 budget_av->has_saa7113 = 1; 881 882 if (0 != saa7146_vv_init(dev, &vv_data)) { ··· 894 895 saa7113_setinput(budget_av, 0); 896 } else { 897 - budget_av->has_saa7113 = 0; 898 - 899 - saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); 900 } 901 902 /* fixme: find some sane values here... */ ··· 902 903 mac = budget_av->budget.dvb_adapter.proposed_mac; 904 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { 905 - printk("KNC1-%d: Could not read MAC from KNC1 card\n", 906 budget_av->budget.dvb_adapter.num); 907 memset(mac, 0, 6); 908 } else { 909 - printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 910 budget_av->budget.dvb_adapter.num, 911 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 912 } 913 914 budget_av->budget.dvb_adapter.priv = budget_av; 915 frontend_init(budget_av); 916 - 917 - if (enable_ci) 918 - ciintf_init(budget_av); 919 920 return 0; 921 } ··· 1046 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); 1047 MODULE_DESCRIPTION("driver for the SAA7146 based so-called " 1048 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); 1049 - module_param_named(enable_ci, enable_ci, int, 0644); 1050 - MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");
··· 59 struct dvb_ca_en50221 ca; 60 }; 61 62 + /* GPIO CI Connections: 63 + * 0 - Vcc/Reset (Reset is controlled by capacitor) 64 + * 1 - Attribute Memory 65 + * 2 - Card Enable (Active Low) 66 + * 3 - Card Detect 67 + */ 68 69 /**************************************************************************** 70 * INITIALIZATION ··· 188 { 189 struct budget_av *budget_av = (struct budget_av *) ca->data; 190 struct saa7146_dev *saa = budget_av->budget.dev; 191 + int timeout = 50; // 5 seconds (4.4.6 Ready) 192 193 if (slot != 0) 194 return -EINVAL; 195 196 dprintk(1, "ciintf_slot_reset\n"); 197 198 + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 199 200 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ 201 + msleep(2); 202 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ 203 + msleep(20); /* 20 ms Vcc settling time */ 204 + 205 + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ 206 + 207 + /* This should have been based on pin 16 READY of the pcmcia port, 208 + * but AFAICS it is not routed to the saa7146 */ 209 + while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) 210 msleep(100); 211 212 + if (timeout <= 0) 213 + { 214 + printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); 215 + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 216 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ 217 + return -ETIMEDOUT; 218 + } 219 + 220 return 0; 221 } 222 ··· 240 { 241 struct budget_av *budget_av = (struct budget_av *) ca->data; 242 struct saa7146_dev *saa = budget_av->budget.dev; 243 244 if (slot != 0) 245 return -EINVAL; ··· 248 if (!budget_av->slot_status) { 249 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 250 udelay(1); 251 + if (saa7146_read(saa, PSR) & MASK_06) 252 + { 253 + printk(KERN_INFO "budget-av: cam inserted\n"); 254 budget_av->slot_status = 1; 255 + } 256 + saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 257 } else if (!open) { 258 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); 259 if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) 260 + { 261 + printk(KERN_INFO "budget-av: cam ejected\n"); 262 + saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ 263 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ 264 budget_av->slot_status = 0; 265 + } 266 } 267 268 if (budget_av->slot_status == 1) ··· 272 273 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); 274 275 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); 276 + saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); 277 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); 278 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); 279 280 /* Enable DEBI pins */ 281 saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); ··· 297 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; 298 budget_av->ca.poll_slot_status = ciintf_poll_slot_status; 299 budget_av->ca.data = budget_av; 300 + 301 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, 302 &budget_av->ca, 0, 1)) != 0) { 303 + printk(KERN_ERR "budget-av: ci initialisation failed.\n"); 304 goto error; 305 } 306 + 307 + printk(KERN_INFO "budget-av: ci interface initialised.\n"); 308 budget_av->budget.ci_present = 1; 309 return 0; 310 ··· 361 static int saa7113_init(struct budget_av *budget_av) 362 { 363 struct budget *budget = &budget_av->budget; 364 + struct saa7146_dev *saa = budget->dev; 365 const u8 *data = saa7113_tab; 366 + 367 + saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); 368 + msleep(200); 369 370 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { 371 dprintk(1, "saa7113 not found on KNC card\n"); ··· 697 return pwm; 698 } 699 700 + #define SUBID_DVBS_KNC1 0x0010 701 + #define SUBID_DVBS_KNC1_PLUS 0x0011 702 + #define SUBID_DVBS_TYPHOON 0x4f56 703 + #define SUBID_DVBS_CINERGY1200 0x1154 704 + 705 + #define SUBID_DVBC_KNC1 0x0020 706 + #define SUBID_DVBC_KNC1_PLUS 0x0021 707 + #define SUBID_DVBC_CINERGY1200 0x1156 708 + 709 + #define SUBID_DVBT_KNC1_PLUS 0x0031 710 + #define SUBID_DVBT_KNC1 0x0030 711 + #define SUBID_DVBT_CINERGY1200 0x1157 712 713 static void frontend_init(struct budget_av *budget_av) 714 { 715 + struct saa7146_dev * saa = budget_av->budget.dev; 716 + struct dvb_frontend * fe = NULL; 717 + 718 + switch (saa->pci->subsystem_device) { 719 + case SUBID_DVBS_KNC1_PLUS: 720 + case SUBID_DVBC_KNC1_PLUS: 721 + case SUBID_DVBT_KNC1_PLUS: 722 + // Enable / PowerON Frontend 723 + saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); 724 break; 725 + } 726 + 727 + switch (saa->pci->subsystem_device) { 728 + 729 + case SUBID_DVBS_KNC1: 730 + case SUBID_DVBS_KNC1_PLUS: 731 + case SUBID_DVBS_TYPHOON: 732 + fe = stv0299_attach(&typhoon_config, 733 + &budget_av->budget.i2c_adap); 734 break; 735 736 + case SUBID_DVBS_CINERGY1200: 737 + fe = stv0299_attach(&cinergy_1200s_config, 738 + &budget_av->budget.i2c_adap); 739 break; 740 741 + case SUBID_DVBC_KNC1: 742 + case SUBID_DVBC_KNC1_PLUS: 743 + fe = tda10021_attach(&philips_cu1216_config, 744 + &budget_av->budget.i2c_adap, 745 + read_pwm(budget_av)); 746 break; 747 748 + case SUBID_DVBT_KNC1: 749 + case SUBID_DVBT_KNC1_PLUS: 750 + fe = tda10046_attach(&philips_tu1216_config, 751 + &budget_av->budget.i2c_adap); 752 break; 753 754 + case SUBID_DVBC_CINERGY1200: 755 + fe = tda10021_attach(&philips_cu1216_config, 756 + &budget_av->budget.i2c_adap, 757 + read_pwm(budget_av)); 758 break; 759 760 + case SUBID_DVBT_CINERGY1200: 761 + fe = tda10046_attach(&philips_tu1216_config, 762 + &budget_av->budget.i2c_adap); 763 break; 764 } 765 766 + if (fe == NULL) { 767 + printk(KERN_ERR "budget-av: A frontend driver was not found " 768 + "for device %04x/%04x subsystem %04x/%04x\n", 769 + saa->pci->vendor, 770 + saa->pci->device, 771 + saa->pci->subsystem_vendor, 772 + saa->pci->subsystem_device); 773 + return; 774 + } 775 + 776 + budget_av->budget.dvb_frontend = fe; 777 + 778 + if (dvb_register_frontend(&budget_av->budget.dvb_adapter, 779 + budget_av->budget.dvb_frontend)) { 780 + printk(KERN_ERR "budget-av: Frontend registration failed!\n"); 781 + if (budget_av->budget.dvb_frontend->ops->release) 782 + budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); 783 + budget_av->budget.dvb_frontend = NULL; 784 } 785 } 786 ··· 829 830 memset(budget_av, 0, sizeof(struct budget_av)); 831 832 + budget_av->has_saa7113 = 0; 833 budget_av->budget.ci_present = 0; 834 835 dev->ext_priv = budget_av; ··· 843 saa7146_write(dev, DD1_INIT, 0x07000600); 844 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); 845 846 + if (saa7113_init(budget_av) == 0) { 847 budget_av->has_saa7113 = 1; 848 849 if (0 != saa7146_vv_init(dev, &vv_data)) { ··· 867 868 saa7113_setinput(budget_av, 0); 869 } else { 870 + ciintf_init(budget_av); 871 } 872 873 /* fixme: find some sane values here... */ ··· 877 878 mac = budget_av->budget.dvb_adapter.proposed_mac; 879 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { 880 + printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n", 881 budget_av->budget.dvb_adapter.num); 882 memset(mac, 0, 6); 883 } else { 884 + printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", 885 budget_av->budget.dvb_adapter.num, 886 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 887 } 888 889 budget_av->budget.dvb_adapter.priv = budget_av; 890 frontend_init(budget_av); 891 892 return 0; 893 } ··· 1024 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); 1025 MODULE_DESCRIPTION("driver for the SAA7146 based so-called " 1026 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");