/* si4713_s_ctrl - set the value of a control */ static int si4713_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { struct si4713_device *sdev = to_si4713_device(sd); int rval = 0; if (!sdev) return -ENODEV; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: if (ctrl->value) { rval = si4713_set_mute(sdev, ctrl->value); if (rval < 0) goto exit; rval = si4713_set_power_state(sdev, POWER_DOWN); } else { rval = si4713_set_power_state(sdev, POWER_UP); if (rval < 0) goto exit; rval = si4713_setup(sdev); if (rval < 0) goto exit; rval = si4713_set_mute(sdev, ctrl->value); } break; } exit: return rval; }
static int si4713_initialize(struct si4713_device *sdev) { int rval; rval = si4713_set_power_state(sdev, POWER_ON); if (rval < 0) goto exit; rval = si4713_checkrev(sdev); if (rval < 0) goto exit; rval = si4713_set_power_state(sdev, POWER_OFF); if (rval < 0) goto exit; mutex_lock(&sdev->mutex); sdev->rds_info.pi = DEFAULT_RDS_PI; sdev->rds_info.pty = DEFAULT_RDS_PTY; sdev->rds_info.deviation = DEFAULT_RDS_DEVIATION; strlcpy(sdev->rds_info.ps_name, DEFAULT_RDS_PS_NAME, MAX_RDS_PS_NAME); strlcpy(sdev->rds_info.radio_text, DEFAULT_RDS_RADIO_TEXT, MAX_RDS_RADIO_TEXT); sdev->rds_info.enabled = 1; sdev->limiter_info.release_time = DEFAULT_LIMITER_RTIME; sdev->limiter_info.deviation = DEFAULT_LIMITER_DEV; sdev->limiter_info.enabled = 1; sdev->pilot_info.deviation = DEFAULT_PILOT_DEVIATION; sdev->pilot_info.frequency = DEFAULT_PILOT_FREQUENCY; sdev->pilot_info.enabled = 1; sdev->acomp_info.release_time = DEFAULT_ACOMP_RTIME; sdev->acomp_info.attack_time = DEFAULT_ACOMP_ATIME; sdev->acomp_info.threshold = DEFAULT_ACOMP_THRESHOLD; sdev->acomp_info.gain = DEFAULT_ACOMP_GAIN; sdev->acomp_info.enabled = 1; sdev->frequency = DEFAULT_FREQUENCY; sdev->preemphasis = DEFAULT_PREEMPHASIS; sdev->mute = DEFAULT_MUTE; sdev->power_level = DEFAULT_POWER_LEVEL; sdev->antenna_capacitor = 0; sdev->stereo = 1; sdev->tune_rnl = DEFAULT_TUNE_RNL; mutex_unlock(&sdev->mutex); exit: return rval; }
/* * si4713_initialize - Sets the device up with default configuration. * @sdev: si4713_device structure for the device we are communicating */ static int si4713_initialize(struct si4713_device *sdev) { int rval; rval = si4713_set_power_state(sdev, POWER_ON); if (rval < 0) return rval; rval = si4713_checkrev(sdev); if (rval < 0) return rval; rval = si4713_set_power_state(sdev, POWER_OFF); if (rval < 0) return rval; sdev->frequency = DEFAULT_FREQUENCY; sdev->stereo = 1; sdev->tune_rnl = DEFAULT_TUNE_RNL; return 0; }
/* si4713_remove - remove the device */ static int si4713_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct si4713_device *sdev = to_si4713_device(sd); platform_device_unregister(sdev->pd); if (sdev->power_state) si4713_set_power_state(sdev, POWER_DOWN); v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); return 0; }
/* si4713_remove - remove the device */ static int si4713_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct si4713_device *sdev = to_si4713_device(sd); if (sdev->power_state) si4713_set_power_state(sdev, POWER_DOWN); if (client->irq > 0) free_irq(client->irq, sdev); v4l2_device_unregister_subdev(sd); kfree(sdev); return 0; }
/* si4713_remove - remove the device */ static int si4713_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct si4713_device *sdev = to_si4713_device(sd); if (sdev->power_state) si4713_set_power_state(sdev, POWER_DOWN); if (client->irq > 0) free_irq(client->irq, sdev); v4l2_device_unregister_subdev(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); if (gpio_is_valid(sdev->gpio_reset)) gpio_free(sdev->gpio_reset); kfree(sdev); return 0; }
/* si4713_s_ctrl - set the value of a control */ static int si4713_s_ctrl(struct v4l2_ctrl *ctrl) { struct si4713_device *sdev = container_of(ctrl->handler, struct si4713_device, ctrl_handler); u32 val = 0; s32 bit = 0, mask = 0; u16 property = 0; int mul = 0; unsigned long *table = NULL; int size = 0; bool force = false; int c; int ret = 0; if (ctrl->id != V4L2_CID_AUDIO_MUTE) return -EINVAL; if (ctrl->is_new) { if (ctrl->val) { ret = si4713_set_mute(sdev, ctrl->val); if (!ret) ret = si4713_set_power_state(sdev, POWER_DOWN); return ret; } ret = si4713_set_power_state(sdev, POWER_UP); if (!ret) ret = si4713_set_mute(sdev, ctrl->val); if (!ret) ret = si4713_setup(sdev); if (ret) return ret; force = true; } if (!sdev->power_state) return 0; for (c = 1; !ret && c < ctrl->ncontrols; c++) { ctrl = ctrl->cluster[c]; if (!force && !ctrl->is_new) continue; switch (ctrl->id) { case V4L2_CID_RDS_TX_PS_NAME: ret = si4713_set_rds_ps_name(sdev, ctrl->string); break; case V4L2_CID_RDS_TX_RADIO_TEXT: ret = si4713_set_rds_radio_text(sdev, ctrl->string); break; case V4L2_CID_TUNE_ANTENNA_CAPACITOR: /* don't handle this control if we force setting all * controls since in that case it will be handled by * V4L2_CID_TUNE_POWER_LEVEL. */ if (force) break; /* fall through */ case V4L2_CID_TUNE_POWER_LEVEL: ret = si4713_tx_tune_power(sdev, sdev->tune_pwr_level->val, sdev->tune_ant_cap->val); if (!ret) { /* Make sure we don't set this twice */ sdev->tune_ant_cap->is_new = false; sdev->tune_pwr_level->is_new = false; } break; default: ret = si4713_choose_econtrol_action(sdev, ctrl->id, &bit, &mask, &property, &mul, &table, &size); if (ret < 0) break; val = ctrl->val; if (mul) { val = val / mul; } else if (table) { ret = usecs_to_dev(val, table, size); if (ret < 0) break; val = ret; ret = 0; } if (mask) { ret = si4713_read_property(sdev, property, &val); if (ret < 0) break; val = set_bits(val, ctrl->val, bit, mask); } ret = si4713_write_property(sdev, property, val); if (ret < 0) break; if (mask) val = ctrl->val; break; } } return ret; }