unsigned int type; /* chip type id */
unsigned int config;
int (*tuner_callback) (void *dev, int command, int arg);
+ const char *name;
};
/* standard i2c insmod options */
tuner_warn("Support for tuners in i2c address range 0x64 thru 0x6f\n");
tuner_warn("will soon be dropped. This message indicates that your\n");
tuner_warn("hardware has a %s tuner at i2c address 0x%02x.\n",
- t->i2c->name, t->i2c->addr);
+ t->name, t->i2c->addr);
tuner_warn("To ensure continued support for your device, please\n");
tuner_warn("send a copy of this message, along with full dmesg\n");
tuner_warn("output to v4l-dvb-maintainer@linuxtv.org\n");
tuner_warn("Please use subject line: \"obsolete tuner i2c address.\"\n");
tuner_warn("driver: %s, addr: 0x%02x, type: %d (%s)\n",
- t->i2c->adapter->name, t->i2c->addr, t->type, t->i2c->name);
+ t->i2c->adapter->name, t->i2c->addr, t->type, t->name);
tuner_warn("====================== WARNING! ======================\n");
}
-static void attach_tda829x(struct tuner *t)
-{
- struct tda829x_config cfg = {
- .lna_cfg = t->config,
- .tuner_callback = t->tuner_callback,
- };
- dvb_attach(tda829x_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
-}
-
static struct xc5000_config xc5000_cfg;
static void set_type(struct i2c_client *c, unsigned int type,
switch (t->type) {
case TUNER_MT2032:
- dvb_attach(microtune_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr);
+ if (!dvb_attach(microtune_attach,
+ &t->fe, t->i2c->adapter, t->i2c->addr))
+ goto attach_failed;
break;
case TUNER_PHILIPS_TDA8290:
{
- attach_tda829x(t);
+ struct tda829x_config cfg = {
+ .lna_cfg = t->config,
+ .tuner_callback = t->tuner_callback,
+ };
+ if (!dvb_attach(tda829x_attach, &t->fe, t->i2c->adapter,
+ t->i2c->addr, &cfg))
+ goto attach_failed;
break;
}
case TUNER_TEA5767:
break;
}
case TUNER_TDA9887:
- dvb_attach(tda9887_attach,
- &t->fe, t->i2c->adapter, t->i2c->addr);
+ if (!dvb_attach(tda9887_attach,
+ &t->fe, t->i2c->adapter, t->i2c->addr))
+ goto attach_failed;
break;
case TUNER_XC5000:
{
xc5000_cfg.i2c_address = t->i2c->addr;
xc5000_cfg.if_khz = 5380;
- xc5000_cfg.priv = c->adapter->algo_data;
xc5000_cfg.tuner_callback = t->tuner_callback;
if (!dvb_attach(xc5000_attach,
- &t->fe, t->i2c->adapter, &xc5000_cfg))
+ &t->fe, t->i2c->adapter, &xc5000_cfg,
+ c->adapter->algo_data))
goto attach_failed;
xc_tuner_ops = &t->fe.ops.tuner_ops;
if ((NULL == analog_ops->set_params) &&
(fe_tuner_ops->set_analog_params)) {
- strlcpy(t->i2c->name, fe_tuner_ops->info.name,
- sizeof(t->i2c->name));
+ t->name = fe_tuner_ops->info.name;
t->fe.analog_demod_priv = t;
memcpy(analog_ops, &tuner_core_ops,
sizeof(struct analog_demod_ops));
} else {
- strlcpy(t->i2c->name, analog_ops->info.name,
- sizeof(t->i2c->name));
+ t->name = analog_ops->info.name;
}
- tuner_dbg("type set to %s\n", t->i2c->name);
+ tuner_dbg("type set to %s\n", t->name);
if (t->mode_mask == T_UNINITIALIZED)
t->mode_mask = new_mode_mask;
static inline int check_mode(struct tuner *t, char *cmd)
{
if ((1 << t->mode & t->mode_mask) == 0) {
- return EINVAL;
+ return -EINVAL;
}
switch (t->mode) {
t->mode = mode;
- if (check_mode(t, cmd) == EINVAL) {
+ if (check_mode(t, cmd) == -EINVAL) {
t->mode = T_STANDBY;
if (analog_ops->standby)
analog_ops->standby(&t->fe);
- return EINVAL;
+ return -EINVAL;
}
return 0;
}
break;
case AUDC_SET_RADIO:
if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
- == EINVAL)
+ == -EINVAL)
return 0;
if (t->radio_freq)
set_freq(client, t->radio_freq);
break;
case TUNER_SET_STANDBY:
- if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
+ if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
return 0;
t->mode = T_STANDBY;
if (analog_ops->standby)
break;
#ifdef CONFIG_VIDEO_ALLOW_V4L1
case VIDIOCSAUDIO:
- if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
+ if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
return 0;
- if (check_v4l2(t) == EINVAL)
+ if (check_v4l2(t) == -EINVAL)
return 0;
/* Should be implemented, since bttv calls it */
};
struct video_channel *vc = arg;
- if (check_v4l2(t) == EINVAL)
+ if (check_v4l2(t) == -EINVAL)
return 0;
- if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
+ if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL)
return 0;
if (vc->norm < ARRAY_SIZE(map))
{
unsigned long *v = arg;
- if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
+ if (check_mode(t, "VIDIOCSFREQ") == -EINVAL)
return 0;
- if (check_v4l2(t) == EINVAL)
+ if (check_v4l2(t) == -EINVAL)
return 0;
set_freq(client, *v);
{
struct video_tuner *vt = arg;
- if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
+ if (check_mode(t, "VIDIOCGTUNER") == -EINVAL)
return 0;
- if (check_v4l2(t) == EINVAL)
+ if (check_v4l2(t) == -EINVAL)
return 0;
if (V4L2_TUNER_RADIO == t->mode) {
{
struct video_audio *va = arg;
- if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
+ if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL)
return 0;
- if (check_v4l2(t) == EINVAL)
+ if (check_v4l2(t) == -EINVAL)
return 0;
if (V4L2_TUNER_RADIO == t->mode) {
v4l2_std_id *id = arg;
if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
- == EINVAL)
+ == -EINVAL)
return 0;
switch_v4l2();
struct v4l2_frequency *f = arg;
if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
- == EINVAL)
+ == -EINVAL)
return 0;
switch_v4l2();
set_freq(client,f->frequency);
{
struct v4l2_frequency *f = arg;
- if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
+ if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
return 0;
switch_v4l2();
f->type = t->mode;
{
struct v4l2_tuner *tuner = arg;
- if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
+ if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
return 0;
switch_v4l2();
{
struct v4l2_tuner *tuner = arg;
- if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
+ if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
return 0;
switch_v4l2();
if (NULL == t)
return -ENOMEM;
t->i2c = client;
- strlcpy(client->name, "(tuner unset)", sizeof(client->name));
+ t->name = "(tuner unset)";
i2c_set_clientdata(client, t);
t->type = UNSET;
t->audmode = V4L2_TUNER_MODE_STEREO;
/* If chip is not tda8290, don't register.
since it can be tda9887*/
if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
- t->i2c->addr) == 0) {
+ t->i2c->addr) >= 0) {
tuner_dbg("tda829x detected\n");
} else {
/* Default is being tda9887 */
case 0x60:
if (tuner_symbol_probe(tea5767_autodetection,
t->i2c->adapter, t->i2c->addr)
- != EINVAL) {
+ >= 0) {
t->type = TUNER_TEA5767;
t->mode_mask = T_RADIO;
t->mode = T_STANDBY;
/* ----------------------------------------------------------------------- */
+/* This driver supports many devices and the idea is to let the driver
+ detect which device is present. So rather than listing all supported
+ devices here, we pretend to support a single, fake device type. */
+static const struct i2c_device_id tuner_id[] = {
+ { "tuner", }, /* autodetect */
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tuner_id);
+
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tuner",
.driverid = I2C_DRIVERID_TUNER,
.suspend = tuner_suspend,
.resume = tuner_resume,
.legacy_probe = tuner_legacy_probe,
+ .id_table = tuner_id,
};