/* I2C probe: check if the device exists and register with v4l if it is */ static int __devinit tea5764_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tea5764_device *radio; struct tea5764_regs *r; int ret; PDEBUG("probe"); radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); if (!radio) return -ENOMEM; mutex_init(&radio->mutex); radio->i2c_client = client; ret = tea5764_i2c_read(radio); if (ret) goto errfr; r = &radio->regs; PDEBUG("chipid = %04X, manid = %04X", r->chipid, r->manid); if (r->chipid != TEA5764_CHIPID || (r->manid & 0x0fff) != TEA5764_MANID) { PWARN("This chip is not a TEA5764!"); ret = -EINVAL; goto errfr; } radio->videodev = video_device_alloc(); if (!(radio->videodev)) { ret = -ENOMEM; goto errfr; } memcpy(radio->videodev, &tea5764_radio_template, sizeof(tea5764_radio_template)); i2c_set_clientdata(client, radio); video_set_drvdata(radio->videodev, radio); ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); if (ret < 0) { PWARN("Could not register video device!"); goto errrel; } /* initialize and power off the chip */ tea5764_i2c_read(radio); tea5764_set_audout_mode(radio, V4L2_TUNER_MODE_STEREO); tea5764_mute(radio, 1); tea5764_power_down(radio); PINFO("registered."); return 0; errrel: video_device_release(radio->videodev); errfr: kfree(radio); return ret; }
static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { struct tea5764_device *radio = video_drvdata(file); struct tea5764_regs *r = &radio->regs; if (v->index > 0) return -EINVAL; memset(v, 0, sizeof(*v)); strcpy(v->name, "FM"); v->type = V4L2_TUNER_RADIO; tea5764_i2c_read(radio); v->rangelow = FREQ_MIN * FREQ_MUL; v->rangehigh = FREQ_MAX * FREQ_MUL; v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; if (r->tunchk & TEA5764_TUNCHK_STEREO) v->rxsubchans = V4L2_TUNER_SUB_STEREO; else v->rxsubchans = V4L2_TUNER_SUB_MONO; v->audmode = tea5764_get_audout_mode(radio); v->signal = TEA5764_TUNCHK_LEVEL(r->tunchk) * 0xffff / 0xf; v->afc = TEA5764_TUNCHK_IFCNT(r->tunchk); return 0; }
static int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctrl) { struct tea5764_device *radio = video_drvdata(file); switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: tea5764_i2c_read(radio); ctrl->value = tea5764_is_muted(radio) ? 1 : 0; return 0; } return -EINVAL; }
static int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct tea5764_device *radio = video_drvdata(file); struct tea5764_regs *r = &radio->regs; tea5764_i2c_read(radio); memset(f, 0, sizeof(f)); f->type = V4L2_TUNER_RADIO; if (r->tnctrl & TEA5764_TNCTRL_PUPD0) f->frequency = (tea5764_get_freq(radio) * 2) / 125; else f->frequency = 0; return 0; }