static int tda9840_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; /* let's see whether this adapter can support what we need */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -EIO; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL); if (sd == NULL) return -ENOMEM; v4l2_i2c_subdev_init(sd, client, &tda9840_ops); /* set initial values for level & stereo - adjustment, mode */ tda9840_write(sd, LEVEL_ADJUST, 0); tda9840_write(sd, STEREO_ADJUST, 0); tda9840_write(sd, SWITCH, TDA9840_SET_STEREO); return 0; }
static int tda9840_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *t) { int stat = tda9840_status(sd); int byte; if (t->index) return -EINVAL; stat = stat < 0 ? 0 : stat; if (stat == 0 || stat == 0x60) /* mono input */ byte = TDA9840_SET_MONO; else if (stat == 0x40) /* stereo input */ byte = (t->audmode == V4L2_TUNER_MODE_MONO) ? TDA9840_SET_MONO : TDA9840_SET_STEREO; else { /* bilingual */ switch (t->audmode) { case V4L2_TUNER_MODE_LANG1_LANG2: byte = TDA9840_SET_BOTH; break; case V4L2_TUNER_MODE_LANG2: byte = TDA9840_SET_LANG2; break; default: byte = TDA9840_SET_LANG1; break; } } v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte); tda9840_write(sd, SWITCH, byte); return 0; }
static int tda9840_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct v4l2_subdev *sd; int result; int byte; /* let's see whether this adapter can support what we need */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return -EIO; v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); if (sd == NULL) return -ENOMEM; v4l2_i2c_subdev_init(sd, client, &tda9840_ops); /* set initial values for level & stereo - adjustment, mode */ byte = 0; result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte); result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte); tda9840_write(sd, SWITCH, TDA9840_SET_STEREO); if (result) { v4l2_dbg(1, debug, sd, "could not initialize tda9840\n"); kfree(sd); return -ENODEV; } return 0; }
static int tda9840_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t) { int byte; if (t->index) return -EINVAL; switch (t->audmode) { case V4L2_TUNER_MODE_STEREO: byte = TDA9840_SET_STEREO; break; case V4L2_TUNER_MODE_LANG1_LANG2: byte = TDA9840_SET_BOTH; break; case V4L2_TUNER_MODE_LANG1: byte = TDA9840_SET_LANG1; break; case V4L2_TUNER_MODE_LANG2: byte = TDA9840_SET_LANG2; break; default: byte = TDA9840_SET_MONO; break; } v4l2_dbg(1, debug, sd, "TDA9840_SWITCH: 0x%02x\n", byte); tda9840_write(sd, SWITCH, byte); return 0; }
static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg) { int byte; switch (cmd) { case TDA9840_LEVEL_ADJUST: byte = *(int *)arg; v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -20) return -EINVAL; /* calculate actual value to set, see specs, page 18 */ byte /= 5; if (0 < byte) byte += 0x8; else byte = -byte; tda9840_write(sd, LEVEL_ADJUST, byte); break; case TDA9840_STEREO_ADJUST: byte = *(int *)arg; v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte); /* check for correct range */ if (byte > 25 || byte < -24) return -EINVAL; /* calculate actual value to set */ byte /= 5; if (0 < byte) byte += 0x20; else byte = -byte; tda9840_write(sd, STEREO_ADJUST, byte); break; default: return -ENOIOCTLCMD; } return 0; }