static int em28xx_gpio_write(enum v4l2_tuner_type mode, void *priv, int ptr){ struct em28xx *dev=(struct em28xx*)priv; int ret; char gpio[6]; dev->mode=mode; switch(dev->model){ case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: gpio[0]=0x2d; gpio[1]=0x3d; gpio[2]=0x2e; gpio[3]=0x3e; gpio[4]=0x08; gpio[5]=0x0c; break; case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: gpio[0]=0x2d; gpio[1]=0x3d; gpio[2]=0x2e; gpio[3]=0x3e; gpio[4]=0x00; gpio[5]=0x00; break; case EM2880_BOARD_TERRATEC_HYBRID_XS: case EM2870_BOARD_TERRATEC_XS: case EM2880_BOARD_KWORLD_DVB_310U: case EM2870_BOARD_KWORLD_350U: gpio[0]=0x6d; gpio[1]=0x7d; gpio[2]=0x6e; gpio[3]=0x7e; gpio[4]=0x00; gpio[5]=0x00; break; case EM2880_BOARD_MSI_DIGIVOX_AD: gpio[0]=0x69; gpio[1]=0x79; gpio[2]=0x6a; gpio[3]=0x7a; gpio[4]=0x00; gpio[5]=0x00; break; case EM2881_BOARD_DNT_DA2_HYBRID: case EM2881_BOARD_PINNACLE_HYBRID_PRO: gpio[0]=0x6d; gpio[1]=0x7d; gpio[2]=0x6e; gpio[3]=0x7e; gpio[4]=0x08; gpio[5]=0x0c; break; case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: case EM2880_BOARD_TERRATEC_HYBRID_XS_FR_2: gpio[0]=0x6d; gpio[1]=0x7d; gpio[2]=0x6e; gpio[3]=0x7e; gpio[4]=0x00; gpio[5]=0x00; break; case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: gpio[0]=0x2d; gpio[1]=0x3d; gpio[2]=0x2e; gpio[3]=0x3e; gpio[4]=0x00; gpio[5]=0x00; break; default: return -EINVAL; } /* not sure about the delays here we have no specs about this */ if(ptr==0 || ptr==1){ switch(mode){ case V4L2_TUNER_ANALOG_TV: if(ptr==0){ dev->em28xx_write_regs_req(dev,0x00,0x48,"\x00",1); dev->em28xx_write_regs_req(dev,0x00,0x12,"\x67",1); if(gpio[4]){ ret = dev->em28xx_write_regs(dev,0x04,&gpio[4],1); msleep(140); } } msleep(6); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[0], 1); msleep(10); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[1], 1); msleep(5); break; case V4L2_TUNER_DVBT_TV: case V4L2_TUNER_DVBC_TV: case V4L2_TUNER_ATSC_TV: if(ptr==0){ dev->em28xx_write_regs_req(dev,0x00,0x48,"\x00",1); dev->em28xx_write_regs_req(dev,0x00,0x12,"\x67",1); if(gpio[4]){ ret = dev->em28xx_write_regs(dev,0x04,&gpio[4],1); msleep(140); } } msleep(6); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[0], 1); msleep(10); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[1], 1); msleep(5); break; case V4L2_TUNER_DVBT_TV: case V4L2_TUNER_DVBC_TV: case V4L2_TUNER_ATSC_TV: if(ptr==0){ dev->em28xx_write_regs_req(dev,0x00,0x48,"\x00",1); dev->em28xx_write_regs_req(dev,0x00,0x12,"\x37",1); if(gpio[5]){ ret = dev->em28xx_write_regs(dev,0x04,&gpio[5],1); msleep(140); } } msleep(6); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[2], 1); msleep(6); ret = dev->em28xx_write_regs(dev, 0x08, &gpio[3], 1); msleep(6); /* thanks for no specs here grr! -- Markus */ if (ptr==0 && (dev->model==EM2880_BOARD_TERRATEC_HYBRID_XS_FR || dev->model==EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950)){ ret = dev->em28xx_write_regs(dev,0x04,"\x04",1); msleep(10); ret = dev->em28xx_write_regs(dev,0x04,"\x0c",1); msleep(10); } break; default: printk("em28xx-i2c.c: tuner mode unsupported!\n"); return -EINVAL; } } else if(dev->dvb_dev && ptr==2 && (mode==V4L2_TUNER_DVBC_TV || mode==V4L2_TUNER_DVBT_TV|| mode==V4L2_TUNER_ATSC_TV)){ if (dev->dvb_dev->demod_init) dev->dvb_dev->demod_init(dev->dvb_dev->frontend); } return 0; }