With this patch I try again to add initial support for HVR930C. Tested only DVB-T, since in Italy Analog service is stopped. Actually "scan -a0 -f1", find only about 50 channel while 400 should be available. Signed-off-by: Eddi De Pieri <eddi@xxxxxxxxxxx> Regards Eddi
diff -u -N -r linux/drivers/media/common/tuners/xc5000.c linux.patched/drivers/media/common/tuners/xc5000.c --- linux/drivers/media/common/tuners/xc5000.c 2011-03-31 23:56:49.000000000 +0200 +++ linux.patched/drivers/media/common/tuners/xc5000.c 2011-11-19 15:37:20.516138695 +0100 @@ -977,6 +977,13 @@ return 0; } +static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct xc5000_priv *priv = fe->tuner_priv; + *frequency = priv->if_khz * 1000; + return 0; +} + static int xc5000_get_status(struct dvb_frontend *fe, u32 *status) { struct xc5000_priv *priv = fe->tuner_priv; @@ -996,6 +1003,8 @@ struct xc5000_priv *priv = fe->tuner_priv; int ret = 0; + mutex_lock(&xc5000_list_mutex); + if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) { ret = xc5000_fwupload(fe); if (ret != XC_RESULT_SUCCESS) @@ -1015,6 +1024,8 @@ /* Default to "CABLE" mode */ ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE); + mutex_unlock(&xc5000_list_mutex); + return ret; } @@ -1109,6 +1120,7 @@ .set_analog_params = xc5000_set_analog_params, .get_frequency = xc5000_get_frequency, .get_bandwidth = xc5000_get_bandwidth, + .get_if_frequency = xc5000_get_if_frequency, .get_status = xc5000_get_status }; diff -u -N -r linux/drivers/media/dvb/frontends/drxk.h linux.patched/drivers/media/dvb/frontends/drxk.h --- linux/drivers/media/dvb/frontends/drxk.h 2011-07-11 20:09:53.000000000 +0200 +++ linux.patched/drivers/media/dvb/frontends/drxk.h 2011-11-19 15:20:32.119137206 +0100 @@ -25,6 +25,8 @@ bool antenna_dvbt; u16 antenna_gpio; + + int chunk_size; const char *microcode_name; }; diff -u -N -r linux/drivers/media/dvb/frontends/drxk_hard.c linux.patched/drivers/media/dvb/frontends/drxk_hard.c --- linux/drivers/media/dvb/frontends/drxk_hard.c 2011-09-04 05:45:09.000000000 +0200 +++ linux.patched/drivers/media/dvb/frontends/drxk_hard.c 2011-11-19 15:20:32.123137210 +0100 @@ -681,7 +681,8 @@ state->m_hasOOB = false; state->m_hasAudio = false; - state->m_ChunkSize = 124; + if (!state->m_ChunkSize) + state->m_ChunkSize = 124; state->m_oscClockFreq = 0; state->m_smartAntInverted = false; @@ -6423,6 +6424,7 @@ state->no_i2c_bridge = config->no_i2c_bridge; state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; + state->m_ChunkSize = config->chunk_size; /* NOTE: as more UIO bits will be used, add them to the mask */ state->UIO_mask = config->antenna_gpio; diff -u -N -r linux/drivers/media/video/em28xx/em28xx-cards.c linux.patched/drivers/media/video/em28xx/em28xx-cards.c --- linux/drivers/media/video/em28xx/em28xx-cards.c 2011-11-04 05:45:40.000000000 +0100 +++ linux.patched/drivers/media/video/em28xx/em28xx-cards.c 2011-11-19 15:21:18.247365922 +0100 @@ -336,6 +336,24 @@ { -1, -1, -1, -1}, }; +static struct em28xx_reg_seq hauppauge_930c_gpio[] = { +// xc5000 reset + {EM2874_R80_GPIO, 0x6f, 0xff, 10}, + {EM2874_R80_GPIO, 0x4f, 0xff, 10}, + {EM2874_R80_GPIO, 0x6f, 0xff, 10}, + {EM2874_R80_GPIO, 0x4f, 0xff, 10}, + { -1, -1, -1, -1}, +}; + +#if 0 +static struct em28xx_reg_seq hauppauge_930c_digital[] = { + {EM2874_R80_GPIO, 0xf6, 0xff, 10}, + {EM2874_R80_GPIO, 0xe6, 0xff, 100}, + {EM2874_R80_GPIO, 0xa6, 0xff, 10}, + { -1, -1, -1, -1}, +}; +#endif + /* * Board definitions */ @@ -892,6 +910,19 @@ EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, }, + [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { + .name = "Hauppauge WinTV HVR 930C", + .has_dvb = 1, +//#if 0 +// .tuner_type = TUNER_XC5000, +// .tuner_addr = 0x41, +// .dvb_gpio = hauppauge_930c_digital, /* FIXME: probably wrong */ + .tuner_gpio = hauppauge_930c_gpio, +//#endif + .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | + EM28XX_I2C_CLK_WAIT_ENABLE | + EM28XX_I2C_FREQ_400_KHZ, + }, [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { .name = "Hauppauge WinTV HVR 900", .tda9887_conf = TDA9887_PRESENT, @@ -1975,6 +2006,8 @@ .driver_info = EM28174_BOARD_PCTV_290E }, { USB_DEVICE(0x2013, 0x024c), .driver_info = EM28174_BOARD_PCTV_460E }, + { USB_DEVICE(0x2040, 0x1605), + .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, { }, }; MODULE_DEVICE_TABLE(usb, em28xx_id_table); @@ -2028,10 +2061,10 @@ int rc = 0; struct em28xx *dev = ptr; - if (dev->tuner_type != TUNER_XC2028) + if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) return 0; - if (command != XC2028_TUNER_RESET) + if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) return 0; rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); diff -u -N -r linux/drivers/media/video/em28xx/em28xx-dvb.c linux.patched/drivers/media/video/em28xx/em28xx-dvb.c --- linux/drivers/media/video/em28xx/em28xx-dvb.c 2011-09-22 05:45:23.000000000 +0200 +++ linux.patched/drivers/media/video/em28xx/em28xx-dvb.c 2011-11-19 15:20:32.127137205 +0100 @@ -1,4 +1,4 @@ -/* +/*6 DVB device driver for em28xx (c) 2008-2011 Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxx> @@ -316,6 +316,14 @@ .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; +struct drxk_config hauppauge_930c_drxk = { + .adr = 0x29, + .single_master = 1, + .no_i2c_bridge = 1, + .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", + .chunk_size = 56, +}; + static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct em28xx_dvb *dvb = fe->sec_priv; @@ -334,6 +342,91 @@ return status; } +static void hauppauge_hvr930c_init(struct em28xx *dev) +{ + int i; + + + struct em28xx_reg_seq hauppauge_hvr930c_init[] = { + {EM2874_R80_GPIO, 0xff, 0xff, 101}, //11111111 +// {0xd , 0xff, 0xff, 101}, //11111111 + {EM2874_R80_GPIO, 0xfb, 0xff, 50}, //11111011 init bit 3 + {EM2874_R80_GPIO, 0xff, 0xff, 184}, //11111111 + { -1, -1, -1, -1}, + }; + struct em28xx_reg_seq hauppauge_hvr930c_end[] = { + {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 + {EM2874_R80_GPIO, 0xaf, 0xff, 101}, //10101111 init bit 7 + {EM2874_R80_GPIO, 0xef, 0xff, 118}, //11101111 + + +//per il tuner? + {EM2874_R80_GPIO, 0xef, 0xff, 1}, //11101111 + {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 64}, //11101111 + + {EM2874_R80_GPIO, 0xcf, 0xff, 101}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 + {EM2874_R80_GPIO, 0xcf, 0xff, 11}, //11001111 init bit 6 + {EM2874_R80_GPIO, 0xef, 0xff, 101}, //11101111 + +// {EM2874_R80_GPIO, 0x6f, 0xff, 10}, //01101111 +// {EM2874_R80_GPIO, 0x6d, 0xff, 100}, //01101101 init bit 2 + { -1, -1, -1, -1}, + }; + + struct em28xx_reg_seq hauppauge_hvr930c_end2[] = { +// {EM2874_R80_GPIO, 0x6f, 0xff, 124}, //01101111 +// {EM2874_R80_GPIO, 0x4f, 0xff, 11}, //01001111 init bit 6 +// {EM2874_R80_GPIO, 0x6f, 0xff, 1}, //01101111 +// {EM2874_R80_GPIO, 0x4f, 0xff, 10}, //01001111 init bit 6 +// {EM2874_R80_GPIO, 0x6f, 0xff, 100}, //01101111 +// {0xd , 0x42, 0xff, 101}, //11111111 + { -1, -1, -1, -1}, + }; + struct { + unsigned char r[4]; + int len; + } regs[] = { + {{ 0x06, 0x02, 0x00, 0x31 }, 4}, + {{ 0x01, 0x02 }, 2}, + {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, + {{ 0x01, 0x00 }, 2}, + {{ 0x01, 0x00, 0xff, 0xaf }, 4}, + {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, + {{ 0x01, 0x00 }, 2}, + {{ 0x01, 0x00, 0x73, 0xaf }, 4}, + {{ 0x04, 0x00 }, 2}, + {{ 0x00, 0x04 }, 2}, + {{ 0x00, 0x04, 0x00, 0x0a }, 4}, + {{ 0x04, 0x14 }, 2}, + {{ 0x04, 0x14, 0x00, 0x00 }, 4}, + }; + + em28xx_gpio_set(dev, hauppauge_hvr930c_init); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); + msleep(10); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); + msleep(10); + + dev->i2c_client.addr = 0x82 >> 1; + + for (i = 0; i < ARRAY_SIZE(regs); i++) + i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); + em28xx_gpio_set(dev, hauppauge_hvr930c_end); + + msleep(100); + + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); + msleep(30); + + em28xx_gpio_set(dev, hauppauge_hvr930c_end2); + msleep(10); + em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); + msleep(10); + +} + static void terratec_h5_init(struct em28xx *dev) { int i; @@ -788,6 +881,47 @@ mfe_shared = 1; } break; + case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: + hauppauge_hvr930c_init(dev); + + dvb->dont_attach_fe1 = 1; + + dvb->fe[0] = dvb_attach(drxk_attach, &hauppauge_930c_drxk, &dev->i2c_adap, &dvb->fe[1]); + if (!dvb->fe[0]) { + result = -EINVAL; + goto out_free; + } + /* FIXME: do we need a pll semaphore? */ + dvb->fe[0]->sec_priv = dvb; + sema_init(&dvb->pll_mutex, 1); + dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; + dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; + dvb->fe[1]->id = 1; + + /* Attach xc5000 */ + struct xc5000_config cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.i2c_address = 0x61; + //cfg.if_khz = 4570; //FIXME + cfg.if_khz = 4000; //FIXME (should be ok) read from i2c traffic + + if (dvb->fe[0]->ops.i2c_gate_ctrl) + dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); + if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, &cfg)) { + result = -EINVAL; + goto out_free; + } + + if (dvb->fe[0]->ops.i2c_gate_ctrl) + dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); + + /* Hack - needed by drxk/tda18271c2dd */ + dvb->fe[1]->tuner_priv = dvb->fe[0]->tuner_priv; + memcpy(&dvb->fe[1]->ops.tuner_ops, + &dvb->fe[0]->ops.tuner_ops, + sizeof(dvb->fe[0]->ops.tuner_ops)); + + break; case EM2884_BOARD_TERRATEC_H5: terratec_h5_init(dev); @@ -798,7 +932,6 @@ result = -EINVAL; goto out_free; } - /* FIXME: do we need a pll semaphore? */ dvb->fe[0]->sec_priv = dvb; sema_init(&dvb->pll_mutex, 1); @@ -845,7 +978,9 @@ } /* define general-purpose callback pointer */ dvb->fe[0]->callback = em28xx_tuner_callback; - + if (dvb->fe[1]) + dvb->fe[1]->callback = em28xx_tuner_callback; + /* register everything */ result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); diff -u -N -r linux/drivers/media/video/em28xx/em28xx.h linux.patched/drivers/media/video/em28xx/em28xx.h --- linux/drivers/media/video/em28xx/em28xx.h 2011-09-27 05:45:21.000000000 +0200 +++ linux.patched/drivers/media/video/em28xx/em28xx.h 2011-11-19 15:21:47.199509466 +0100 @@ -38,6 +38,7 @@ #include <media/videobuf-dvb.h> #endif #include "tuner-xc2028.h" +#include "xc5000.h" #include "em28xx-reg.h" /* Boards supported by driver */ @@ -121,6 +122,7 @@ #define EM28174_BOARD_PCTV_290E 78 #define EM2884_BOARD_TERRATEC_H5 79 #define EM28174_BOARD_PCTV_460E 80 +#define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 /* Limits minimum and default number of buffers */ #define EM28XX_MIN_BUF 4