diff options
Diffstat (limited to 'drivers/media/i2c')
61 files changed, 4249 insertions, 5075 deletions
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 53b443be5a..59ee0ca2c9 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -216,6 +216,16 @@ config VIDEO_MT9M111 This driver supports MT9M111, MT9M112 and MT9M131 cameras from Micron/Aptina +config VIDEO_MT9M114 + tristate "onsemi MT9M114 sensor support" + select V4L2_CCI_I2C + help + This is a Video4Linux2 sensor-level driver for the onsemi MT9M114 + camera. + + To compile this driver as a module, choose M here: the + module will be called mt9m114. + config VIDEO_MT9P031 tristate "Aptina MT9P031 support" select VIDEO_APTINA_PLL diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index 80b00d39b4..f5010f80a2 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_ML86V7667) += ml86v7667.o obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o obj-$(CONFIG_VIDEO_MT9M001) += mt9m001.o obj-$(CONFIG_VIDEO_MT9M111) += mt9m111.o +obj-$(CONFIG_VIDEO_MT9M114) += mt9m114.o obj-$(CONFIG_VIDEO_MT9P031) += mt9p031.o obj-$(CONFIG_VIDEO_MT9T112) += mt9t112.o obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index 98ca417b80..5ace7b5804 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -411,43 +411,44 @@ static int adp1653_of_init(struct i2c_client *client, struct device_node *node) { struct adp1653_platform_data *pd; - struct device_node *child; + struct device_node *node_indicator = NULL; + struct device_node *node_flash; pd = devm_kzalloc(&client->dev, sizeof(*pd), GFP_KERNEL); if (!pd) return -ENOMEM; flash->platform_data = pd; - child = of_get_child_by_name(node, "flash"); - if (!child) + node_flash = of_get_child_by_name(node, "flash"); + if (!node_flash) return -EINVAL; - if (of_property_read_u32(child, "flash-timeout-us", + if (of_property_read_u32(node_flash, "flash-timeout-us", &pd->max_flash_timeout)) goto err; - if (of_property_read_u32(child, "flash-max-microamp", + if (of_property_read_u32(node_flash, "flash-max-microamp", &pd->max_flash_intensity)) goto err; pd->max_flash_intensity /= 1000; - if (of_property_read_u32(child, "led-max-microamp", + if (of_property_read_u32(node_flash, "led-max-microamp", &pd->max_torch_intensity)) goto err; pd->max_torch_intensity /= 1000; - of_node_put(child); - child = of_get_child_by_name(node, "indicator"); - if (!child) - return -EINVAL; + node_indicator = of_get_child_by_name(node, "indicator"); + if (!node_indicator) + goto err; - if (of_property_read_u32(child, "led-max-microamp", + if (of_property_read_u32(node_indicator, "led-max-microamp", &pd->max_indicator_intensity)) goto err; - of_node_put(child); + of_node_put(node_flash); + of_node_put(node_indicator); pd->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); if (IS_ERR(pd->enable_gpio)) { @@ -458,7 +459,8 @@ static int adp1653_of_init(struct i2c_client *client, return 0; err: dev_err(&client->dev, "Required property not found\n"); - of_node_put(child); + of_node_put(node_flash); + of_node_put(node_indicator); return -EINVAL; } diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index 99ba925e8e..5413447318 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -5,6 +5,7 @@ * Copyright (C) 2013 Cogent Embedded, Inc. * Copyright (C) 2013 Renesas Solutions Corp. */ +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/init.h> #include <linux/errno.h> @@ -1395,7 +1396,6 @@ out_unlock: static int adv7180_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device_node *np = client->dev.of_node; struct adv7180_state *state; struct v4l2_subdev *sd; @@ -1411,7 +1411,7 @@ static int adv7180_probe(struct i2c_client *client) state->client = client; state->field = V4L2_FIELD_ALTERNATE; - state->chip_info = (struct adv7180_chip_info *)id->driver_data; + state->chip_info = i2c_get_match_data(client); state->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown", GPIOD_OUT_HIGH); @@ -1536,22 +1536,6 @@ static void adv7180_remove(struct i2c_client *client) mutex_destroy(&state->mutex); } -static const struct i2c_device_id adv7180_id[] = { - { "adv7180", (kernel_ulong_t)&adv7180_info }, - { "adv7180cp", (kernel_ulong_t)&adv7180_info }, - { "adv7180st", (kernel_ulong_t)&adv7180_info }, - { "adv7182", (kernel_ulong_t)&adv7182_info }, - { "adv7280", (kernel_ulong_t)&adv7280_info }, - { "adv7280-m", (kernel_ulong_t)&adv7280_m_info }, - { "adv7281", (kernel_ulong_t)&adv7281_info }, - { "adv7281-m", (kernel_ulong_t)&adv7281_m_info }, - { "adv7281-ma", (kernel_ulong_t)&adv7281_ma_info }, - { "adv7282", (kernel_ulong_t)&adv7282_info }, - { "adv7282-m", (kernel_ulong_t)&adv7282_m_info }, - {}, -}; -MODULE_DEVICE_TABLE(i2c, adv7180_id); - #ifdef CONFIG_PM_SLEEP static int adv7180_suspend(struct device *dev) { @@ -1585,30 +1569,43 @@ static SIMPLE_DEV_PM_OPS(adv7180_pm_ops, adv7180_suspend, adv7180_resume); #define ADV7180_PM_OPS NULL #endif -#ifdef CONFIG_OF -static const struct of_device_id adv7180_of_id[] = { - { .compatible = "adi,adv7180", }, - { .compatible = "adi,adv7180cp", }, - { .compatible = "adi,adv7180st", }, - { .compatible = "adi,adv7182", }, - { .compatible = "adi,adv7280", }, - { .compatible = "adi,adv7280-m", }, - { .compatible = "adi,adv7281", }, - { .compatible = "adi,adv7281-m", }, - { .compatible = "adi,adv7281-ma", }, - { .compatible = "adi,adv7282", }, - { .compatible = "adi,adv7282-m", }, - { }, +static const struct i2c_device_id adv7180_id[] = { + { "adv7180", (kernel_ulong_t)&adv7180_info }, + { "adv7180cp", (kernel_ulong_t)&adv7180_info }, + { "adv7180st", (kernel_ulong_t)&adv7180_info }, + { "adv7182", (kernel_ulong_t)&adv7182_info }, + { "adv7280", (kernel_ulong_t)&adv7280_info }, + { "adv7280-m", (kernel_ulong_t)&adv7280_m_info }, + { "adv7281", (kernel_ulong_t)&adv7281_info }, + { "adv7281-m", (kernel_ulong_t)&adv7281_m_info }, + { "adv7281-ma", (kernel_ulong_t)&adv7281_ma_info }, + { "adv7282", (kernel_ulong_t)&adv7282_info }, + { "adv7282-m", (kernel_ulong_t)&adv7282_m_info }, + {} }; +MODULE_DEVICE_TABLE(i2c, adv7180_id); +static const struct of_device_id adv7180_of_id[] = { + { .compatible = "adi,adv7180", &adv7180_info }, + { .compatible = "adi,adv7180cp", &adv7180_info }, + { .compatible = "adi,adv7180st", &adv7180_info }, + { .compatible = "adi,adv7182", &adv7182_info }, + { .compatible = "adi,adv7280", &adv7280_info }, + { .compatible = "adi,adv7280-m", &adv7280_m_info }, + { .compatible = "adi,adv7281", &adv7281_info }, + { .compatible = "adi,adv7281-m", &adv7281_m_info }, + { .compatible = "adi,adv7281-ma", &adv7281_ma_info }, + { .compatible = "adi,adv7282", &adv7282_info }, + { .compatible = "adi,adv7282-m", &adv7282_m_info }, + {} +}; MODULE_DEVICE_TABLE(of, adv7180_of_id); -#endif static struct i2c_driver adv7180_driver = { .driver = { .name = KBUILD_MODNAME, .pm = ADV7180_PM_OPS, - .of_match_table = of_match_ptr(adv7180_of_id), + .of_match_table = adv7180_of_id, }, .probe = adv7180_probe, .remove = adv7180_remove, diff --git a/drivers/media/i2c/ar0521.c b/drivers/media/i2c/ar0521.c index a4e39871e8..701f36345f 100644 --- a/drivers/media/i2c/ar0521.c +++ b/drivers/media/i2c/ar0521.c @@ -133,8 +133,6 @@ struct ar0521_dev { u16 mult2; u16 vt_pix; } pll; - - bool streaming; }; static inline struct ar0521_dev *to_ar0521_dev(struct v4l2_subdev *sd) @@ -991,12 +989,9 @@ static int ar0521_s_stream(struct v4l2_subdev *sd, int enable) int ret; mutex_lock(&sensor->lock); - ret = ar0521_set_stream(sensor, enable); - if (!ret) - sensor->streaming = enable; - mutex_unlock(&sensor->lock); + return ret; } @@ -1023,28 +1018,6 @@ static const struct v4l2_subdev_ops ar0521_subdev_ops = { .pad = &ar0521_pad_ops, }; -static int __maybe_unused ar0521_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ar0521_dev *sensor = to_ar0521_dev(sd); - - if (sensor->streaming) - ar0521_set_stream(sensor, 0); - - return 0; -} - -static int __maybe_unused ar0521_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ar0521_dev *sensor = to_ar0521_dev(sd); - - if (sensor->streaming) - return ar0521_set_stream(sensor, 1); - - return 0; -} - static int ar0521_probe(struct i2c_client *client) { struct v4l2_fwnode_endpoint ep = { @@ -1183,7 +1156,6 @@ static void ar0521_remove(struct i2c_client *client) } static const struct dev_pm_ops ar0521_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ar0521_suspend, ar0521_resume) SET_RUNTIME_PM_OPS(ar0521_power_off, ar0521_power_on, NULL) }; static const struct of_device_id ar0521_dt_ids[] = { diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c index 6f8fbd82e2..12e6f0a26f 100644 --- a/drivers/media/i2c/ccs/ccs-core.c +++ b/drivers/media/i2c/ccs/ccs-core.c @@ -508,9 +508,8 @@ static void __ccs_update_exposure_limits(struct ccs_sensor *sensor) struct v4l2_ctrl *ctrl = sensor->exposure; int max; - max = sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - + sensor->vblank->val - - CCS_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN); + max = sensor->pa_src.height + sensor->vblank->val - + CCS_LIM(sensor, COARSE_INTEGRATION_TIME_MAX_MARGIN); __v4l2_ctrl_modify_range(ctrl, ctrl->minimum, max, ctrl->step, max); } @@ -728,15 +727,12 @@ static int ccs_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: rval = ccs_write(sensor, FRAME_LENGTH_LINES, - sensor->pixel_array->crop[ - CCS_PA_PAD_SRC].height - + ctrl->val); + sensor->pa_src.height + ctrl->val); break; case V4L2_CID_HBLANK: rval = ccs_write(sensor, LINE_LENGTH_PCK, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - + ctrl->val); + sensor->pa_src.width + ctrl->val); break; case V4L2_CID_TEST_PATTERN: @@ -1214,15 +1210,13 @@ static void ccs_update_blanking(struct ccs_sensor *sensor) min = max_t(int, CCS_LIM(sensor, MIN_FRAME_BLANKING_LINES), - min_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height); - max = max_fll - sensor->pixel_array->crop[CCS_PA_PAD_SRC].height; + min_fll - sensor->pa_src.height); + max = max_fll - sensor->pa_src.height; __v4l2_ctrl_modify_range(vblank, min, max, vblank->step, min); - min = max_t(int, - min_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width, - min_lbp); - max = max_llp - sensor->pixel_array->crop[CCS_PA_PAD_SRC].width; + min = max_t(int, min_llp - sensor->pa_src.width, min_lbp); + max = max_llp - sensor->pa_src.width; __v4l2_ctrl_modify_range(hblank, min, max, hblank->step, min); @@ -1246,10 +1240,8 @@ static int ccs_pll_blanking_update(struct ccs_sensor *sensor) dev_dbg(&client->dev, "real timeperframe\t100/%d\n", sensor->pll.pixel_rate_pixel_array / - ((sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - + sensor->hblank->val) * - (sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - + sensor->vblank->val) / 100)); + ((sensor->pa_src.width + sensor->hblank->val) * + (sensor->pa_src.height + sensor->vblank->val) / 100)); return 0; } @@ -1756,28 +1748,22 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) goto out; /* Analog crop start coordinates */ - rval = ccs_write(sensor, X_ADDR_START, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].left); + rval = ccs_write(sensor, X_ADDR_START, sensor->pa_src.left); if (rval < 0) goto out; - rval = ccs_write(sensor, Y_ADDR_START, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].top); + rval = ccs_write(sensor, Y_ADDR_START, sensor->pa_src.top); if (rval < 0) goto out; /* Analog crop end coordinates */ - rval = ccs_write( - sensor, X_ADDR_END, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].left - + sensor->pixel_array->crop[CCS_PA_PAD_SRC].width - 1); + rval = ccs_write(sensor, X_ADDR_END, + sensor->pa_src.left + sensor->pa_src.width - 1); if (rval < 0) goto out; - rval = ccs_write( - sensor, Y_ADDR_END, - sensor->pixel_array->crop[CCS_PA_PAD_SRC].top - + sensor->pixel_array->crop[CCS_PA_PAD_SRC].height - 1); + rval = ccs_write(sensor, Y_ADDR_END, + sensor->pa_src.top + sensor->pa_src.height - 1); if (rval < 0) goto out; @@ -1789,27 +1775,23 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) /* Digital crop */ if (CCS_LIM(sensor, DIGITAL_CROP_CAPABILITY) == CCS_DIGITAL_CROP_CAPABILITY_INPUT_CROP) { - rval = ccs_write( - sensor, DIGITAL_CROP_X_OFFSET, - sensor->scaler->crop[CCS_PAD_SINK].left); + rval = ccs_write(sensor, DIGITAL_CROP_X_OFFSET, + sensor->scaler_sink.left); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_Y_OFFSET, - sensor->scaler->crop[CCS_PAD_SINK].top); + rval = ccs_write(sensor, DIGITAL_CROP_Y_OFFSET, + sensor->scaler_sink.top); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_IMAGE_WIDTH, - sensor->scaler->crop[CCS_PAD_SINK].width); + rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_WIDTH, + sensor->scaler_sink.width); if (rval < 0) goto out; - rval = ccs_write( - sensor, DIGITAL_CROP_IMAGE_HEIGHT, - sensor->scaler->crop[CCS_PAD_SINK].height); + rval = ccs_write(sensor, DIGITAL_CROP_IMAGE_HEIGHT, + sensor->scaler_sink.height); if (rval < 0) goto out; } @@ -1827,12 +1809,10 @@ static int ccs_start_streaming(struct ccs_sensor *sensor) } /* Output size from sensor */ - rval = ccs_write(sensor, X_OUTPUT_SIZE, - sensor->src->crop[CCS_PAD_SRC].width); + rval = ccs_write(sensor, X_OUTPUT_SIZE, sensor->src_src.width); if (rval < 0) goto out; - rval = ccs_write(sensor, Y_OUTPUT_SIZE, - sensor->src->crop[CCS_PAD_SRC].height); + rval = ccs_write(sensor, Y_OUTPUT_SIZE, sensor->src_src.height); if (rval < 0) goto out; @@ -1923,9 +1903,6 @@ static int ccs_set_stream(struct v4l2_subdev *subdev, int enable) struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); int rval; - if (sensor->streaming == enable) - return 0; - if (!enable) { ccs_stop_streaming(sensor); sensor->streaming = false; @@ -2053,24 +2030,8 @@ static int __ccs_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) { - struct ccs_subdev *ssd = to_ccs_subdev(subdev); - - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - fmt->format = *v4l2_subdev_get_try_format(subdev, sd_state, - fmt->pad); - } else { - struct v4l2_rect *r; - - if (fmt->pad == ssd->source_pad) - r = &ssd->crop[ssd->source_pad]; - else - r = &ssd->sink_fmt; - - fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); - fmt->format.width = r->width; - fmt->format.height = r->height; - fmt->format.field = V4L2_FIELD_NONE; - } + fmt->format = *v4l2_subdev_get_pad_format(subdev, sd_state, fmt->pad); + fmt->format.code = __ccs_get_mbus_code(subdev, fmt->pad); return 0; } @@ -2092,28 +2053,18 @@ static int ccs_get_format(struct v4l2_subdev *subdev, static void ccs_get_crop_compose(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_rect **crops, - struct v4l2_rect **comps, int which) + struct v4l2_rect **comps) { struct ccs_subdev *ssd = to_ccs_subdev(subdev); unsigned int i; - if (which == V4L2_SUBDEV_FORMAT_ACTIVE) { - if (crops) - for (i = 0; i < subdev->entity.num_pads; i++) - crops[i] = &ssd->crop[i]; - if (comps) - *comps = &ssd->compose; - } else { - if (crops) { - for (i = 0; i < subdev->entity.num_pads; i++) - crops[i] = v4l2_subdev_get_try_crop(subdev, - sd_state, - i); - } - if (comps) - *comps = v4l2_subdev_get_try_compose(subdev, sd_state, - CCS_PAD_SINK); - } + if (crops) + for (i = 0; i < subdev->entity.num_pads; i++) + crops[i] = + v4l2_subdev_get_pad_crop(subdev, sd_state, i); + if (comps) + *comps = v4l2_subdev_get_pad_compose(subdev, sd_state, + ssd->sink_pad); } /* Changes require propagation only on sink pad. */ @@ -2124,8 +2075,9 @@ static void ccs_propagate(struct v4l2_subdev *subdev, struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; + struct v4l2_mbus_framefmt *fmt; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); switch (target) { case V4L2_SEL_TGT_CROP: @@ -2136,6 +2088,7 @@ static void ccs_propagate(struct v4l2_subdev *subdev, sensor->scale_m = CCS_LIM(sensor, SCALER_N_MIN); sensor->scaling_mode = CCS_SCALING_MODE_NO_SCALING; + sensor->scaler_sink = *comp; } else if (ssd == sensor->binner) { sensor->binning_horizontal = 1; sensor->binning_vertical = 1; @@ -2144,6 +2097,11 @@ static void ccs_propagate(struct v4l2_subdev *subdev, fallthrough; case V4L2_SEL_TGT_COMPOSE: *crops[CCS_PAD_SRC] = *comp; + fmt = v4l2_subdev_get_pad_format(subdev, sd_state, CCS_PAD_SRC); + fmt->width = comp->width; + fmt->height = comp->height; + if (which == V4L2_SUBDEV_FORMAT_ACTIVE && ssd == sensor->src) + sensor->src_src = *crops[CCS_PAD_SRC]; break; default: WARN_ON_ONCE(1); @@ -2252,14 +2210,12 @@ static int ccs_set_format(struct v4l2_subdev *subdev, CCS_LIM(sensor, MIN_Y_OUTPUT_SIZE), CCS_LIM(sensor, MAX_Y_OUTPUT_SIZE)); - ccs_get_crop_compose(subdev, sd_state, crops, NULL, fmt->which); + ccs_get_crop_compose(subdev, sd_state, crops, NULL); crops[ssd->sink_pad]->left = 0; crops[ssd->sink_pad]->top = 0; crops[ssd->sink_pad]->width = fmt->format.width; crops[ssd->sink_pad]->height = fmt->format.height; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) - ssd->sink_fmt = *crops[ssd->sink_pad]; ccs_propagate(subdev, sd_state, fmt->which, V4L2_SEL_TGT_CROP); mutex_unlock(&sensor->mutex); @@ -2482,7 +2438,7 @@ static int ccs_set_compose(struct v4l2_subdev *subdev, struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); sel->r.top = 0; sel->r.left = 0; @@ -2501,8 +2457,8 @@ static int ccs_set_compose(struct v4l2_subdev *subdev, return 0; } -static int __ccs_sel_supported(struct v4l2_subdev *subdev, - struct v4l2_subdev_selection *sel) +static int ccs_sel_supported(struct v4l2_subdev *subdev, + struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); @@ -2545,33 +2501,18 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); - struct v4l2_rect *src_size, *crops[CCS_PADS]; - struct v4l2_rect _r; + struct v4l2_rect src_size = { 0 }, *crops[CCS_PADS], *comp; - ccs_get_crop_compose(subdev, sd_state, crops, NULL, sel->which); + ccs_get_crop_compose(subdev, sd_state, crops, &comp); - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - if (sel->pad == ssd->sink_pad) - src_size = &ssd->sink_fmt; - else - src_size = &ssd->compose; + if (sel->pad == ssd->sink_pad) { + struct v4l2_mbus_framefmt *mfmt = + v4l2_subdev_get_pad_format(subdev, sd_state, sel->pad); + + src_size.width = mfmt->width; + src_size.height = mfmt->height; } else { - if (sel->pad == ssd->sink_pad) { - _r.left = 0; - _r.top = 0; - _r.width = v4l2_subdev_get_try_format(subdev, - sd_state, - sel->pad) - ->width; - _r.height = v4l2_subdev_get_try_format(subdev, - sd_state, - sel->pad) - ->height; - src_size = &_r; - } else { - src_size = v4l2_subdev_get_try_compose( - subdev, sd_state, ssd->sink_pad); - } + src_size = *comp; } if (ssd == sensor->src && sel->pad == CCS_PAD_SRC) { @@ -2579,16 +2520,19 @@ static int ccs_set_crop(struct v4l2_subdev *subdev, sel->r.top = 0; } - sel->r.width = min(sel->r.width, src_size->width); - sel->r.height = min(sel->r.height, src_size->height); + sel->r.width = min(sel->r.width, src_size.width); + sel->r.height = min(sel->r.height, src_size.height); - sel->r.left = min_t(int, sel->r.left, src_size->width - sel->r.width); - sel->r.top = min_t(int, sel->r.top, src_size->height - sel->r.height); + sel->r.left = min_t(int, sel->r.left, src_size.width - sel->r.width); + sel->r.top = min_t(int, sel->r.top, src_size.height - sel->r.height); *crops[sel->pad] = sel->r; if (ssd != sensor->pixel_array && sel->pad == CCS_PAD_SINK) ccs_propagate(subdev, sd_state, sel->which, V4L2_SEL_TGT_CROP); + else if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE && + ssd == sensor->pixel_array) + sensor->pa_src = sel->r; return 0; } @@ -2601,44 +2545,36 @@ static void ccs_get_native_size(struct ccs_subdev *ssd, struct v4l2_rect *r) r->height = CCS_LIM(ssd->sensor, Y_ADDR_MAX) + 1; } -static int __ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) +static int ccs_get_selection(struct v4l2_subdev *subdev, + struct v4l2_subdev_state *sd_state, + struct v4l2_subdev_selection *sel) { struct ccs_sensor *sensor = to_ccs_sensor(subdev); struct ccs_subdev *ssd = to_ccs_subdev(subdev); struct v4l2_rect *comp, *crops[CCS_PADS]; - struct v4l2_rect sink_fmt; int ret; - ret = __ccs_sel_supported(subdev, sel); + ret = ccs_sel_supported(subdev, sel); if (ret) return ret; - ccs_get_crop_compose(subdev, sd_state, crops, &comp, sel->which); - - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - sink_fmt = ssd->sink_fmt; - } else { - struct v4l2_mbus_framefmt *fmt = - v4l2_subdev_get_try_format(subdev, sd_state, - ssd->sink_pad); - - sink_fmt.left = 0; - sink_fmt.top = 0; - sink_fmt.width = fmt->width; - sink_fmt.height = fmt->height; - } + ccs_get_crop_compose(subdev, sd_state, crops, &comp); switch (sel->target) { case V4L2_SEL_TGT_CROP_BOUNDS: case V4L2_SEL_TGT_NATIVE_SIZE: - if (ssd == sensor->pixel_array) + if (ssd == sensor->pixel_array) { ccs_get_native_size(ssd, &sel->r); - else if (sel->pad == ssd->sink_pad) - sel->r = sink_fmt; - else + } else if (sel->pad == ssd->sink_pad) { + struct v4l2_mbus_framefmt *sink_fmt = + v4l2_subdev_get_pad_format(subdev, sd_state, + ssd->sink_pad); + sel->r.top = sel->r.left = 0; + sel->r.width = sink_fmt->width; + sel->r.height = sink_fmt->height; + } else { sel->r = *comp; + } break; case V4L2_SEL_TGT_CROP: case V4L2_SEL_TGT_COMPOSE_BOUNDS: @@ -2652,20 +2588,6 @@ static int __ccs_get_selection(struct v4l2_subdev *subdev, return 0; } -static int ccs_get_selection(struct v4l2_subdev *subdev, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) -{ - struct ccs_sensor *sensor = to_ccs_sensor(subdev); - int rval; - - mutex_lock(&sensor->mutex); - rval = __ccs_get_selection(subdev, sd_state, sel); - mutex_unlock(&sensor->mutex); - - return rval; -} - static int ccs_set_selection(struct v4l2_subdev *subdev, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) @@ -2673,7 +2595,7 @@ static int ccs_set_selection(struct v4l2_subdev *subdev, struct ccs_sensor *sensor = to_ccs_sensor(subdev); int ret; - ret = __ccs_sel_supported(subdev, sel); + ret = ccs_sel_supported(subdev, sel); if (ret) return ret; @@ -2945,7 +2867,6 @@ static int ccs_identify_module(struct ccs_sensor *sensor) } static const struct v4l2_subdev_ops ccs_ops; -static const struct v4l2_subdev_internal_ops ccs_internal_ops; static const struct media_entity_operations ccs_entity_ops; static int ccs_register_subdev(struct ccs_sensor *sensor, @@ -2959,12 +2880,6 @@ static int ccs_register_subdev(struct ccs_sensor *sensor, if (!sink_ssd) return 0; - rval = media_entity_pads_init(&ssd->sd.entity, ssd->npads, ssd->pads); - if (rval) { - dev_err(&client->dev, "media_entity_pads_init failed\n"); - return rval; - } - rval = v4l2_device_register_subdev(sensor->src->sd.v4l2_dev, &ssd->sd); if (rval) { dev_err(&client->dev, "v4l2_device_register_subdev failed\n"); @@ -3025,6 +2940,12 @@ out_err: static void ccs_cleanup(struct ccs_sensor *sensor) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + unsigned int i; + + for (i = 0; i < sensor->ssds_used; i++) { + v4l2_subdev_cleanup(&sensor->ssds[2].sd); + media_entity_cleanup(&sensor->ssds[i].sd.entity); + } device_remove_file(&client->dev, &dev_attr_nvm); device_remove_file(&client->dev, &dev_attr_ident); @@ -3032,14 +2953,17 @@ static void ccs_cleanup(struct ccs_sensor *sensor) ccs_free_controls(sensor); } -static void ccs_create_subdev(struct ccs_sensor *sensor, - struct ccs_subdev *ssd, const char *name, - unsigned short num_pads, u32 function) +static int ccs_init_subdev(struct ccs_sensor *sensor, + struct ccs_subdev *ssd, const char *name, + unsigned short num_pads, u32 function, + const char *lock_name, + struct lock_class_key *lock_key) { struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); + int rval; if (!ssd) - return; + return 0; if (ssd != sensor->src) v4l2_subdev_init(&ssd->sd, &ccs_ops); @@ -3053,57 +2977,70 @@ static void ccs_create_subdev(struct ccs_sensor *sensor, v4l2_i2c_subdev_set_name(&ssd->sd, client, sensor->minfo.name, name); - ccs_get_native_size(ssd, &ssd->sink_fmt); - - ssd->compose.width = ssd->sink_fmt.width; - ssd->compose.height = ssd->sink_fmt.height; - ssd->crop[ssd->source_pad] = ssd->compose; ssd->pads[ssd->source_pad].flags = MEDIA_PAD_FL_SOURCE; - if (ssd != sensor->pixel_array) { - ssd->crop[ssd->sink_pad] = ssd->compose; + if (ssd != sensor->pixel_array) ssd->pads[ssd->sink_pad].flags = MEDIA_PAD_FL_SINK; - } ssd->sd.entity.ops = &ccs_entity_ops; - if (ssd == sensor->src) - return; + if (ssd != sensor->src) { + ssd->sd.owner = THIS_MODULE; + ssd->sd.dev = &client->dev; + v4l2_set_subdevdata(&ssd->sd, client); + } + + rval = media_entity_pads_init(&ssd->sd.entity, ssd->npads, ssd->pads); + if (rval) { + dev_err(&client->dev, "media_entity_pads_init failed\n"); + return rval; + } - ssd->sd.internal_ops = &ccs_internal_ops; - ssd->sd.owner = THIS_MODULE; - ssd->sd.dev = &client->dev; - v4l2_set_subdevdata(&ssd->sd, client); + rval = __v4l2_subdev_init_finalize(&ssd->sd, lock_name, lock_key); + if (rval) { + media_entity_cleanup(&ssd->sd.entity); + return rval; + } + + return 0; } -static int ccs_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +static int ccs_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { struct ccs_subdev *ssd = to_ccs_subdev(sd); struct ccs_sensor *sensor = ssd->sensor; - unsigned int i; + unsigned int pad = ssd == sensor->pixel_array ? + CCS_PA_PAD_SRC : CCS_PAD_SINK; + struct v4l2_mbus_framefmt *fmt = + v4l2_subdev_get_pad_format(sd, sd_state, pad); + struct v4l2_rect *crop = + v4l2_subdev_get_pad_crop(sd, sd_state, pad); + bool is_active = !sd->active_state || sd->active_state == sd_state; mutex_lock(&sensor->mutex); - for (i = 0; i < ssd->npads; i++) { - struct v4l2_mbus_framefmt *try_fmt = - v4l2_subdev_get_try_format(sd, fh->state, i); - struct v4l2_rect *try_crop = - v4l2_subdev_get_try_crop(sd, fh->state, i); - struct v4l2_rect *try_comp; + ccs_get_native_size(ssd, crop); - ccs_get_native_size(ssd, try_crop); + fmt->width = crop->width; + fmt->height = crop->height; + fmt->code = sensor->internal_csi_format->code; + fmt->field = V4L2_FIELD_NONE; - try_fmt->width = try_crop->width; - try_fmt->height = try_crop->height; - try_fmt->code = sensor->internal_csi_format->code; - try_fmt->field = V4L2_FIELD_NONE; + if (ssd == sensor->pixel_array) { + if (is_active) + sensor->pa_src = *crop; - if (ssd == sensor->pixel_array) - continue; - - try_comp = v4l2_subdev_get_try_compose(sd, fh->state, i); - *try_comp = *try_crop; + mutex_unlock(&sensor->mutex); + return 0; } + fmt = v4l2_subdev_get_pad_format(sd, sd_state, CCS_PAD_SRC); + fmt->code = ssd == sensor->src ? + sensor->csi_format->code : sensor->internal_csi_format->code; + fmt->field = V4L2_FIELD_NONE; + + ccs_propagate(sd, sd_state, is_active, V4L2_SEL_TGT_CROP); + mutex_unlock(&sensor->mutex); return 0; @@ -3116,6 +3053,7 @@ static const struct v4l2_subdev_video_ops ccs_video_ops = { }; static const struct v4l2_subdev_pad_ops ccs_pad_ops = { + .init_cfg = ccs_init_cfg, .enum_mbus_code = ccs_enum_mbus_code, .get_fmt = ccs_get_format, .set_fmt = ccs_set_format, @@ -3141,53 +3079,12 @@ static const struct media_entity_operations ccs_entity_ops = { static const struct v4l2_subdev_internal_ops ccs_internal_src_ops = { .registered = ccs_registered, .unregistered = ccs_unregistered, - .open = ccs_open, -}; - -static const struct v4l2_subdev_internal_ops ccs_internal_ops = { - .open = ccs_open, }; /* ----------------------------------------------------------------------------- * I2C Driver */ -static int __maybe_unused ccs_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *subdev = i2c_get_clientdata(client); - struct ccs_sensor *sensor = to_ccs_sensor(subdev); - bool streaming = sensor->streaming; - int rval; - - rval = pm_runtime_resume_and_get(dev); - if (rval < 0) - return rval; - - if (sensor->streaming) - ccs_stop_streaming(sensor); - - /* save state for resume */ - sensor->streaming = streaming; - - return 0; -} - -static int __maybe_unused ccs_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *subdev = i2c_get_clientdata(client); - struct ccs_sensor *sensor = to_ccs_sensor(subdev); - int rval = 0; - - pm_runtime_put(dev); - - if (sensor->streaming) - rval = ccs_start_streaming(sensor); - - return rval; -} - static int ccs_get_hwconfig(struct ccs_sensor *sensor, struct device *dev) { struct ccs_hwconfig *hwcfg = &sensor->hwcfg; @@ -3311,6 +3208,8 @@ static int ccs_firmware_name(struct i2c_client *client, static int ccs_probe(struct i2c_client *client) { + static struct lock_class_key pixel_array_lock_key, binner_lock_key, + scaler_lock_key; const struct ccs_device *ccsdev = device_get_match_data(&client->dev); struct ccs_sensor *sensor; const struct firmware *fw; @@ -3587,12 +3486,27 @@ static int ccs_probe(struct i2c_client *client) sensor->pll.ext_clk_freq_hz = sensor->hwcfg.ext_clk; sensor->pll.scale_n = CCS_LIM(sensor, SCALER_N_MIN); - ccs_create_subdev(sensor, sensor->scaler, " scaler", 2, - MEDIA_ENT_F_PROC_VIDEO_SCALER); - ccs_create_subdev(sensor, sensor->binner, " binner", 2, - MEDIA_ENT_F_PROC_VIDEO_SCALER); - ccs_create_subdev(sensor, sensor->pixel_array, " pixel_array", 1, - MEDIA_ENT_F_CAM_SENSOR); + rval = ccs_get_mbus_formats(sensor); + if (rval) { + rval = -ENODEV; + goto out_cleanup; + } + + rval = ccs_init_subdev(sensor, sensor->scaler, " scaler", 2, + MEDIA_ENT_F_PROC_VIDEO_SCALER, + "ccs scaler mutex", &scaler_lock_key); + if (rval) + goto out_cleanup; + rval = ccs_init_subdev(sensor, sensor->binner, " binner", 2, + MEDIA_ENT_F_PROC_VIDEO_SCALER, + "ccs binner mutex", &binner_lock_key); + if (rval) + goto out_cleanup; + rval = ccs_init_subdev(sensor, sensor->pixel_array, " pixel_array", 1, + MEDIA_ENT_F_CAM_SENSOR, "ccs pixel array mutex", + &pixel_array_lock_key); + if (rval) + goto out_cleanup; rval = ccs_init_controls(sensor); if (rval < 0) @@ -3602,12 +3516,6 @@ static int ccs_probe(struct i2c_client *client) if (rval) goto out_cleanup; - rval = ccs_get_mbus_formats(sensor); - if (rval) { - rval = -ENODEV; - goto out_cleanup; - } - rval = ccs_init_late_controls(sensor); if (rval) { rval = -ENODEV; @@ -3625,14 +3533,9 @@ static int ccs_probe(struct i2c_client *client) sensor->streaming = false; sensor->dev_init_done = true; - rval = media_entity_pads_init(&sensor->src->sd.entity, 2, - sensor->src->pads); - if (rval < 0) - goto out_media_entity_cleanup; - rval = ccs_write_msr_regs(sensor); if (rval) - goto out_media_entity_cleanup; + goto out_cleanup; pm_runtime_set_active(&client->dev); pm_runtime_get_noresume(&client->dev); @@ -3652,9 +3555,6 @@ out_disable_runtime_pm: pm_runtime_put_noidle(&client->dev); pm_runtime_disable(&client->dev); -out_media_entity_cleanup: - media_entity_cleanup(&sensor->src->sd.entity); - out_cleanup: ccs_cleanup(sensor); @@ -3687,10 +3587,8 @@ static void ccs_remove(struct i2c_client *client) ccs_power_off(&client->dev); pm_runtime_set_suspended(&client->dev); - for (i = 0; i < sensor->ssds_used; i++) { + for (i = 0; i < sensor->ssds_used; i++) v4l2_device_unregister_subdev(&sensor->ssds[i].sd); - media_entity_cleanup(&sensor->ssds[i].sd.entity); - } ccs_cleanup(sensor); mutex_destroy(&sensor->mutex); kfree(sensor->ccs_limits); @@ -3720,7 +3618,6 @@ static const struct of_device_id ccs_of_table[] = { MODULE_DEVICE_TABLE(of, ccs_of_table); static const struct dev_pm_ops ccs_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ccs_suspend, ccs_resume) SET_RUNTIME_PM_OPS(ccs_power_off, ccs_power_on, NULL) }; diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h index a94c796cea..9c3587b2fb 100644 --- a/drivers/media/i2c/ccs/ccs.h +++ b/drivers/media/i2c/ccs/ccs.h @@ -182,9 +182,6 @@ struct ccs_binning_subtype { struct ccs_subdev { struct v4l2_subdev sd; struct media_pad pads[CCS_PADS]; - struct v4l2_rect sink_fmt; - struct v4l2_rect crop[CCS_PADS]; - struct v4l2_rect compose; /* compose on sink */ unsigned short sink_pad; unsigned short source_pad; int npads; @@ -220,6 +217,7 @@ struct ccs_sensor { u32 mbus_frame_fmts; const struct ccs_csi_data_format *csi_format; const struct ccs_csi_data_format *internal_csi_format; + struct v4l2_rect pa_src, scaler_sink, src_src; u32 default_mbus_frame_fmts; int default_pixel_order; struct ccs_data_container sdata, mdata; diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c index 5aec252890..04461c893d 100644 --- a/drivers/media/i2c/cx25840/cx25840-core.c +++ b/drivers/media/i2c/cx25840/cx25840-core.c @@ -2738,10 +2738,801 @@ static int cx25840_irq_handler(struct v4l2_subdev *sd, u32 status, #define DIF_BPF_COEFF3435 (0x38c) #define DIF_BPF_COEFF36 (0x390) +static const u32 ifhz_coeffs[][19] = { + { // 3.0 MHz + 0x00000002, 0x00080012, 0x001e0024, 0x001bfff8, + 0xffb4ff50, 0xfed8fe68, 0xfe24fe34, 0xfebaffc7, + 0x014d031f, 0x04f0065d, 0x07010688, 0x04c901d6, + 0xfe00f9d3, 0xf600f342, 0xf235f337, 0xf64efb22, + 0x0105070f, 0x0c460fce, 0x110d0000, + }, { // 3.1 MHz + 0x00000001, 0x00070012, 0x00220032, 0x00370026, + 0xfff0ff91, 0xff0efe7c, 0xfe01fdcc, 0xfe0afedb, + 0x00440224, 0x0434060c, 0x0738074e, 0x06090361, + 0xff99fb39, 0xf6fef3b6, 0xf21af2a5, 0xf573fa33, + 0x0034067d, 0x0bfb0fb9, 0x110d0000, + }, { // 3.2 MHz + 0x00000000, 0x0004000e, 0x00200038, 0x004c004f, + 0x002fffdf, 0xff5cfeb6, 0xfe0dfd92, 0xfd7ffe03, + 0xff36010a, 0x03410575, 0x072607d2, 0x071804d5, + 0x0134fcb7, 0xf81ff451, 0xf223f22e, 0xf4a7f94b, + 0xff6405e8, 0x0bae0fa4, 0x110d0000, + }, { // 3.3 MHz + 0x0000ffff, 0x00000008, 0x001a0036, 0x0056006d, + 0x00670030, 0xffbdff10, 0xfe46fd8d, 0xfd25fd4f, + 0xfe35ffe0, 0x0224049f, 0x06c9080e, 0x07ef0627, + 0x02c9fe45, 0xf961f513, 0xf250f1d2, 0xf3ecf869, + 0xfe930552, 0x0b5f0f8f, 0x110d0000, + }, { // 3.4 MHz + 0xfffffffe, 0xfffd0001, 0x000f002c, 0x0054007d, + 0x0093007c, 0x0024ff82, 0xfea6fdbb, 0xfd03fcca, + 0xfd51feb9, 0x00eb0392, 0x06270802, 0x08880750, + 0x044dffdb, 0xfabdf5f8, 0xf2a0f193, 0xf342f78f, + 0xfdc404b9, 0x0b0e0f78, 0x110d0000, + }, { // 3.5 MHz + 0xfffffffd, 0xfffafff9, 0x0002001b, 0x0046007d, + 0x00ad00ba, 0x00870000, 0xff26fe1a, 0xfd1bfc7e, + 0xfc99fda4, 0xffa5025c, 0x054507ad, 0x08dd0847, + 0x05b80172, 0xfc2ef6ff, 0xf313f170, 0xf2abf6bd, + 0xfcf6041f, 0x0abc0f61, 0x110d0000, + }, { // 3.6 MHz + 0xfffffffd, 0xfff8fff3, 0xfff50006, 0x002f006c, + 0x00b200e3, 0x00dc007e, 0xffb9fea0, 0xfd6bfc71, + 0xfc17fcb1, 0xfe65010b, 0x042d0713, 0x08ec0906, + 0x07020302, 0xfdaff823, 0xf3a7f16a, 0xf228f5f5, + 0xfc2a0384, 0x0a670f4a, 0x110d0000, + }, { // 3.7 MHz + 0x0000fffd, 0xfff7ffef, 0xffe9fff1, 0x0010004d, + 0x00a100f2, 0x011a00f0, 0x0053ff44, 0xfdedfca2, + 0xfbd3fbef, 0xfd39ffae, 0x02ea0638, 0x08b50987, + 0x08230483, 0xff39f960, 0xf45bf180, 0xf1b8f537, + 0xfb6102e7, 0x0a110f32, 0x110d0000, + }, { // 3.8 MHz + 0x0000fffe, 0xfff9ffee, 0xffe1ffdd, 0xfff00024, + 0x007c00e5, 0x013a014a, 0x00e6fff8, 0xfe98fd0f, + 0xfbd3fb67, 0xfc32fe54, 0x01880525, 0x083909c7, + 0x091505ee, 0x00c7fab3, 0xf52df1b4, 0xf15df484, + 0xfa9b0249, 0x09ba0f19, 0x110d0000, + }, { // 3.9 MHz + 0x00000000, 0xfffbfff0, 0xffdeffcf, 0xffd1fff6, + 0x004800be, 0x01390184, 0x016300ac, 0xff5efdb1, + 0xfc17fb23, 0xfb5cfd0d, 0x001703e4, 0x077b09c4, + 0x09d2073c, 0x0251fc18, 0xf61cf203, 0xf118f3dc, + 0xf9d801aa, 0x09600eff, 0x110d0000, + }, { // 4.0 MHz + 0x00000001, 0xfffefff4, 0xffe1ffc8, 0xffbaffca, + 0x000b0082, 0x01170198, 0x01c10152, 0x0030fe7b, + 0xfc99fb24, 0xfac3fbe9, 0xfea5027f, 0x0683097f, + 0x0a560867, 0x03d2fd89, 0xf723f26f, 0xf0e8f341, + 0xf919010a, 0x09060ee5, 0x110d0000, + }, { // 4.1 MHz + 0x00010002, 0x0002fffb, 0xffe8ffca, 0xffacffa4, + 0xffcd0036, 0x00d70184, 0x01f601dc, 0x00ffff60, + 0xfd51fb6d, 0xfa6efaf5, 0xfd410103, 0x055708f9, + 0x0a9e0969, 0x0543ff02, 0xf842f2f5, 0xf0cef2b2, + 0xf85e006b, 0x08aa0ecb, 0x110d0000, + }, { // 4.2 MHz + 0x00010003, 0x00050003, 0xfff3ffd3, 0xffaaff8b, + 0xff95ffe5, 0x0080014a, 0x01fe023f, 0x01ba0050, + 0xfe35fbf8, 0xfa62fa3b, 0xfbf9ff7e, 0x04010836, + 0x0aa90a3d, 0x069f007f, 0xf975f395, 0xf0cbf231, + 0xf7a9ffcb, 0x084c0eaf, 0x110d0000, + }, { // 4.3 MHz + 0x00010003, 0x0008000a, 0x0000ffe4, 0xffb4ff81, + 0xff6aff96, 0x001c00f0, 0x01d70271, 0x0254013b, + 0xff36fcbd, 0xfa9ff9c5, 0xfadbfdfe, 0x028c073b, + 0x0a750adf, 0x07e101fa, 0xfab8f44e, 0xf0ddf1be, + 0xf6f9ff2b, 0x07ed0e94, 0x110d0000, + }, { // 4.4 MHz + 0x00000003, 0x0009000f, 0x000efff8, 0xffc9ff87, + 0xff52ff54, 0xffb5007e, 0x01860270, 0x02c00210, + 0x0044fdb2, 0xfb22f997, 0xf9f2fc90, 0x0102060f, + 0x0a050b4c, 0x0902036e, 0xfc0af51e, 0xf106f15a, + 0xf64efe8b, 0x078d0e77, 0x110d0000, + }, { // 4.5 MHz + 0x00000002, 0x00080012, 0x0019000e, 0xffe5ff9e, + 0xff4fff25, 0xff560000, 0x0112023b, 0x02f702c0, + 0x014dfec8, 0xfbe5f9b3, 0xf947fb41, 0xff7004b9, + 0x095a0b81, 0x0a0004d8, 0xfd65f603, 0xf144f104, + 0xf5aafdec, 0x072b0e5a, 0x110d0000, + }, { // 4.6 MHz + 0x00000001, 0x00060012, 0x00200022, 0x0005ffc1, + 0xff61ff10, 0xff09ff82, 0x008601d7, 0x02f50340, + 0x0241fff0, 0xfcddfa19, 0xf8e2fa1e, 0xfde30343, + 0x08790b7f, 0x0ad50631, 0xfec7f6fc, 0xf198f0bd, + 0xf50dfd4e, 0x06c90e3d, 0x110d0000, + }, { // 4.7 MHz + 0x0000ffff, 0x0003000f, 0x00220030, 0x0025ffed, + 0xff87ff15, 0xfed6ff10, 0xffed014c, 0x02b90386, + 0x03110119, 0xfdfefac4, 0xf8c6f92f, 0xfc6701b7, + 0x07670b44, 0x0b7e0776, 0x002df807, 0xf200f086, + 0xf477fcb1, 0x06650e1e, 0x110d0000, + }, { // 4.8 MHz + 0xfffffffe, 0xffff0009, 0x001e0038, 0x003f001b, + 0xffbcff36, 0xfec2feb6, 0xff5600a5, 0x0248038d, + 0x03b00232, 0xff39fbab, 0xf8f4f87f, 0xfb060020, + 0x062a0ad2, 0x0bf908a3, 0x0192f922, 0xf27df05e, + 0xf3e8fc14, 0x06000e00, 0x110d0000, + }, { // 4.9 MHz + 0xfffffffd, 0xfffc0002, 0x00160037, 0x00510046, + 0xfff9ff6d, 0xfed0fe7c, 0xfecefff0, 0x01aa0356, + 0x0413032b, 0x007ffcc5, 0xf96cf812, 0xf9cefe87, + 0x04c90a2c, 0x0c4309b4, 0x02f3fa4a, 0xf30ef046, + 0xf361fb7a, 0x059b0de0, 0x110d0000, + }, { // 5.0 MHz + 0xfffffffd, 0xfff9fffa, 0x000a002d, 0x00570067, + 0x0037ffb5, 0xfefffe68, 0xfe62ff3d, 0x00ec02e3, + 0x043503f6, 0x01befe05, 0xfa27f7ee, 0xf8c6fcf8, + 0x034c0954, 0x0c5c0aa4, 0x044cfb7e, 0xf3b1f03f, + 0xf2e2fae1, 0x05340dc0, 0x110d0000, + }, { // 5.1 MHz + 0x0000fffd, 0xfff8fff4, 0xfffd001e, 0x0051007b, + 0x006e0006, 0xff48fe7c, 0xfe1bfe9a, 0x001d023e, + 0x04130488, 0x02e6ff5b, 0xfb1ef812, 0xf7f7fb7f, + 0x01bc084e, 0x0c430b72, 0x059afcba, 0xf467f046, + 0xf26cfa4a, 0x04cd0da0, 0x110d0000, + }, { // 5.2 MHz + 0x0000fffe, 0xfff8ffef, 0xfff00009, 0x003f007f, + 0x00980056, 0xffa5feb6, 0xfe00fe15, 0xff4b0170, + 0x03b004d7, 0x03e800b9, 0xfc48f87f, 0xf768fa23, + 0x0022071f, 0x0bf90c1b, 0x06dafdfd, 0xf52df05e, + 0xf1fef9b5, 0x04640d7f, 0x110d0000, + }, { // 5.3 MHz + 0x0000ffff, 0xfff9ffee, 0xffe6fff3, 0x00250072, + 0x00af009c, 0x000cff10, 0xfe13fdb8, 0xfe870089, + 0x031104e1, 0x04b8020f, 0xfd98f92f, 0xf71df8f0, + 0xfe8805ce, 0x0b7e0c9c, 0x0808ff44, 0xf603f086, + 0xf19af922, 0x03fb0d5e, 0x110d0000, + }, { // 5.4 MHz + 0x00000001, 0xfffcffef, 0xffe0ffe0, 0x00050056, + 0x00b000d1, 0x0071ff82, 0xfe53fd8c, 0xfddfff99, + 0x024104a3, 0x054a034d, 0xff01fa1e, 0xf717f7ed, + 0xfcf50461, 0x0ad50cf4, 0x0921008d, 0xf6e7f0bd, + 0xf13ff891, 0x03920d3b, 0x110d0000, + }, { // 5.5 MHz + 0x00010002, 0xfffffff3, 0xffdeffd1, 0xffe5002f, + 0x009c00ed, 0x00cb0000, 0xfebafd94, 0xfd61feb0, + 0x014d0422, 0x05970464, 0x0074fb41, 0xf759f721, + 0xfb7502de, 0x0a000d21, 0x0a2201d4, 0xf7d9f104, + 0xf0edf804, 0x03280d19, 0x110d0000, + }, { // 5.6 MHz + 0x00010003, 0x0003fffa, 0xffe3ffc9, 0xffc90002, + 0x007500ef, 0x010e007e, 0xff3dfdcf, 0xfd16fddd, + 0x00440365, 0x059b0548, 0x01e3fc90, 0xf7dff691, + 0xfa0f014d, 0x09020d23, 0x0b0a0318, 0xf8d7f15a, + 0xf0a5f779, 0x02bd0cf6, 0x110d0000, + }, { // 5.7 MHz + 0x00010003, 0x00060001, 0xffecffc9, 0xffb4ffd4, + 0x004000d5, 0x013600f0, 0xffd3fe39, 0xfd04fd31, + 0xff360277, 0x055605ef, 0x033efdfe, 0xf8a5f642, + 0xf8cbffb6, 0x07e10cfb, 0x0bd50456, 0xf9dff1be, + 0xf067f6f2, 0x02520cd2, 0x110d0000, + }, { // 5.8 MHz + 0x00000003, 0x00080009, 0xfff8ffd2, 0xffaaffac, + 0x000200a3, 0x013c014a, 0x006dfec9, 0xfd2bfcb7, + 0xfe350165, 0x04cb0651, 0x0477ff7e, 0xf9a5f635, + 0xf7b1fe20, 0x069f0ca8, 0x0c81058b, 0xfaf0f231, + 0xf033f66d, 0x01e60cae, 0x110d0000, + }, { // 5.9 MHz + 0x00000002, 0x0009000e, 0x0005ffe1, 0xffacff90, + 0xffc5005f, 0x01210184, 0x00fcff72, 0xfd8afc77, + 0xfd51003f, 0x04020669, 0x05830103, 0xfad7f66b, + 0xf6c8fc93, 0x05430c2b, 0x0d0d06b5, 0xfc08f2b2, + 0xf00af5ec, 0x017b0c89, 0x110d0000, + }, { // 6.0 MHz + 0x00000001, 0x00070012, 0x0012fff5, 0xffbaff82, + 0xff8e000f, 0x00e80198, 0x01750028, 0xfe18fc75, + 0xfc99ff15, 0x03050636, 0x0656027f, 0xfc32f6e2, + 0xf614fb17, 0x03d20b87, 0x0d7707d2, 0xfd26f341, + 0xefeaf56f, 0x010f0c64, 0x110d0000, + }, { // 6.1 MHz + 0xffff0000, 0x00050012, 0x001c000b, 0xffd1ff84, + 0xff66ffbe, 0x00960184, 0x01cd00da, 0xfeccfcb2, + 0xfc17fdf9, 0x01e005bc, 0x06e703e4, 0xfdabf798, + 0xf599f9b3, 0x02510abd, 0x0dbf08df, 0xfe48f3dc, + 0xefd5f4f6, 0x00a20c3e, 0x110d0000, + }, { // 6.2 MHz + 0xfffffffe, 0x0002000f, 0x0021001f, 0xfff0ff97, + 0xff50ff74, 0x0034014a, 0x01fa0179, 0xff97fd2a, + 0xfbd3fcfa, 0x00a304fe, 0x07310525, 0xff37f886, + 0xf55cf86e, 0x00c709d0, 0x0de209db, 0xff6df484, + 0xefcbf481, 0x00360c18, 0x110d0000, + }, { // 6.3 MHz + 0xfffffffd, 0xfffe000a, 0x0021002f, 0x0010ffb8, + 0xff50ff3b, 0xffcc00f0, 0x01fa01fa, 0x0069fdd4, + 0xfbd3fc26, 0xff5d0407, 0x07310638, 0x00c9f9a8, + 0xf55cf74e, 0xff3908c3, 0x0de20ac3, 0x0093f537, + 0xefcbf410, 0xffca0bf2, 0x110d0000, + }, { // 6.4 MHz + 0xfffffffd, 0xfffb0003, 0x001c0037, 0x002fffe2, + 0xff66ff17, 0xff6a007e, 0x01cd0251, 0x0134fea5, + 0xfc17fb8b, 0xfe2002e0, 0x06e70713, 0x0255faf5, + 0xf599f658, 0xfdaf0799, 0x0dbf0b96, 0x01b8f5f5, + 0xefd5f3a3, 0xff5e0bca, 0x110d0000, + }, { // 6.5 MHz + 0x0000fffd, 0xfff9fffb, 0x00120037, 0x00460010, + 0xff8eff0f, 0xff180000, 0x01750276, 0x01e8ff8d, + 0xfc99fb31, 0xfcfb0198, 0x065607ad, 0x03cefc64, + 0xf614f592, 0xfc2e0656, 0x0d770c52, 0x02daf6bd, + 0xefeaf33b, 0xfef10ba3, 0x110d0000, + }, { // 6.6 MHz + 0x0000fffe, 0xfff7fff5, 0x0005002f, 0x0054003c, + 0xffc5ff22, 0xfedfff82, 0x00fc0267, 0x0276007e, + 0xfd51fb1c, 0xfbfe003e, 0x05830802, 0x0529fdec, + 0xf6c8f4fe, 0xfabd04ff, 0x0d0d0cf6, 0x03f8f78f, + 0xf00af2d7, 0xfe850b7b, 0x110d0000, + }, { // 6.7 MHz + 0x0000ffff, 0xfff8fff0, 0xfff80020, 0x00560060, + 0x0002ff4e, 0xfec4ff10, 0x006d0225, 0x02d50166, + 0xfe35fb4e, 0xfb35fee1, 0x0477080e, 0x065bff82, + 0xf7b1f4a0, 0xf9610397, 0x0c810d80, 0x0510f869, + 0xf033f278, 0xfe1a0b52, 0x110d0000, + }, { // 6.8 MHz + 0x00010000, 0xfffaffee, 0xffec000c, 0x004c0078, + 0x0040ff8e, 0xfecafeb6, 0xffd301b6, 0x02fc0235, + 0xff36fbc5, 0xfaaafd90, 0x033e07d2, 0x075b011b, + 0xf8cbf47a, 0xf81f0224, 0x0bd50def, 0x0621f94b, + 0xf067f21e, 0xfdae0b29, 0x110d0000, + }, { // 6.9 MHz + 0x00010001, 0xfffdffef, 0xffe3fff6, 0x0037007f, + 0x0075ffdc, 0xfef2fe7c, 0xff3d0122, 0x02ea02dd, + 0x0044fc79, 0xfa65fc5d, 0x01e3074e, 0x082102ad, + 0xfa0ff48c, 0xf6fe00a9, 0x0b0a0e43, 0x0729fa33, + 0xf0a5f1c9, 0xfd430b00, 0x110d0000, + }, { // 7.0 MHz + 0x00010002, 0x0001fff3, 0xffdeffe2, 0x001b0076, + 0x009c002d, 0xff35fe68, 0xfeba0076, 0x029f0352, + 0x014dfd60, 0xfa69fb53, 0x00740688, 0x08a7042d, + 0xfb75f4d6, 0xf600ff2d, 0x0a220e7a, 0x0827fb22, + 0xf0edf17a, 0xfcd80ad6, 0x110d0000, + }, { // 7.1 MHz + 0x00000003, 0x0004fff9, 0xffe0ffd2, 0xfffb005e, + 0x00b0007a, 0xff8ffe7c, 0xfe53ffc1, 0x0221038c, + 0x0241fe6e, 0xfab6fa80, 0xff010587, 0x08e90590, + 0xfcf5f556, 0xf52bfdb3, 0x09210e95, 0x0919fc15, + 0xf13ff12f, 0xfc6e0aab, 0x110d0000, + }, { // 7.2 MHz + 0x00000003, 0x00070000, 0xffe6ffc9, 0xffdb0039, + 0x00af00b8, 0xfff4feb6, 0xfe13ff10, 0x01790388, + 0x0311ff92, 0xfb48f9ed, 0xfd980453, 0x08e306cd, + 0xfe88f60a, 0xf482fc40, 0x08080e93, 0x09fdfd0c, + 0xf19af0ea, 0xfc050a81, 0x110d0000, + }, { // 7.3 MHz + 0x00000002, 0x00080008, 0xfff0ffc9, 0xffc1000d, + 0x009800e2, 0x005bff10, 0xfe00fe74, 0x00b50345, + 0x03b000bc, 0xfc18f9a1, 0xfc4802f9, 0x089807dc, + 0x0022f6f0, 0xf407fada, 0x06da0e74, 0x0ad3fe06, + 0xf1fef0ab, 0xfb9c0a55, 0x110d0000, + }, { // 7.4 MHz + 0x00000001, 0x0008000e, 0xfffdffd0, 0xffafffdf, + 0x006e00f2, 0x00b8ff82, 0xfe1bfdf8, 0xffe302c8, + 0x041301dc, 0xfd1af99e, 0xfb1e0183, 0x080908b5, + 0x01bcf801, 0xf3bdf985, 0x059a0e38, 0x0b99ff03, + 0xf26cf071, 0xfb330a2a, 0x110d0000, + }, { // 7.5 MHz + 0xffff0000, 0x00070011, 0x000affdf, 0xffa9ffb5, + 0x003700e6, 0x01010000, 0xfe62fda8, 0xff140219, + 0x043502e1, 0xfe42f9e6, 0xfa270000, 0x073a0953, + 0x034cf939, 0xf3a4f845, 0x044c0de1, 0x0c4f0000, + 0xf2e2f03c, 0xfacc09fe, 0x110d0000, + }, { // 7.6 MHz + 0xffffffff, 0x00040012, 0x0016fff3, 0xffafff95, + 0xfff900c0, 0x0130007e, 0xfecefd89, 0xfe560146, + 0x041303bc, 0xff81fa76, 0xf96cfe7d, 0x063209b1, + 0x04c9fa93, 0xf3bdf71e, 0x02f30d6e, 0x0cf200fd, + 0xf361f00e, 0xfa6509d1, 0x110d0000, + }, { // 7.7 MHz + 0xfffffffe, 0x00010010, 0x001e0008, 0xffc1ff84, + 0xffbc0084, 0x013e00f0, 0xff56fd9f, 0xfdb8005c, + 0x03b00460, 0x00c7fb45, 0xf8f4fd07, 0x04fa09ce, + 0x062afc07, 0xf407f614, 0x01920ce0, 0x0d8301fa, + 0xf3e8efe5, 0xfa0009a4, 0x110d0000, + }, { // 7.8 MHz + 0x0000fffd, 0xfffd000b, 0x0022001d, 0xffdbff82, + 0xff870039, 0x012a014a, 0xffedfde7, 0xfd47ff6b, + 0x031104c6, 0x0202fc4c, 0xf8c6fbad, 0x039909a7, + 0x0767fd8e, 0xf482f52b, 0x002d0c39, 0x0e0002f4, + 0xf477efc2, 0xf99b0977, 0x110d0000, + }, { // 7.9 MHz + 0x0000fffd, 0xfffa0004, 0x0020002d, 0xfffbff91, + 0xff61ffe8, 0x00f70184, 0x0086fe5c, 0xfd0bfe85, + 0x024104e5, 0x0323fd7d, 0xf8e2fa79, 0x021d093f, + 0x0879ff22, 0xf52bf465, 0xfec70b79, 0x0e6803eb, + 0xf50defa5, 0xf937094a, 0x110d0000, + }, { // 8.0 MHz + 0x0000fffe, 0xfff8fffd, 0x00190036, 0x001bffaf, + 0xff4fff99, 0x00aa0198, 0x0112fef3, 0xfd09fdb9, + 0x014d04be, 0x041bfecc, 0xf947f978, 0x00900897, + 0x095a00b9, 0xf600f3c5, 0xfd650aa3, 0x0ebc04de, + 0xf5aaef8e, 0xf8d5091c, 0x110d0000, + }, { // 8.1 MHz + 0x0000ffff, 0xfff7fff6, 0x000e0038, 0x0037ffd7, + 0xff52ff56, 0x004b0184, 0x0186ffa1, 0xfd40fd16, + 0x00440452, 0x04de0029, 0xf9f2f8b2, 0xfefe07b5, + 0x0a05024d, 0xf6fef34d, 0xfc0a09b8, 0x0efa05cd, + 0xf64eef7d, 0xf87308ed, 0x110d0000, + }, { // 8.2 MHz + 0x00010000, 0xfff8fff0, 0x00000031, 0x004c0005, + 0xff6aff27, 0xffe4014a, 0x01d70057, 0xfdacfca6, + 0xff3603a7, 0x05610184, 0xfadbf82e, 0xfd74069f, + 0x0a7503d6, 0xf81ff2ff, 0xfab808b9, 0x0f2306b5, + 0xf6f9ef72, 0xf81308bf, 0x110d0000, + }, { // 8.3 MHz + 0x00010001, 0xfffbffee, 0xfff30022, 0x00560032, + 0xff95ff10, 0xff8000f0, 0x01fe0106, 0xfe46fc71, + 0xfe3502c7, 0x059e02ce, 0xfbf9f7f2, 0xfbff055b, + 0x0aa9054c, 0xf961f2db, 0xf97507aa, 0x0f350797, + 0xf7a9ef6d, 0xf7b40890, 0x110d0000, + }, { // 8.4 MHz + 0x00010002, 0xfffeffee, 0xffe8000f, 0x00540058, + 0xffcdff14, 0xff29007e, 0x01f6019e, 0xff01fc7c, + 0xfd5101bf, 0x059203f6, 0xfd41f7fe, 0xfaa903f3, + 0x0a9e06a9, 0xfabdf2e2, 0xf842068b, 0x0f320871, + 0xf85eef6e, 0xf7560860, 0x110d0000, + }, { // 8.5 MHz + 0x00000003, 0x0002fff2, 0xffe1fff9, 0x00460073, + 0x000bff34, 0xfee90000, 0x01c10215, 0xffd0fcc5, + 0xfc99009d, 0x053d04f1, 0xfea5f853, 0xf97d0270, + 0x0a5607e4, 0xfc2ef314, 0xf723055f, 0x0f180943, + 0xf919ef75, 0xf6fa0830, 0x110d0000, + }, { // 8.6 MHz + 0x00000003, 0x0005fff8, 0xffdeffe4, 0x002f007f, + 0x0048ff6b, 0xfec7ff82, 0x0163025f, 0x00a2fd47, + 0xfc17ff73, 0x04a405b2, 0x0017f8ed, 0xf88500dc, + 0x09d208f9, 0xfdaff370, 0xf61c0429, 0x0ee80a0b, + 0xf9d8ef82, 0xf6a00800, 0x110d0000, + }, { // 8.7 MHz + 0x00000003, 0x0007ffff, 0xffe1ffd4, 0x0010007a, + 0x007cffb2, 0xfec6ff10, 0x00e60277, 0x0168fdf9, + 0xfbd3fe50, 0x03ce0631, 0x0188f9c8, 0xf7c7ff43, + 0x091509e3, 0xff39f3f6, 0xf52d02ea, 0x0ea30ac9, + 0xfa9bef95, 0xf64607d0, 0x110d0000, + }, { // 8.8 MHz + 0x00000002, 0x00090007, 0xffe9ffca, 0xfff00065, + 0x00a10003, 0xfee6feb6, 0x0053025b, 0x0213fed0, + 0xfbd3fd46, 0x02c70668, 0x02eafadb, 0xf74bfdae, + 0x08230a9c, 0x00c7f4a3, 0xf45b01a6, 0x0e480b7c, + 0xfb61efae, 0xf5ef079f, 0x110d0000, + }, { // 8.9 MHz + 0xffff0000, 0x0008000d, 0xfff5ffc8, 0xffd10043, + 0x00b20053, 0xff24fe7c, 0xffb9020c, 0x0295ffbb, + 0xfc17fc64, 0x019b0654, 0x042dfc1c, 0xf714fc2a, + 0x07020b21, 0x0251f575, 0xf3a7005e, 0x0dd80c24, + 0xfc2aefcd, 0xf599076e, 0x110d0000, + }, { // 9.0 MHz + 0xffffffff, 0x00060011, 0x0002ffcf, 0xffba0018, + 0x00ad009a, 0xff79fe68, 0xff260192, 0x02e500ab, + 0xfc99fbb6, 0x005b05f7, 0x0545fd81, 0xf723fabf, + 0x05b80b70, 0x03d2f669, 0xf313ff15, 0x0d550cbf, + 0xfcf6eff2, 0xf544073d, 0x110d0000, + }, { // 9.1 MHz + 0xfffffffe, 0x00030012, 0x000fffdd, 0xffacffea, + 0x009300cf, 0xffdcfe7c, 0xfea600f7, 0x02fd0190, + 0xfd51fb46, 0xff150554, 0x0627fefd, 0xf778f978, + 0x044d0b87, 0x0543f77d, 0xf2a0fdcf, 0x0cbe0d4e, + 0xfdc4f01d, 0xf4f2070b, 0x110d0000, + }, { // 9.2 MHz + 0x0000fffd, 0x00000010, 0x001afff0, 0xffaaffbf, + 0x006700ed, 0x0043feb6, 0xfe460047, 0x02db0258, + 0xfe35fb1b, 0xfddc0473, 0x06c90082, 0xf811f85e, + 0x02c90b66, 0x069ff8ad, 0xf250fc8d, 0x0c140dcf, + 0xfe93f04d, 0xf4a106d9, 0x110d0000, + }, { // 9.3 MHz + 0x0000fffd, 0xfffc000c, 0x00200006, 0xffb4ff9c, + 0x002f00ef, 0x00a4ff10, 0xfe0dff92, 0x028102f7, + 0xff36fb37, 0xfcbf035e, 0x07260202, 0xf8e8f778, + 0x01340b0d, 0x07e1f9f4, 0xf223fb51, 0x0b590e42, + 0xff64f083, 0xf45206a7, 0x110d0000, + }, { // 9.4 MHz + 0x0000fffd, 0xfff90005, 0x0022001a, 0xffc9ff86, + 0xfff000d7, 0x00f2ff82, 0xfe01fee5, 0x01f60362, + 0x0044fb99, 0xfbcc0222, 0x07380370, 0xf9f7f6cc, + 0xff990a7e, 0x0902fb50, 0xf21afa1f, 0x0a8d0ea6, + 0x0034f0bf, 0xf4050675, 0x110d0000, + }, { // 9.5 MHz + 0x0000fffe, 0xfff8fffe, 0x001e002b, 0xffe5ff81, + 0xffb400a5, 0x01280000, 0xfe24fe50, 0x01460390, + 0x014dfc3a, 0xfb1000ce, 0x070104bf, 0xfb37f65f, + 0xfe0009bc, 0x0a00fcbb, 0xf235f8f8, 0x09b20efc, + 0x0105f101, 0xf3ba0642, 0x110d0000, + }, { // 9.6 MHz + 0x0001ffff, 0xfff8fff7, 0x00150036, 0x0005ff8c, + 0xff810061, 0x013d007e, 0xfe71fddf, 0x007c0380, + 0x0241fd13, 0xfa94ff70, 0x068005e2, 0xfc9bf633, + 0xfc7308ca, 0x0ad5fe30, 0xf274f7e0, 0x08c90f43, + 0x01d4f147, 0xf371060f, 0x110d0000, + }, { // 9.7 MHz + 0x00010001, 0xfff9fff1, 0x00090038, 0x0025ffa7, + 0xff5e0012, 0x013200f0, 0xfee3fd9b, 0xffaa0331, + 0x0311fe15, 0xfa60fe18, 0x05bd06d1, 0xfe1bf64a, + 0xfafa07ae, 0x0b7effab, 0xf2d5f6d7, 0x07d30f7a, + 0x02a3f194, 0xf32905dc, 0x110d0000, + }, { // 9.8 MHz + 0x00010002, 0xfffcffee, 0xfffb0032, 0x003fffcd, + 0xff4effc1, 0x0106014a, 0xff6efd8a, 0xfedd02aa, + 0x03b0ff34, 0xfa74fcd7, 0x04bf0781, 0xffaaf6a3, + 0xf99e066b, 0x0bf90128, 0xf359f5e1, 0x06d20fa2, + 0x0370f1e5, 0xf2e405a8, 0x110d0000, + }, { // 9.9 MHz + 0x00000003, 0xffffffee, 0xffef0024, 0x0051fffa, + 0xff54ff77, 0x00be0184, 0x0006fdad, 0xfe2701f3, + 0x0413005e, 0xfad1fbba, 0x039007ee, 0x013bf73d, + 0xf868050a, 0x0c4302a1, 0xf3fdf4fe, 0x05c70fba, + 0x043bf23c, 0xf2a10575, 0x110d0000, + }, { // 10.0 MHz + 0x00000003, 0x0003fff1, 0xffe50011, 0x00570027, + 0xff70ff3c, 0x00620198, 0x009efe01, 0xfd95011a, + 0x04350183, 0xfb71fad0, 0x023c0812, 0x02c3f811, + 0xf75e0390, 0x0c5c0411, 0xf4c1f432, 0x04b30fc1, + 0x0503f297, 0xf2610541, 0x110d0000, + }, { // 10.1 MHz + 0x00000003, 0x0006fff7, 0xffdffffc, 0x00510050, + 0xff9dff18, 0xfffc0184, 0x0128fe80, 0xfd32002e, + 0x04130292, 0xfc4dfa21, 0x00d107ee, 0x0435f91c, + 0xf6850205, 0x0c430573, 0xf5a1f37d, 0x03990fba, + 0x05c7f2f8, 0xf222050d, 0x110d0000, + }, { // 10.2 MHz + 0x00000002, 0x0008fffe, 0xffdfffe7, 0x003f006e, + 0xffd6ff0f, 0xff96014a, 0x0197ff1f, 0xfd05ff3e, + 0x03b0037c, 0xfd59f9b7, 0xff5d0781, 0x0585fa56, + 0xf5e4006f, 0x0bf906c4, 0xf69df2e0, 0x02790fa2, + 0x0688f35d, 0xf1e604d8, 0x110d0000, + }, { // 10.3 MHz + 0xffff0001, 0x00090005, 0xffe4ffd6, 0x0025007e, + 0x0014ff20, 0xff3c00f0, 0x01e1ffd0, 0xfd12fe5c, + 0x03110433, 0xfe88f996, 0xfdf106d1, 0x06aafbb7, + 0xf57efed8, 0x0b7e07ff, 0xf7b0f25e, 0x01560f7a, + 0x0745f3c7, 0xf1ac04a4, 0x110d0000, + }, { // 10.4 MHz + 0xffffffff, 0x0008000c, 0xffedffcb, 0x0005007d, + 0x0050ff4c, 0xfef6007e, 0x01ff0086, 0xfd58fd97, + 0x024104ad, 0xffcaf9c0, 0xfc9905e2, 0x079afd35, + 0xf555fd46, 0x0ad50920, 0xf8d9f1f6, 0x00310f43, + 0x07fdf435, 0xf174046f, 0x110d0000, + }, { // 10.5 MHz + 0xfffffffe, 0x00050011, 0xfffaffc8, 0xffe5006b, + 0x0082ff8c, 0xfecc0000, 0x01f00130, 0xfdd2fcfc, + 0x014d04e3, 0x010efa32, 0xfb6404bf, 0x084efec5, + 0xf569fbc2, 0x0a000a23, 0xfa15f1ab, 0xff0b0efc, + 0x08b0f4a7, 0xf13f043a, 0x110d0000, + }, { // 10.6 MHz + 0x0000fffd, 0x00020012, 0x0007ffcd, 0xffc9004c, + 0x00a4ffd9, 0xfec3ff82, 0x01b401c1, 0xfe76fc97, + 0x004404d2, 0x0245fae8, 0xfa5f0370, 0x08c1005f, + 0xf5bcfa52, 0x09020b04, 0xfb60f17b, 0xfde70ea6, + 0x095df51e, 0xf10c0405, 0x110d0000, + }, { // 10.7 MHz + 0x0000fffd, 0xffff0011, 0x0014ffdb, 0xffb40023, + 0x00b2002a, 0xfedbff10, 0x0150022d, 0xff38fc6f, + 0xff36047b, 0x035efbda, 0xf9940202, 0x08ee01f5, + 0xf649f8fe, 0x07e10bc2, 0xfcb6f169, 0xfcc60e42, + 0x0a04f599, 0xf0db03d0, 0x110d0000, + }, { // 10.8 MHz + 0x0000fffd, 0xfffb000d, 0x001dffed, 0xffaafff5, + 0x00aa0077, 0xff13feb6, 0x00ce026b, 0x000afc85, + 0xfe3503e3, 0x044cfcfb, 0xf90c0082, 0x08d5037f, + 0xf710f7cc, 0x069f0c59, 0xfe16f173, 0xfbaa0dcf, + 0x0aa5f617, 0xf0ad039b, 0x110d0000, + }, { // 10.9 MHz + 0x0000fffe, 0xfff90006, 0x00210003, 0xffacffc8, + 0x008e00b6, 0xff63fe7c, 0x003a0275, 0x00dafcda, + 0xfd510313, 0x0501fe40, 0xf8cbfefd, 0x087604f0, + 0xf80af6c2, 0x05430cc8, 0xff7af19a, 0xfa940d4e, + 0x0b3ff699, 0xf0810365, 0x110d0000, + }, { // 11.0 MHz + 0x0001ffff, 0xfff8ffff, 0x00210018, 0xffbaffa3, + 0x006000e1, 0xffc4fe68, 0xffa0024b, 0x019afd66, + 0xfc990216, 0x0575ff99, 0xf8d4fd81, 0x07d40640, + 0xf932f5e6, 0x03d20d0d, 0x00dff1de, 0xf9860cbf, + 0x0bd1f71e, 0xf058032f, 0x110d0000, + }, { // 11.1 MHz + 0x00010000, 0xfff8fff8, 0x001b0029, 0xffd1ff8a, + 0x002600f2, 0x002cfe7c, 0xff0f01f0, 0x023bfe20, + 0xfc1700fa, 0x05a200f7, 0xf927fc1c, 0x06f40765, + 0xfa82f53b, 0x02510d27, 0x0243f23d, 0xf8810c24, + 0x0c5cf7a7, 0xf03102fa, 0x110d0000, + }, { // 11.2 MHz + 0x00010002, 0xfffafff2, 0x00110035, 0xfff0ff81, + 0xffe700e7, 0x008ffeb6, 0xfe94016d, 0x02b0fefb, + 0xfbd3ffd1, 0x05850249, 0xf9c1fadb, 0x05de0858, + 0xfbf2f4c4, 0x00c70d17, 0x03a0f2b8, 0xf7870b7c, + 0x0cdff833, 0xf00d02c4, 0x110d0000, + }, { // 11.3 MHz + 0x00000003, 0xfffdffee, 0x00040038, 0x0010ff88, + 0xffac00c2, 0x00e2ff10, 0xfe3900cb, 0x02f1ffe9, + 0xfbd3feaa, 0x05210381, 0xfa9cf9c8, 0x04990912, + 0xfd7af484, 0xff390cdb, 0x04f4f34d, 0xf69a0ac9, + 0x0d5af8c1, 0xefec028e, 0x110d0000, + }, { // 11.4 MHz + 0x00000003, 0x0000ffee, 0xfff60033, 0x002fff9f, + 0xff7b0087, 0x011eff82, 0xfe080018, 0x02f900d8, + 0xfc17fd96, 0x04790490, 0xfbadf8ed, 0x032f098e, + 0xff10f47d, 0xfdaf0c75, 0x063cf3fc, 0xf5ba0a0b, + 0x0dccf952, 0xefcd0258, 0x110d0000, + }, { // 11.5 MHz + 0x00000003, 0x0004fff1, 0xffea0026, 0x0046ffc3, + 0xff5a003c, 0x013b0000, 0xfe04ff63, 0x02c801b8, + 0xfc99fca6, 0x0397056a, 0xfcecf853, 0x01ad09c9, + 0x00acf4ad, 0xfc2e0be7, 0x0773f4c2, 0xf4e90943, + 0x0e35f9e6, 0xefb10221, 0x110d0000, + }, { // 11.6 MHz + 0x00000002, 0x0007fff6, 0xffe20014, 0x0054ffee, + 0xff4effeb, 0x0137007e, 0xfe2efebb, 0x0260027a, + 0xfd51fbe6, 0x02870605, 0xfe4af7fe, 0x001d09c1, + 0x0243f515, 0xfabd0b32, 0x0897f59e, 0xf4280871, + 0x0e95fa7c, 0xef9701eb, 0x110d0000, + }, { // 11.7 MHz + 0xffff0001, 0x0008fffd, 0xffdeffff, 0x0056001d, + 0xff57ff9c, 0x011300f0, 0xfe82fe2e, 0x01ca0310, + 0xfe35fb62, 0x0155065a, 0xffbaf7f2, 0xfe8c0977, + 0x03cef5b2, 0xf9610a58, 0x09a5f68f, 0xf3790797, + 0x0eebfb14, 0xef8001b5, 0x110d0000, + }, { // 11.8 MHz + 0xffff0000, 0x00080004, 0xffe0ffe9, 0x004c0047, + 0xff75ff58, 0x00d1014a, 0xfef9fdc8, 0x0111036f, + 0xff36fb21, 0x00120665, 0x012df82e, 0xfd0708ec, + 0x0542f682, 0xf81f095c, 0x0a9af792, 0xf2db06b5, + 0x0f38fbad, 0xef6c017e, 0x110d0000, + }, { // 11.9 MHz + 0xffffffff, 0x0007000b, 0xffe7ffd8, 0x00370068, + 0xffa4ff28, 0x00790184, 0xff87fd91, 0x00430392, + 0x0044fb26, 0xfece0626, 0x0294f8b2, 0xfb990825, + 0x0698f77f, 0xf6fe0842, 0x0b73f8a7, 0xf25105cd, + 0x0f7bfc48, 0xef5a0148, 0x110d0000, + }, { // 12.0 MHz + 0x0000fffe, 0x00050010, 0xfff2ffcc, 0x001b007b, + 0xffdfff10, 0x00140198, 0x0020fd8e, 0xff710375, + 0x014dfb73, 0xfd9a059f, 0x03e0f978, 0xfa4e0726, + 0x07c8f8a7, 0xf600070c, 0x0c2ff9c9, 0xf1db04de, + 0x0fb4fce5, 0xef4b0111, 0x110d0000, + }, { // 12.1 MHz + 0x0000fffd, 0x00010012, 0xffffffc8, 0xfffb007e, + 0x001dff14, 0xffad0184, 0x00b7fdbe, 0xfea9031b, + 0x0241fc01, 0xfc8504d6, 0x0504fa79, 0xf93005f6, + 0x08caf9f2, 0xf52b05c0, 0x0ccbfaf9, 0xf17903eb, + 0x0fe3fd83, 0xef3f00db, 0x110d0000, + }, { // 12.2 MHz + 0x0000fffd, 0xfffe0011, 0x000cffcc, 0xffdb0071, + 0x0058ff32, 0xff4f014a, 0x013cfe1f, 0xfdfb028a, + 0x0311fcc9, 0xfb9d03d6, 0x05f4fbad, 0xf848049d, + 0x0999fb5b, 0xf4820461, 0x0d46fc32, 0xf12d02f4, + 0x1007fe21, 0xef3600a4, 0x110d0000, + }, { // 12.3 MHz + 0x0000fffe, 0xfffa000e, 0x0017ffd9, 0xffc10055, + 0x0088ff68, 0xff0400f0, 0x01a6fea7, 0xfd7501cc, + 0x03b0fdc0, 0xfaef02a8, 0x06a7fd07, 0xf79d0326, + 0x0a31fcda, 0xf40702f3, 0x0d9ffd72, 0xf0f601fa, + 0x1021fec0, 0xef2f006d, 0x110d0000, + }, { // 12.4 MHz + 0x0001ffff, 0xfff80007, 0x001fffeb, 0xffaf002d, + 0x00a8ffb0, 0xfed3007e, 0x01e9ff4c, 0xfd2000ee, + 0x0413fed8, 0xfa82015c, 0x0715fe7d, 0xf7340198, + 0x0a8dfe69, 0xf3bd017c, 0x0dd5feb8, 0xf0d500fd, + 0x1031ff60, 0xef2b0037, 0x110d0000, + }, { // 12.5 MHz + 0x00010000, 0xfff70000, 0x00220000, 0xffa90000, + 0x00b30000, 0xfec20000, 0x02000000, 0xfd030000, + 0x04350000, 0xfa5e0000, 0x073b0000, 0xf7110000, + 0x0aac0000, 0xf3a40000, 0x0de70000, 0xf0c90000, + 0x10360000, 0xef290000, 0x110d0000, + }, { // 12.6 MHz + 0x00010001, 0xfff8fff9, 0x001f0015, 0xffafffd3, + 0x00a80050, 0xfed3ff82, 0x01e900b4, 0xfd20ff12, + 0x04130128, 0xfa82fea4, 0x07150183, 0xf734fe68, + 0x0a8d0197, 0xf3bdfe84, 0x0dd50148, 0xf0d5ff03, + 0x103100a0, 0xef2bffc9, 0x110d0000, + }, { // 12.7 MHz + 0x00000002, 0xfffafff2, 0x00170027, 0xffc1ffab, + 0x00880098, 0xff04ff10, 0x01a60159, 0xfd75fe34, + 0x03b00240, 0xfaeffd58, 0x06a702f9, 0xf79dfcda, + 0x0a310326, 0xf407fd0d, 0x0d9f028e, 0xf0f6fe06, + 0x10210140, 0xef2fff93, 0x110d0000, + }, { // 12.8 MHz + 0x00000003, 0xfffeffef, 0x000c0034, 0xffdbff8f, + 0x005800ce, 0xff4ffeb6, 0x013c01e1, 0xfdfbfd76, + 0x03110337, 0xfb9dfc2a, 0x05f40453, 0xf848fb63, + 0x099904a5, 0xf482fb9f, 0x0d4603ce, 0xf12dfd0c, + 0x100701df, 0xef36ff5c, 0x110d0000, + }, { // 12.9 MHz + 0x00000003, 0x0001ffee, 0xffff0038, 0xfffbff82, + 0x001d00ec, 0xffadfe7c, 0x00b70242, 0xfea9fce5, + 0x024103ff, 0xfc85fb2a, 0x05040587, 0xf930fa0a, + 0x08ca060e, 0xf52bfa40, 0x0ccb0507, 0xf179fc15, + 0x0fe3027d, 0xef3fff25, 0x110d0000, + }, { // 13.0 MHz + 0x00000002, 0x0005fff0, 0xfff20034, 0x001bff85, + 0xffdf00f0, 0x0014fe68, 0x00200272, 0xff71fc8b, + 0x014d048d, 0xfd9afa61, 0x03e00688, 0xfa4ef8da, + 0x07c80759, 0xf600f8f4, 0x0c2f0637, 0xf1dbfb22, + 0x0fb4031b, 0xef4bfeef, 0x110d0000, + }, { // 13.1 MHz + 0xffff0001, 0x0007fff5, 0xffe70028, 0x0037ff98, + 0xffa400d8, 0x0079fe7c, 0xff87026f, 0x0043fc6e, + 0x004404da, 0xfecef9da, 0x0294074e, 0xfb99f7db, + 0x06980881, 0xf6fef7be, 0x0b730759, 0xf251fa33, + 0x0f7b03b8, 0xef5afeb8, 0x110d0000, + }, { // 13.2 MHz + 0xffff0000, 0x0008fffc, 0xffe00017, 0x004cffb9, + 0xff7500a8, 0x00d1feb6, 0xfef90238, 0x0111fc91, + 0xff3604df, 0x0012f99b, 0x012d07d2, 0xfd07f714, + 0x0542097e, 0xf81ff6a4, 0x0a9a086e, 0xf2dbf94b, + 0x0f380453, 0xef6cfe82, 0x110d0000, + }, { // 13.3 MHz + 0xffffffff, 0x00080003, 0xffde0001, 0x0056ffe3, + 0xff570064, 0x0113ff10, 0xfe8201d2, 0x01cafcf0, + 0xfe35049e, 0x0155f9a6, 0xffba080e, 0xfe8cf689, + 0x03ce0a4e, 0xf961f5a8, 0x09a50971, 0xf379f869, + 0x0eeb04ec, 0xef80fe4b, 0x110d0000, + }, { // 13.4 MHz + 0x0000fffe, 0x0007000a, 0xffe2ffec, 0x00540012, + 0xff4e0015, 0x0137ff82, 0xfe2e0145, 0x0260fd86, + 0xfd51041a, 0x0287f9fb, 0xfe4a0802, 0x001df63f, + 0x02430aeb, 0xfabdf4ce, 0x08970a62, 0xf428f78f, + 0x0e950584, 0xef97fe15, 0x110d0000, + }, { // 13.5 MHz + 0x0000fffd, 0x0004000f, 0xffeaffda, 0x0046003d, + 0xff5affc4, 0x013b0000, 0xfe04009d, 0x02c8fe48, + 0xfc99035a, 0x0397fa96, 0xfcec07ad, 0x01adf637, + 0x00ac0b53, 0xfc2ef419, 0x07730b3e, 0xf4e9f6bd, + 0x0e35061a, 0xefb1fddf, 0x110d0000, + }, { // 13.6 MHz + 0x0000fffd, 0x00000012, 0xfff6ffcd, 0x002f0061, + 0xff7bff79, 0x011e007e, 0xfe08ffe8, 0x02f9ff28, + 0xfc17026a, 0x0479fb70, 0xfbad0713, 0x032ff672, + 0xff100b83, 0xfdaff38b, 0x063c0c04, 0xf5baf5f5, + 0x0dcc06ae, 0xefcdfda8, 0x110d0000, + }, { // 13.7 MHz + 0x0000fffd, 0xfffd0012, 0x0004ffc8, 0x00100078, + 0xffacff3e, 0x00e200f0, 0xfe39ff35, 0x02f10017, + 0xfbd30156, 0x0521fc7f, 0xfa9c0638, 0x0499f6ee, + 0xfd7a0b7c, 0xff39f325, 0x04f40cb3, 0xf69af537, + 0x0d5a073f, 0xefecfd72, 0x110d0000, + }, { // 13.8 MHz + 0x0001fffe, 0xfffa000e, 0x0011ffcb, 0xfff0007f, + 0xffe7ff19, 0x008f014a, 0xfe94fe93, 0x02b00105, + 0xfbd3002f, 0x0585fdb7, 0xf9c10525, 0x05def7a8, + 0xfbf20b3c, 0x00c7f2e9, 0x03a00d48, 0xf787f484, + 0x0cdf07cd, 0xf00dfd3c, 0x110d0000, + }, { // 13.9 MHz + 0x00010000, 0xfff80008, 0x001bffd7, 0xffd10076, + 0x0026ff0e, 0x002c0184, 0xff0ffe10, 0x023b01e0, + 0xfc17ff06, 0x05a2ff09, 0xf92703e4, 0x06f4f89b, + 0xfa820ac5, 0x0251f2d9, 0x02430dc3, 0xf881f3dc, + 0x0c5c0859, 0xf031fd06, 0x110d0000, + }, { // 14.0 MHz + 0x00010001, 0xfff80001, 0x0021ffe8, 0xffba005d, + 0x0060ff1f, 0xffc40198, 0xffa0fdb5, 0x019a029a, + 0xfc99fdea, 0x05750067, 0xf8d4027f, 0x07d4f9c0, + 0xf9320a1a, 0x03d2f2f3, 0x00df0e22, 0xf986f341, + 0x0bd108e2, 0xf058fcd1, 0x110d0000, + }, { // 14.1 MHz + 0x00000002, 0xfff9fffa, 0x0021fffd, 0xffac0038, + 0x008eff4a, 0xff630184, 0x003afd8b, 0x00da0326, + 0xfd51fced, 0x050101c0, 0xf8cb0103, 0x0876fb10, + 0xf80a093e, 0x0543f338, 0xff7a0e66, 0xfa94f2b2, + 0x0b3f0967, 0xf081fc9b, 0x110d0000, + }, { // 14.2 MHz + 0x00000003, 0xfffbfff3, 0x001d0013, 0xffaa000b, + 0x00aaff89, 0xff13014a, 0x00cefd95, 0x000a037b, + 0xfe35fc1d, 0x044c0305, 0xf90cff7e, 0x08d5fc81, + 0xf7100834, 0x069ff3a7, 0xfe160e8d, 0xfbaaf231, + 0x0aa509e9, 0xf0adfc65, 0x110d0000, + }, { // 14.3 MHz + 0x00000003, 0xffffffef, 0x00140025, 0xffb4ffdd, + 0x00b2ffd6, 0xfedb00f0, 0x0150fdd3, 0xff380391, + 0xff36fb85, 0x035e0426, 0xf994fdfe, 0x08eefe0b, + 0xf6490702, 0x07e1f43e, 0xfcb60e97, 0xfcc6f1be, + 0x0a040a67, 0xf0dbfc30, 0x110d0000, + }, { // 14.4 MHz + 0x00000003, 0x0002ffee, 0x00070033, 0xffc9ffb4, + 0x00a40027, 0xfec3007e, 0x01b4fe3f, 0xfe760369, + 0x0044fb2e, 0x02450518, 0xfa5ffc90, 0x08c1ffa1, + 0xf5bc05ae, 0x0902f4fc, 0xfb600e85, 0xfde7f15a, + 0x095d0ae2, 0xf10cfbfb, 0x110d0000, + }, { // 14.5 MHz + 0xffff0002, 0x0005ffef, 0xfffa0038, 0xffe5ff95, + 0x00820074, 0xfecc0000, 0x01f0fed0, 0xfdd20304, + 0x014dfb1d, 0x010e05ce, 0xfb64fb41, 0x084e013b, + 0xf569043e, 0x0a00f5dd, 0xfa150e55, 0xff0bf104, + 0x08b00b59, 0xf13ffbc6, 0x110d0000, + }, { // 14.6 MHz + 0xffff0001, 0x0008fff4, 0xffed0035, 0x0005ff83, + 0x005000b4, 0xfef6ff82, 0x01ffff7a, 0xfd580269, + 0x0241fb53, 0xffca0640, 0xfc99fa1e, 0x079a02cb, + 0xf55502ba, 0x0ad5f6e0, 0xf8d90e0a, 0x0031f0bd, + 0x07fd0bcb, 0xf174fb91, 0x110d0000, + }, { // 14.7 MHz + 0xffffffff, 0x0009fffb, 0xffe4002a, 0x0025ff82, + 0x001400e0, 0xff3cff10, 0x01e10030, 0xfd1201a4, + 0x0311fbcd, 0xfe88066a, 0xfdf1f92f, 0x06aa0449, + 0xf57e0128, 0x0b7ef801, 0xf7b00da2, 0x0156f086, + 0x07450c39, 0xf1acfb5c, 0x110d0000, + }, { // 14.8 MHz + 0x0000fffe, 0x00080002, 0xffdf0019, 0x003fff92, + 0xffd600f1, 0xff96feb6, 0x019700e1, 0xfd0500c2, + 0x03b0fc84, 0xfd590649, 0xff5df87f, 0x058505aa, + 0xf5e4ff91, 0x0bf9f93c, 0xf69d0d20, 0x0279f05e, + 0x06880ca3, 0xf1e6fb28, 0x110d0000, + }, { // 14.9 MHz + 0x0000fffd, 0x00060009, 0xffdf0004, 0x0051ffb0, + 0xff9d00e8, 0xfffcfe7c, 0x01280180, 0xfd32ffd2, + 0x0413fd6e, 0xfc4d05df, 0x00d1f812, 0x043506e4, + 0xf685fdfb, 0x0c43fa8d, 0xf5a10c83, 0x0399f046, + 0x05c70d08, 0xf222faf3, 0x110d0000, + }, { // 15.0 MHz + 0x0000fffd, 0x0003000f, 0xffe5ffef, 0x0057ffd9, + 0xff7000c4, 0x0062fe68, 0x009e01ff, 0xfd95fee6, + 0x0435fe7d, 0xfb710530, 0x023cf7ee, 0x02c307ef, + 0xf75efc70, 0x0c5cfbef, 0xf4c10bce, 0x04b3f03f, + 0x05030d69, 0xf261fabf, 0x110d0000, + }, { // 15.1 MHz + 0x0000fffd, 0xffff0012, 0xffefffdc, 0x00510006, + 0xff540089, 0x00befe7c, 0x00060253, 0xfe27fe0d, + 0x0413ffa2, 0xfad10446, 0x0390f812, 0x013b08c3, + 0xf868faf6, 0x0c43fd5f, 0xf3fd0b02, 0x05c7f046, + 0x043b0dc4, 0xf2a1fa8b, 0x110d0000, + }, { // 15.2 MHz + 0x0001fffe, 0xfffc0012, 0xfffbffce, 0x003f0033, + 0xff4e003f, 0x0106feb6, 0xff6e0276, 0xfeddfd56, + 0x03b000cc, 0xfa740329, 0x04bff87f, 0xffaa095d, + 0xf99ef995, 0x0bf9fed8, 0xf3590a1f, 0x06d2f05e, + 0x03700e1b, 0xf2e4fa58, 0x110d0000, + }, { // 15.3 MHz + 0x0001ffff, 0xfff9000f, 0x0009ffc8, 0x00250059, + 0xff5effee, 0x0132ff10, 0xfee30265, 0xffaafccf, + 0x031101eb, 0xfa6001e8, 0x05bdf92f, 0xfe1b09b6, + 0xfafaf852, 0x0b7e0055, 0xf2d50929, 0x07d3f086, + 0x02a30e6c, 0xf329fa24, 0x110d0000, + }, { // 15.4 MHz + 0x00010001, 0xfff80009, 0x0015ffca, 0x00050074, + 0xff81ff9f, 0x013dff82, 0xfe710221, 0x007cfc80, + 0x024102ed, 0xfa940090, 0x0680fa1e, 0xfc9b09cd, + 0xfc73f736, 0x0ad501d0, 0xf2740820, 0x08c9f0bd, + 0x01d40eb9, 0xf371f9f1, 0x110d0000, + }, { // 15.5 MHz + 0x00000002, 0xfff80002, 0x001effd5, 0xffe5007f, + 0xffb4ff5b, 0x01280000, 0xfe2401b0, 0x0146fc70, + 0x014d03c6, 0xfb10ff32, 0x0701fb41, 0xfb3709a1, + 0xfe00f644, 0x0a000345, 0xf2350708, 0x09b2f104, + 0x01050eff, 0xf3baf9be, 0x110d0000, + }, { // 15.6 MHz + 0x00000003, 0xfff9fffb, 0x0022ffe6, 0xffc9007a, + 0xfff0ff29, 0x00f2007e, 0xfe01011b, 0x01f6fc9e, + 0x00440467, 0xfbccfdde, 0x0738fc90, 0xf9f70934, + 0xff99f582, 0x090204b0, 0xf21a05e1, 0x0a8df15a, + 0x00340f41, 0xf405f98b, 0x110d0000, + }, { // 15.7 MHz + 0x00000003, 0xfffcfff4, 0x0020fffa, 0xffb40064, + 0x002fff11, 0x00a400f0, 0xfe0d006e, 0x0281fd09, + 0xff3604c9, 0xfcbffca2, 0x0726fdfe, 0xf8e80888, + 0x0134f4f3, 0x07e1060c, 0xf22304af, 0x0b59f1be, + 0xff640f7d, 0xf452f959, 0x110d0000, + }, { // 15.8 MHz + 0x00000003, 0x0000fff0, 0x001a0010, 0xffaa0041, + 0x0067ff13, 0x0043014a, 0xfe46ffb9, 0x02dbfda8, + 0xfe3504e5, 0xfddcfb8d, 0x06c9ff7e, 0xf81107a2, + 0x02c9f49a, 0x069f0753, 0xf2500373, 0x0c14f231, + 0xfe930fb3, 0xf4a1f927, 0x110d0000, + }, { // 15.9 MHz + 0xffff0002, 0x0003ffee, 0x000f0023, 0xffac0016, + 0x0093ff31, 0xffdc0184, 0xfea6ff09, 0x02fdfe70, + 0xfd5104ba, 0xff15faac, 0x06270103, 0xf7780688, + 0x044df479, 0x05430883, 0xf2a00231, 0x0cbef2b2, + 0xfdc40fe3, 0xf4f2f8f5, 0x110d0000, + }, { // 16.0 MHz + 0xffff0001, 0x0006ffef, 0x00020031, 0xffbaffe8, + 0x00adff66, 0xff790198, 0xff26fe6e, 0x02e5ff55, + 0xfc99044a, 0x005bfa09, 0x0545027f, 0xf7230541, + 0x05b8f490, 0x03d20997, 0xf31300eb, 0x0d55f341, + 0xfcf6100e, 0xf544f8c3, 0x110d0000, + } +}; + static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz) { u64 pll_freq; u32 pll_freq_word; + const u32 *coeffs; v4l_dbg(1, cx25840_debug, client, "%s(%d)\n", __func__, ifHz); @@ -2763,2889 +3554,26 @@ static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz) v4l_dbg(1, cx25840_debug, client, "%s(%d) again\n", __func__, ifHz); - switch (ifHz) { - case 3000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0024); - cx25840_write4(client, DIF_BPF_COEFF67, 0x001bfff8); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffb4ff50); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed8fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe24fe34); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfebaffc7); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d031f); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04f0065d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07010688); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x04c901d6); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe00f9d3); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f342); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf235f337); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf64efb22); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0105070f); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0c460fce); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00070012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00220032); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00370026); - cx25840_write4(client, DIF_BPF_COEFF89, 0xfff0ff91); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff0efe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01fdcc); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe0afedb); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440224); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0434060c); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0738074e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x06090361); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xff99fb39); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef3b6); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21af2a5); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf573fa33); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0034067d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0bfb0fb9); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0004000e); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00200038); - cx25840_write4(client, DIF_BPF_COEFF67, 0x004c004f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x002fffdf); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff5cfeb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0dfd92); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd7ffe03); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36010a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x03410575); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x072607d2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x071804d5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0134fcb7); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff451); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf223f22e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4a7f94b); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xff6405e8); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0bae0fa4); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00000008); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001a0036); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0056006d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00670030); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffbdff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe46fd8d); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd25fd4f); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35ffe0); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0224049f); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c9080e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x07ef0627); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c9fe45); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f513); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf250f1d2); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3ecf869); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe930552); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0b5f0f8f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd0001); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000f002c); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0054007d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0093007c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0024ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea6fdbb); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd03fcca); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51feb9); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x00eb0392); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06270802); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08880750); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x044dffdb); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf5f8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a0f193); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf342f78f); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc404b9); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0b0e0f78); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff9); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0002001b); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0046007d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00ad00ba); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00870000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff26fe1a); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd1bfc7e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fda4); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xffa5025c); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x054507ad); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08dd0847); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b80172); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef6ff); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf313f170); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2abf6bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6041f); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0abc0f61); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff3); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff50006); - cx25840_write4(client, DIF_BPF_COEFF67, 0x002f006c); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b200e3); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00dc007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffb9fea0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd6bfc71); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fcb1); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe65010b); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x042d0713); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08ec0906); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x07020302); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff823); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3a7f16a); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf228f5f5); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfc2a0384); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0a670f4a); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7ffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe9fff1); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0010004d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a100f2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x011a00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0053ff44); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdedfca2); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fbef); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd39ffae); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x02ea0638); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08b50987); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x08230483); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f960); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf45bf180); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1b8f537); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfb6102e7); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x0a110f32); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffdd); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfff00024); - cx25840_write4(client, DIF_BPF_COEFF89, 0x007c00e5); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013a014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00e6fff8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe98fd0f); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fb67); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc32fe54); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x01880525); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x083909c7); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x091505ee); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7fab3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf52df1b4); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf15df484); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfa9b0249); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x09ba0f19); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 3900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbfff0); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffcf); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1fff6); - cx25840_write4(client, DIF_BPF_COEFF89, 0x004800be); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01390184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x016300ac); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff5efdb1); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fb23); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb5cfd0d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x001703e4); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x077b09c4); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x09d2073c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251fc18); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf61cf203); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf118f3dc); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf9d801aa); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x09600eff); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffefff4); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffca); - cx25840_write4(client, DIF_BPF_COEFF89, 0x000b0082); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01170198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01c10152); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0030fe7b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fb24); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfac3fbe9); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfea5027f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0683097f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a560867); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2fd89); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf723f26f); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0e8f341); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf919010a); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x09060ee5); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0002fffb); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe8ffca); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffa4); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffcd0036); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d70184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f601dc); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00ffff60); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb6d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa6efaf5); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd410103); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x055708f9); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a9e0969); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543ff02); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf842f2f5); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0cef2b2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf85e006b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x08aa0ecb); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00050003); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff3ffd3); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaff8b); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff95ffe5); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0080014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fe023f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01ba0050); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fbf8); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa62fa3b); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbf9ff7e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x04010836); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aa90a3d); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f007f); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf975f395); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0cbf231); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf7a9ffcb); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x084c0eaf); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000a); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0000ffe4); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ff81); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff6aff96); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x001c00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01d70271); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0254013b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fcbd); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa9ff9c5); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfadbfdfe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x028c073b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a750adf); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e101fa); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfab8f44e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0ddf1be); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf6f9ff2b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x07ed0e94); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0009000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000efff8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ff87); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff52ff54); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffb5007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01860270); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c00210); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fdb2); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb22f997); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9f2fc90); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0102060f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a050b4c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902036e); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfc0af51e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf106f15a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf64efe8b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x078d0e77); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0019000e); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff9e); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4fff25); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff560000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0112023b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f702c0); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfec8); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbe5f9b3); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf947fb41); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xff7004b9); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x095a0b81); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a0004d8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfd65f603); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf144f104); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf5aafdec); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x072b0e5a); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00060012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00200022); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ffc1); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff61ff10); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff09ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x008601d7); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f50340); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fff0); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcddfa19); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8e2fa1e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfde30343); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x08790b7f); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50631); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfec7f6fc); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf198f0bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf50dfd4e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x06c90e3d); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0003000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00220030); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ffed); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff87ff15); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed6ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffed014c); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b90386); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110119); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfdfefac4); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8c6f92f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc6701b7); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x07670b44); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0776); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x002df807); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf200f086); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf477fcb1); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x06650e1e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0009); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0038); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003f001b); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffbcff36); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec2feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff5600a5); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0248038d); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00232); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xff39fbab); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8f4f87f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb060020); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x062a0ad2); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf908a3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0192f922); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf27df05e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf3e8fc14); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x06000e00); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 4900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc0002); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00160037); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00510046); - cx25840_write4(client, DIF_BPF_COEFF89, 0xfff9ff6d); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed0fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfecefff0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01aa0356); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413032b); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x007ffcc5); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf96cf812); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9cefe87); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x04c90a2c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c4309b4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x02f3fa4a); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf30ef046); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf361fb7a); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x059b0de0); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffa); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000a002d); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00570067); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0037ffb5); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfefffe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe62ff3d); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00ec02e3); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x043503f6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x01befe05); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa27f7ee); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8c6fcf8); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x034c0954); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5c0aa4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x044cfb7e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3b1f03f); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf2e2fae1); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x05340dc0); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff4); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffd001e); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0051007b); - cx25840_write4(client, DIF_BPF_COEFF89, 0x006e0006); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff48fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe1bfe9a); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x001d023e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130488); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x02e6ff5b); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb1ef812); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7f7fb7f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x01bc084e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c430b72); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x059afcba); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf467f046); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf26cfa4a); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x04cd0da0); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8ffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff00009); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003f007f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00980056); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffa5feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe00fe15); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff4b0170); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b004d7); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x03e800b9); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc48f87f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf768fa23); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0022071f); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf90c1b); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x06dafdfd); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf52df05e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf1fef9b5); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x04640d7f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe6fff3); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00250072); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00af009c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x000cff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe13fdb8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe870089); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x031104e1); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04b8020f); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd98f92f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf71df8f0); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe8805ce); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0c9c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0808ff44); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf603f086); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf19af922); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x03fb0d5e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffe0); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00050056); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b000d1); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0071ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe53fd8c); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfddfff99); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104a3); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x054a034d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xff01fa1e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf717f7ed); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfcf50461); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50cf4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0921008d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf6e7f0bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf13ff891); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x03920d3b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffffff3); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffd1); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5002f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x009c00ed); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00cb0000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfebafd94); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd61feb0); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d0422); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05970464); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0074fb41); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf759f721); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfb7502de); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000d21); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a2201d4); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf7d9f104); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0edf804); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x03280d19); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0003fffa); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe3ffc9); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc90002); - cx25840_write4(client, DIF_BPF_COEFF89, 0x007500ef); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x010e007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff3dfdcf); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd16fddd); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440365); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x059b0548); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x01e3fc90); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7dff691); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa0f014d); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x09020d23); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b0a0318); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf8d7f15a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0a5f779); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x02bd0cf6); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00060001); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffecffc9); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ffd4); - cx25840_write4(client, DIF_BPF_COEFF89, 0x004000d5); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013600f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffd3fe39); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd04fd31); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff360277); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x055605ef); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x033efdfe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8a5f642); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf8cbffb6); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e10cfb); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0bd50456); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf9dff1be); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf067f6f2); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x02520cd2); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080009); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff8ffd2); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaffac); - cx25840_write4(client, DIF_BPF_COEFF89, 0x000200a3); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013c014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x006dfec9); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd2bfcb7); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe350165); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04cb0651); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0477ff7e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9a5f635); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7b1fe20); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0ca8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c81058b); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfaf0f231); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf033f66d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x01e60cae); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 5900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0009000e); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0005ffe1); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffacff90); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffc5005f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01210184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00fcff72); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd8afc77); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51003f); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04020669); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05830103); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfad7f66b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6c8fc93); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430c2b); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d0d06b5); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfc08f2b2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf00af5ec); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x017b0c89); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00070012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0012fff5); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaff82); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff8e000f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e80198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01750028); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe18fc75); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99ff15); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x03050636); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0656027f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc32f6e2); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf614fb17); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20b87); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d7707d2); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfd26f341); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefeaf56f); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x010f0c64); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00050012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001c000b); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1ff84); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff66ffbe); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00960184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01cd00da); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfeccfcb2); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fdf9); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x01e005bc); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06e703e4); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfdabf798); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf599f9b3); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x02510abd); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dbf08df); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfe48f3dc); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefd5f4f6); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x00a20c3e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0002000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0021001f); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0ff97); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff50ff74); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0034014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fa0179); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff97fd2a); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fcfa); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x00a304fe); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07310525); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xff37f886); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55cf86e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c709d0); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de209db); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xff6df484); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefcbf481); - cx25840_write4(client, DIF_BPF_COEFF3435, 0x00360c18); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffe000a); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0021002f); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0010ffb8); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff50ff3b); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffcc00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fa01fa); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0069fdd4); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fc26); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xff5d0407); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07310638); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x00c9f9a8); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55cf74e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xff3908c3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de20ac3); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0093f537); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefcbf410); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xffca0bf2); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffb0003); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001c0037); - cx25840_write4(client, DIF_BPF_COEFF67, 0x002fffe2); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff66ff17); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff6a007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01cd0251); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0134fea5); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fb8b); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe2002e0); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06e70713); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0255faf5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf599f658); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaf0799); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dbf0b96); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x01b8f5f5); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefd5f3a3); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xff5e0bca); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffb); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00120037); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00460010); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff8eff0f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff180000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01750276); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01e8ff8d); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fb31); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcfb0198); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x065607ad); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x03cefc64); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf614f592); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2e0656); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d770c52); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x02daf6bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xefeaf33b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfef10ba3); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7fff5); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0005002f); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0054003c); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffc5ff22); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedfff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00fc0267); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0276007e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb1c); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbfe003e); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05830802); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0529fdec); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6c8f4fe); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabd04ff); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d0d0cf6); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x03f8f78f); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf00af2d7); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfe850b7b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff0); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff80020); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00560060); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0002ff4e); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec4ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x006d0225); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02d50166); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb4e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb35fee1); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0477080e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x065bff82); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7b1f4a0); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf9610397); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c810d80); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0510f869); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf033f278); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfe1a0b52); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffaffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffec000c); - cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0078); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0040ff8e); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecafeb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffd301b6); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fc0235); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fbc5); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaaafd90); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x033e07d2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x075b011b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf8cbf47a); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81f0224); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0bd50def); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0621f94b); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf067f21e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfdae0b29); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 6900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffdffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe3fff6); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0037007f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0075ffdc); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef2fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff3d0122); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02ea02dd); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fc79); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa65fc5d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x01e3074e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x082102ad); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa0ff48c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fe00a9); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b0a0e43); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0729fa33); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0a5f1c9); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfd430b00); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0001fff3); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffe2); - cx25840_write4(client, DIF_BPF_COEFF67, 0x001b0076); - cx25840_write4(client, DIF_BPF_COEFF89, 0x009c002d); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff35fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfeba0076); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x029f0352); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfd60); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa69fb53); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x00740688); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08a7042d); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfb75f4d6); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600ff2d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a220e7a); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0827fb22); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf0edf17a); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfcd80ad6); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0004fff9); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffd2); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfffb005e); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b0007a); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff8ffe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe53ffc1); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0221038c); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fe6e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfab6fa80); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xff010587); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08e90590); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfcf5f556); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bfdb3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x09210e95); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0919fc15); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf13ff12f); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfc6e0aab); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00070000); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe6ffc9); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffdb0039); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00af00b8); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfff4feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe13ff10); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01790388); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311ff92); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb48f9ed); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd980453); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08e306cd); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe88f60a); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482fc40); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x08080e93); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x09fdfd0c); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf19af0ea); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfc050a81); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080008); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff0ffc9); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1000d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x009800e2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x005bff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe00fe74); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00b50345); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b000bc); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc18f9a1); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc4802f9); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x089807dc); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0022f6f0); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407fada); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x06da0e74); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ad3fe06); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf1fef0ab); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfb9c0a55); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000e); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffdffd0); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffafffdf); - cx25840_write4(client, DIF_BPF_COEFF89, 0x006e00f2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00b8ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe1bfdf8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xffe302c8); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x041301dc); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd1af99e); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb1e0183); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x080908b5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x01bcf801); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdf985); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x059a0e38); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b99ff03); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf26cf071); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfb330a2a); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00070011); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000affdf); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffa9ffb5); - cx25840_write4(client, DIF_BPF_COEFF89, 0x003700e6); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01010000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe62fda8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff140219); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x043502e1); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe42f9e6); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa270000); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x073a0953); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x034cf939); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3a4f845); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x044c0de1); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c4f0000); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf2e2f03c); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfacc09fe); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00040012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0016fff3); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffafff95); - cx25840_write4(client, DIF_BPF_COEFF89, 0xfff900c0); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0130007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfecefd89); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe560146); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x041303bc); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xff81fa76); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf96cfe7d); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x063209b1); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x04c9fa93); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdf71e); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x02f30d6e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cf200fd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf361f00e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfa6509d1); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00010010); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001e0008); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1ff84); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffbc0084); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013e00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff56fd9f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdb8005c); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00460); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x00c7fb45); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8f4fd07); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x04fa09ce); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x062afc07); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407f614); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x01920ce0); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d8301fa); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf3e8efe5); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xfa0009a4); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd000b); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0022001d); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffdbff82); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff870039); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x012a014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffedfde7); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd47ff6b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x031104c6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0202fc4c); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8c6fbad); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x039909a7); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0767fd8e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482f52b); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x002d0c39); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e0002f4); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf477efc2); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf99b0977); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 7900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa0004); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0020002d); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfffbff91); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff61ffe8); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f70184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0086fe5c); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd0bfe85); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104e5); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0323fd7d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8e2fa79); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x021d093f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0879ff22); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bf465); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfec70b79); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e6803eb); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf50defa5); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf937094a); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fffd); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00190036); - cx25840_write4(client, DIF_BPF_COEFF67, 0x001bffaf); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4fff99); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00aa0198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0112fef3); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd09fdb9); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d04be); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x041bfecc); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf947f978); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x00900897); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x095a00b9); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f3c5); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfd650aa3); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ebc04de); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf5aaef8e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf8d5091c); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff7fff6); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000e0038); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0037ffd7); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff52ff56); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x004b0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0186ffa1); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd40fd16); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440452); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04de0029); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9f2f8b2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfefe07b5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a05024d); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef34d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfc0a09b8); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0efa05cd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf64eef7d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf87308ed); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff0); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00000031); - cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0005); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff6aff27); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffe4014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01d70057); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdacfca6); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3603a7); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05610184); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfadbf82e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd74069f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a7503d6); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff2ff); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfab808b9); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f2306b5); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf6f9ef72); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf81308bf); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff30022); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00560032); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff95ff10); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff8000f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01fe0106); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe46fc71); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3502c7); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x059e02ce); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbf9f7f2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfbff055b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aa9054c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f2db); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf97507aa); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f350797); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf7a9ef6d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf7b40890); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffeffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe8000f); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00540058); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffcdff14); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff29007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f6019e); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff01fc7c); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd5101bf); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x059203f6); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfd41f7fe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfaa903f3); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a9e06a9); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf2e2); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf842068b); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f320871); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf85eef6e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf7560860); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0002fff2); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1fff9); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00460073); - cx25840_write4(client, DIF_BPF_COEFF89, 0x000bff34); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfee90000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01c10215); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xffd0fcc5); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99009d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x053d04f1); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfea5f853); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf97d0270); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a5607e4); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef314); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf723055f); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0f180943); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf919ef75); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf6fa0830); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0005fff8); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffe4); - cx25840_write4(client, DIF_BPF_COEFF67, 0x002f007f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0048ff6b); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec7ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0163025f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00a2fd47); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17ff73); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04a405b2); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0017f8ed); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf88500dc); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x09d208f9); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff370); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf61c0429); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ee80a0b); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xf9d8ef82); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf6a00800); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0007ffff); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe1ffd4); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0010007a); - cx25840_write4(client, DIF_BPF_COEFF89, 0x007cffb2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec6ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00e60277); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0168fdf9); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fe50); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x03ce0631); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0188f9c8); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7c7ff43); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x091509e3); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f3f6); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf52d02ea); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0ea30ac9); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfa9bef95); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf64607d0); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00090007); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe9ffca); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfff00065); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a10003); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfee6feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0053025b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0213fed0); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3fd46); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x02c70668); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x02eafadb); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf74bfdae); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x08230a9c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7f4a3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf45b01a6); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0e480b7c); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfb61efae); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf5ef079f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 8900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000d); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff5ffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffd10043); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b20053); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff24fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffb9020c); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0295ffbb); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fc64); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x019b0654); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x042dfc1c); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf714fc2a); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x07020b21); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251f575); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3a7005e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0dd80c24); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfc2aefcd); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf599076e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00060011); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0002ffcf); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffba0018); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00ad009a); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff79fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff260192); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02e500ab); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fbb6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x005b05f7); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0545fd81); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf723fabf); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b80b70); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2f669); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf313ff15); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d550cbf); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6eff2); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf544073d); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00030012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000fffdd); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffea); - cx25840_write4(client, DIF_BPF_COEFF89, 0x009300cf); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffdcfe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea600f7); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fd0190); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fb46); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xff150554); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0627fefd); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf778f978); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x044d0b87); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543f77d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a0fdcf); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cbe0d4e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc4f01d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4f2070b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00000010); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001afff0); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaaffbf); - cx25840_write4(client, DIF_BPF_COEFF89, 0x006700ed); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0043feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe460047); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02db0258); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb1b); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfddc0473); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c90082); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf811f85e); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c90b66); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069ff8ad); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf250fc8d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c140dcf); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe93f04d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4a106d9); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc000c); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00200006); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ff9c); - cx25840_write4(client, DIF_BPF_COEFF89, 0x002f00ef); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00a4ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0dff92); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x028102f7); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb37); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcbf035e); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07260202); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8e8f778); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x01340b0d); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1f9f4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf223fb51); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b590e42); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xff64f083); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf45206a7); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff90005); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0022001a); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ff86); - cx25840_write4(client, DIF_BPF_COEFF89, 0xfff000d7); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f2ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01fee5); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01f60362); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb99); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbcc0222); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07380370); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9f7f6cc); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xff990a7e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902fb50); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21afa1f); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0a8d0ea6); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0034f0bf); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4050675); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fffe); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001e002b); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff81); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffb400a5); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01280000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe24fe50); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01460390); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfc3a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb1000ce); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x070104bf); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb37f65f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe0009bc); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a00fcbb); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf235f8f8); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x09b20efc); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0105f101); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf3ba0642); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff7); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00150036); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ff8c); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff810061); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013d007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe71fddf); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x007c0380); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fd13); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa94ff70); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x068005e2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc9bf633); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfc7308ca); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad5fe30); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf274f7e0); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x08c90f43); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x01d4f147); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf371060f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fff1); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00090038); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ffa7); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff5e0012); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013200f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfee3fd9b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xffaa0331); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fe15); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa60fe18); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05bd06d1); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe1bf64a); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfafa07ae); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7effab); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2d5f6d7); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x07d30f7a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x02a3f194); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf32905dc); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffb0032); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003fffcd); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4effc1); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0106014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff6efd8a); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfedd02aa); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0ff34); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa74fcd7); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x04bf0781); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xffaaf6a3); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf99e066b); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf90128); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf359f5e1); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x06d20fa2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0370f1e5); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2e405a8); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 9900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xffffffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffef0024); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0051fffa); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff54ff77); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00be0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0006fdad); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe2701f3); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413005e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfad1fbba); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x039007ee); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x013bf73d); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf868050a); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c4302a1); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3fdf4fe); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x05c70fba); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x043bf23c); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2a10575); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0003fff1); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe50011); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00570027); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff70ff3c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00620198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x009efe01); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd95011a); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x04350183); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb71fad0); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x023c0812); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x02c3f811); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf75e0390); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5c0411); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf4c1f432); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x04b30fc1); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0503f297); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2610541); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0006fff7); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdffffc); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00510050); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff9dff18); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfffc0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0128fe80); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd32002e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130292); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc4dfa21); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x00d107ee); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0435f91c); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6850205); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c430573); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf5a1f37d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x03990fba); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x05c7f2f8); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf222050d); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffe); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdfffe7); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003f006e); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffd6ff0f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff96014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0197ff1f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd05ff3e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0037c); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd59f9b7); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xff5d0781); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0585fa56); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5e4006f); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf906c4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf69df2e0); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x02790fa2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0688f35d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1e604d8); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00090005); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe4ffd6); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0025007e); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0014ff20); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff3c00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e1ffd0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd12fe5c); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110433); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe88f996); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfdf106d1); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x06aafbb7); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf57efed8); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e07ff); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf7b0f25e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x01560f7a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0745f3c7); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1ac04a4); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008000c); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffedffcb); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0005007d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0050ff4c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef6007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01ff0086); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd58fd97); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x024104ad); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xffcaf9c0); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc9905e2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x079afd35); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf555fd46); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad50920); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf8d9f1f6); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x00310f43); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x07fdf435); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf174046f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xfffffffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00050011); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffaffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5006b); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0082ff8c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecc0000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f00130); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdd2fcfc); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d04e3); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x010efa32); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb6404bf); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x084efec5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf569fbc2); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000a23); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfa15f1ab); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xff0b0efc); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x08b0f4a7); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf13f043a); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00020012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0007ffcd); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9004c); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a4ffd9); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec3ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01b401c1); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe76fc97); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x004404d2); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0245fae8); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa5f0370); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08c1005f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5bcfa52); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x09020b04); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfb60f17b); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfde70ea6); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x095df51e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf10c0405); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0011); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0014ffdb); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb40023); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b2002a); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedbff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0150022d); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff38fc6f); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36047b); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x035efbda); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9940202); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08ee01f5); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf649f8fe); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e10bc2); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfcb6f169); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfcc60e42); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0a04f599); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0db03d0); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffb000d); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001dffed); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaafff5); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00aa0077); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff13feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00ce026b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x000afc85); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3503e3); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x044cfcfb); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf90c0082); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08d5037f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf710f7cc); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0c59); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfe16f173); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfbaa0dcf); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0aa5f617); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0ad039b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 10900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff90006); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00210003); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffacffc8); - cx25840_write4(client, DIF_BPF_COEFF89, 0x008e00b6); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff63fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x003a0275); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00dafcda); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd510313); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0501fe40); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8cbfefd); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x087604f0); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf80af6c2); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430cc8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xff7af19a); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfa940d4e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0b3ff699); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0810365); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8ffff); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00210018); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffa3); - cx25840_write4(client, DIF_BPF_COEFF89, 0x006000e1); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffc4fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffa0024b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x019afd66); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc990216); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0575ff99); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8d4fd81); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x07d40640); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf932f5e6); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20d0d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x00dff1de); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf9860cbf); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0bd1f71e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf058032f); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff8); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001b0029); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffd1ff8a); - cx25840_write4(client, DIF_BPF_COEFF89, 0x002600f2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x002cfe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff0f01f0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x023bfe20); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc1700fa); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05a200f7); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf927fc1c); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x06f40765); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa82f53b); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x02510d27); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0243f23d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf8810c24); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0c5cf7a7); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf03102fa); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff2); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00110035); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0ff81); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffe700e7); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x008ffeb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe94016d); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b0fefb); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3ffd1); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05850249); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9c1fadb); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x05de0858); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfbf2f4c4); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c70d17); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x03a0f2b8); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf7870b7c); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0cdff833); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf00d02c4); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffdffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00040038); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0010ff88); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffac00c2); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e2ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe3900cb); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f1ffe9); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3feaa); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05210381); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa9cf9c8); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x04990912); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfd7af484); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xff390cdb); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x04f4f34d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf69a0ac9); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0d5af8c1); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefec028e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0000ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff60033); - cx25840_write4(client, DIF_BPF_COEFF67, 0x002fff9f); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff7b0087); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x011eff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe080018); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f900d8); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17fd96); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x04790490); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbadf8ed); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x032f098e); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xff10f47d); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaf0c75); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x063cf3fc); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf5ba0a0b); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0dccf952); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefcd0258); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0004fff1); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffea0026); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0046ffc3); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff5a003c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013b0000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe04ff63); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c801b8); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fca6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0397056a); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfcecf853); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x01ad09c9); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x00acf4ad); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2e0be7); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0773f4c2); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4e90943); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e35f9e6); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefb10221); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0007fff6); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe20014); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0054ffee); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4effeb); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0137007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2efebb); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0260027a); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fbe6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x02870605); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfe4af7fe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x001d09c1); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0243f515); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabd0b32); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0897f59e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4280871); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e95fa7c); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef9701eb); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffd); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdeffff); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0056001d); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff57ff9c); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x011300f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe82fe2e); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01ca0310); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fb62); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0155065a); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xffbaf7f2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe8c0977); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x03cef5b2); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf9610a58); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x09a5f68f); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf3790797); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0eebfb14); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef8001b5); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080004); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe0ffe9); - cx25840_write4(client, DIF_BPF_COEFF67, 0x004c0047); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff75ff58); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d1014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfef9fdc8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0111036f); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb21); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x00120665); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x012df82e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd0708ec); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0542f682); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81f095c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a9af792); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2db06b5); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f38fbad); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef6c017e); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 11900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0007000b); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe7ffd8); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00370068); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffa4ff28); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00790184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff87fd91); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00430392); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb26); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfece0626); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0294f8b2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb990825); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0698f77f); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fe0842); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b73f8a7); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf25105cd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f7bfc48); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef5a0148); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00050010); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff2ffcc); - cx25840_write4(client, DIF_BPF_COEFF67, 0x001b007b); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffdfff10); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00140198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0020fd8e); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff710375); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfb73); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd9a059f); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x03e0f978); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfa4e0726); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x07c8f8a7); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600070c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c2ff9c9); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1db04de); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fb4fce5); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef4b0111); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00010012); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffffffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfffb007e); - cx25840_write4(client, DIF_BPF_COEFF89, 0x001dff14); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffad0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00b7fdbe); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfea9031b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fc01); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc8504d6); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0504fa79); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf93005f6); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x08caf9f2); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52b05c0); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0ccbfaf9); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf17903eb); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fe3fd83); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3f00db); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffe0011); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000cffcc); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffdb0071); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0058ff32); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff4f014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x013cfe1f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdfb028a); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fcc9); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb9d03d6); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05f4fbad); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf848049d); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0999fb5b); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf4820461); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d46fc32); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf12d02f4); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x1007fe21); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3600a4); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa000e); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0017ffd9); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc10055); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0088ff68); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff0400f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01a6fea7); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd7501cc); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0fdc0); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaef02a8); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06a7fd07); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf79d0326); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a31fcda); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf40702f3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d9ffd72); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0f601fa); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x1021fec0); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2f006d); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80007); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001fffeb); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaf002d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a8ffb0); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed3007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e9ff4c); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd2000ee); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413fed8); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa82015c); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0715fe7d); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7340198); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a8dfe69); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bd017c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dd5feb8); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0d500fd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x1031ff60); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2b0037); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff70000); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00220000); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffa90000); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b30000); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec20000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x02000000); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd030000); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x04350000); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa5e0000); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x073b0000); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7110000); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0aac0000); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3a40000); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0de70000); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0c90000); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x10360000); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef290000); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff8fff9); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001f0015); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffafffd3); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a80050); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfed3ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e900b4); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd20ff12); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x04130128); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa82fea4); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x07150183); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf734fe68); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a8d0197); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf3bdfe84); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0dd50148); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0d5ff03); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x103100a0); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2bffc9); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffafff2); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00170027); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc1ffab); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00880098); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff04ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01a60159); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd75fe34); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b00240); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfaeffd58); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06a702f9); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf79dfcda); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0a310326); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf407fd0d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d9f028e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf0f6fe06); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x10210140); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef2fff93); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffeffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000c0034); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffdbff8f); - cx25840_write4(client, DIF_BPF_COEFF89, 0x005800ce); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff4ffeb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x013c01e1); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdfbfd76); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03110337); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb9dfc2a); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05f40453); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf848fb63); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x099904a5); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf482fb9f); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0d4603ce); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf12dfd0c); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x100701df); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef36ff5c); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 12900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0001ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffff0038); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfffbff82); - cx25840_write4(client, DIF_BPF_COEFF89, 0x001d00ec); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffadfe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00b70242); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfea9fce5); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x024103ff); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc85fb2a); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05040587); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf930fa0a); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x08ca060e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf52bfa40); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0ccb0507); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf179fc15); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fe3027d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef3fff25); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0005fff0); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff20034); - cx25840_write4(client, DIF_BPF_COEFF67, 0x001bff85); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffdf00f0); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0014fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00200272); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff71fc8b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d048d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd9afa61); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x03e00688); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfa4ef8da); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x07c80759); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf600f8f4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0c2f0637); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf1dbfb22); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0fb4031b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef4bfeef); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0007fff5); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe70028); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0037ff98); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffa400d8); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0079fe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff87026f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0043fc6e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x004404da); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfecef9da); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0294074e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb99f7db); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x06980881); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf6fef7be); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0b730759); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf251fa33); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f7b03b8); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef5afeb8); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0000); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fffc); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe00017); - cx25840_write4(client, DIF_BPF_COEFF67, 0x004cffb9); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff7500a8); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00d1feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfef90238); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0111fc91); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3604df); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0012f99b); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x012d07d2); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfd07f714); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0542097e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf81ff6a4); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x0a9a086e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf2dbf94b); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0f380453); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef6cfe82); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080003); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffde0001); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0056ffe3); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff570064); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0113ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe8201d2); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01cafcf0); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35049e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0155f9a6); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xffba080e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe8cf689); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x03ce0a4e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xf961f5a8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x09a50971); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf379f869); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0eeb04ec); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef80fe4b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0007000a); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe2ffec); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00540012); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4e0015); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0137ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2e0145); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0260fd86); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51041a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0287f9fb); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfe4a0802); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x001df63f); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x02430aeb); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfabdf4ce); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x08970a62); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf428f78f); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e950584); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xef97fe15); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0004000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffeaffda); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0046003d); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff5affc4); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013b0000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe04009d); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02c8fe48); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99035a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0397fa96); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfcec07ad); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x01adf637); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x00ac0b53); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfc2ef419); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x07730b3e); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf4e9f6bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0e35061a); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefb1fddf); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00000012); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfff6ffcd); - cx25840_write4(client, DIF_BPF_COEFF67, 0x002f0061); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff7bff79); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x011e007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe08ffe8); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f9ff28); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17026a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0479fb70); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfbad0713); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x032ff672); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xff100b83); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xfdaff38b); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x063c0c04); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf5baf5f5); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0dcc06ae); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefcdfda8); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffd0012); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0004ffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00100078); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffacff3e); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00e200f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe39ff35); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02f10017); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd30156); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0521fc7f); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa9c0638); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0499f6ee); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfd7a0b7c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0xff39f325); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x04f40cb3); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf69af537); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0d5a073f); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xefecfd72); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffa000e); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0011ffcb); - cx25840_write4(client, DIF_BPF_COEFF67, 0xfff0007f); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffe7ff19); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x008f014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe94fe93); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02b00105); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfbd3002f); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x0585fdb7); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf9c10525); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x05def7a8); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfbf20b3c); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x00c7f2e9); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x03a00d48); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf787f484); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0cdf07cd); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf00dfd3c); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 13900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010000); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80008); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001bffd7); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffd10076); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0026ff0e); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x002c0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff0ffe10); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x023b01e0); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc17ff06); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05a2ff09); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf92703e4); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x06f4f89b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfa820ac5); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0251f2d9); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x02430dc3); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf881f3dc); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0c5c0859); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf031fd06); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80001); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0021ffe8); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffba005d); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0060ff1f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffc40198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xffa0fdb5); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x019a029a); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99fdea); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x05750067); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8d4027f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x07d4f9c0); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf9320a1a); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d2f2f3); - cx25840_write4(client, DIF_BPF_COEFF2829, 0x00df0e22); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xf986f341); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0bd108e2); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf058fcd1); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffa); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0021fffd); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffac0038); - cx25840_write4(client, DIF_BPF_COEFF89, 0x008eff4a); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff630184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x003afd8b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x00da0326); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd51fced); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x050101c0); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf8cb0103); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x0876fb10); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf80a093e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0543f338); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xff7a0e66); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfa94f2b2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0b3f0967); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf081fc9b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffbfff3); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001d0013); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaa000b); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00aaff89); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff13014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00cefd95); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x000a037b); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe35fc1d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x044c0305); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf90cff7e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08d5fc81); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf7100834); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069ff3a7); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfe160e8d); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfbaaf231); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0aa509e9); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0adfc65); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xffffffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00140025); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb4ffdd); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00b2ffd6); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfedb00f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x0150fdd3); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xff380391); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff36fb85); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x035e0426); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xf994fdfe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08eefe0b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf6490702); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1f43e); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfcb60e97); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfcc6f1be); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x0a040a67); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf0dbfc30); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0002ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00070033); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9ffb4); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00a40027); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfec3007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01b4fe3f); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe760369); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0044fb2e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x02450518); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfa5ffc90); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x08c1ffa1); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5bc05ae); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0902f4fc); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfb600e85); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xfde7f15a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x095d0ae2); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf10cfbfb); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0005ffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffa0038); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5ff95); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00820074); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfecc0000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01f0fed0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfdd20304); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014dfb1d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x010e05ce); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfb64fb41); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x084e013b); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf569043e); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a00f5dd); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xfa150e55); - cx25840_write4(client, DIF_BPF_COEFF3031, 0xff0bf104); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x08b00b59); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf13ffbc6); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0008fff4); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffed0035); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0005ff83); - cx25840_write4(client, DIF_BPF_COEFF89, 0x005000b4); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfef6ff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01ffff7a); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd580269); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0241fb53); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xffca0640); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfc99fa1e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x079a02cb); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf55502ba); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad5f6e0); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf8d90e0a); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0031f0bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x07fd0bcb); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf174fb91); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffffffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0009fffb); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe4002a); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0025ff82); - cx25840_write4(client, DIF_BPF_COEFF89, 0x001400e0); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff3cff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01e10030); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd1201a4); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0311fbcd); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfe88066a); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xfdf1f92f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x06aa0449); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf57e0128); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7ef801); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf7b00da2); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0156f086); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x07450c39); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1acfb5c); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00080002); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdf0019); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003fff92); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffd600f1); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff96feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x019700e1); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd0500c2); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b0fc84); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfd590649); - cx25840_write4(client, DIF_BPF_COEFF2021, 0xff5df87f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x058505aa); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf5e4ff91); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf9f93c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf69d0d20); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0279f05e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x06880ca3); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf1e6fb28); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 14900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x00060009); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffdf0004); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0051ffb0); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff9d00e8); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xfffcfe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x01280180); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd32ffd2); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413fd6e); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfc4d05df); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x00d1f812); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x043506e4); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf685fdfb); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c43fa8d); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf5a10c83); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0399f046); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x05c70d08); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf222faf3); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0003000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffe5ffef); - cx25840_write4(client, DIF_BPF_COEFF67, 0x0057ffd9); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff7000c4); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0062fe68); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x009e01ff); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfd95fee6); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0435fe7d); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb710530); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x023cf7ee); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x02c307ef); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf75efc70); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c5cfbef); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf4c10bce); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x04b3f03f); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x05030d69); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf261fabf); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15100000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0000fffd); - cx25840_write4(client, DIF_BPF_COEFF23, 0xffff0012); - cx25840_write4(client, DIF_BPF_COEFF45, 0xffefffdc); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00510006); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff540089); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00befe7c); - cx25840_write4(client, DIF_BPF_COEFF1213, 0x00060253); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfe27fe0d); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x0413ffa2); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfad10446); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0390f812); - cx25840_write4(client, DIF_BPF_COEFF2223, 0x013b08c3); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf868faf6); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0c43fd5f); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3fd0b02); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x05c7f046); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x043b0dc4); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2a1fa8b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15200000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001fffe); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffc0012); - cx25840_write4(client, DIF_BPF_COEFF45, 0xfffbffce); - cx25840_write4(client, DIF_BPF_COEFF67, 0x003f0033); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff4e003f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0106feb6); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff6e0276); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xfeddfd56); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x03b000cc); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa740329); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x04bff87f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xffaa095d); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xf99ef995); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0bf9fed8); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf3590a1f); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x06d2f05e); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x03700e1b); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf2e4fa58); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15300000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x0001ffff); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9000f); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0009ffc8); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00250059); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff5effee); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0132ff10); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfee30265); - cx25840_write4(client, DIF_BPF_COEFF1415, 0xffaafccf); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x031101eb); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa6001e8); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x05bdf92f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfe1b09b6); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfafaf852); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0b7e0055); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2d50929); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x07d3f086); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x02a30e6c); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf329fa24); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15400000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00010001); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80009); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0015ffca); - cx25840_write4(client, DIF_BPF_COEFF67, 0x00050074); - cx25840_write4(client, DIF_BPF_COEFF89, 0xff81ff9f); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x013dff82); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe710221); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x007cfc80); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x024102ed); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfa940090); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0680fa1e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfc9b09cd); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfc73f736); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0ad501d0); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2740820); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x08c9f0bd); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x01d40eb9); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf371f9f1); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15500000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000002); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff80002); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001effd5); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffe5007f); - cx25840_write4(client, DIF_BPF_COEFF89, 0xffb4ff5b); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x01280000); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe2401b0); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0146fc70); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x014d03c6); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfb10ff32); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0701fb41); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xfb3709a1); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xfe00f644); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x0a000345); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2350708); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x09b2f104); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x01050eff); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf3baf9be); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15600000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfff9fffb); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0022ffe6); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffc9007a); - cx25840_write4(client, DIF_BPF_COEFF89, 0xfff0ff29); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00f2007e); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe01011b); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x01f6fc9e); - cx25840_write4(client, DIF_BPF_COEFF1617, 0x00440467); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfbccfdde); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0738fc90); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf9f70934); - cx25840_write4(client, DIF_BPF_COEFF2425, 0xff99f582); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x090204b0); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf21a05e1); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0a8df15a); - cx25840_write4(client, DIF_BPF_COEFF3233, 0x00340f41); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf405f98b); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15700000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0xfffcfff4); - cx25840_write4(client, DIF_BPF_COEFF45, 0x0020fffa); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffb40064); - cx25840_write4(client, DIF_BPF_COEFF89, 0x002fff11); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x00a400f0); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe0d006e); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x0281fd09); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xff3604c9); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfcbffca2); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0726fdfe); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf8e80888); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x0134f4f3); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x07e1060c); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf22304af); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0b59f1be); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xff640f7d); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf452f959); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15800000: - cx25840_write4(client, DIF_BPF_COEFF01, 0x00000003); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0000fff0); - cx25840_write4(client, DIF_BPF_COEFF45, 0x001a0010); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffaa0041); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0067ff13); - cx25840_write4(client, DIF_BPF_COEFF1011, 0x0043014a); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfe46ffb9); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02dbfda8); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfe3504e5); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xfddcfb8d); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06c9ff7e); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf81107a2); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x02c9f49a); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x069f0753); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2500373); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0c14f231); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfe930fb3); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4a1f927); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 15900000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0002); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0003ffee); - cx25840_write4(client, DIF_BPF_COEFF45, 0x000f0023); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffac0016); - cx25840_write4(client, DIF_BPF_COEFF89, 0x0093ff31); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xffdc0184); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xfea6ff09); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02fdfe70); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfd5104ba); - cx25840_write4(client, DIF_BPF_COEFF1819, 0xff15faac); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x06270103); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7780688); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x044df479); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x05430883); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf2a00231); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0cbef2b2); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfdc40fe3); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf4f2f8f5); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - - case 16000000: - cx25840_write4(client, DIF_BPF_COEFF01, 0xffff0001); - cx25840_write4(client, DIF_BPF_COEFF23, 0x0006ffef); - cx25840_write4(client, DIF_BPF_COEFF45, 0x00020031); - cx25840_write4(client, DIF_BPF_COEFF67, 0xffbaffe8); - cx25840_write4(client, DIF_BPF_COEFF89, 0x00adff66); - cx25840_write4(client, DIF_BPF_COEFF1011, 0xff790198); - cx25840_write4(client, DIF_BPF_COEFF1213, 0xff26fe6e); - cx25840_write4(client, DIF_BPF_COEFF1415, 0x02e5ff55); - cx25840_write4(client, DIF_BPF_COEFF1617, 0xfc99044a); - cx25840_write4(client, DIF_BPF_COEFF1819, 0x005bfa09); - cx25840_write4(client, DIF_BPF_COEFF2021, 0x0545027f); - cx25840_write4(client, DIF_BPF_COEFF2223, 0xf7230541); - cx25840_write4(client, DIF_BPF_COEFF2425, 0x05b8f490); - cx25840_write4(client, DIF_BPF_COEFF2627, 0x03d20997); - cx25840_write4(client, DIF_BPF_COEFF2829, 0xf31300eb); - cx25840_write4(client, DIF_BPF_COEFF3031, 0x0d55f341); - cx25840_write4(client, DIF_BPF_COEFF3233, 0xfcf6100e); - cx25840_write4(client, DIF_BPF_COEFF3435, 0xf544f8c3); - cx25840_write4(client, DIF_BPF_COEFF36, 0x110d0000); - break; - } + coeffs = ifhz_coeffs[(ifHz - 3000000) / 100000]; + cx25840_write4(client, DIF_BPF_COEFF01, coeffs[0]); + cx25840_write4(client, DIF_BPF_COEFF23, coeffs[1]); + cx25840_write4(client, DIF_BPF_COEFF45, coeffs[2]); + cx25840_write4(client, DIF_BPF_COEFF67, coeffs[3]); + cx25840_write4(client, DIF_BPF_COEFF89, coeffs[4]); + cx25840_write4(client, DIF_BPF_COEFF1011, coeffs[5]); + cx25840_write4(client, DIF_BPF_COEFF1213, coeffs[6]); + cx25840_write4(client, DIF_BPF_COEFF1415, coeffs[7]); + cx25840_write4(client, DIF_BPF_COEFF1617, coeffs[8]); + cx25840_write4(client, DIF_BPF_COEFF1819, coeffs[9]); + cx25840_write4(client, DIF_BPF_COEFF2021, coeffs[10]); + cx25840_write4(client, DIF_BPF_COEFF2223, coeffs[11]); + cx25840_write4(client, DIF_BPF_COEFF2425, coeffs[12]); + cx25840_write4(client, DIF_BPF_COEFF2627, coeffs[13]); + cx25840_write4(client, DIF_BPF_COEFF2829, coeffs[14]); + cx25840_write4(client, DIF_BPF_COEFF3031, coeffs[15]); + cx25840_write4(client, DIF_BPF_COEFF3233, coeffs[16]); + cx25840_write4(client, DIF_BPF_COEFF3435, coeffs[17]); + cx25840_write4(client, DIF_BPF_COEFF36, coeffs[18]); } static void cx23888_std_setup(struct i2c_client *client) diff --git a/drivers/media/i2c/ds90ub913.c b/drivers/media/i2c/ds90ub913.c index 4bfa3b3cf6..8e9ebed09f 100644 --- a/drivers/media/i2c/ds90ub913.c +++ b/drivers/media/i2c/ds90ub913.c @@ -362,8 +362,6 @@ static int ub913_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, if (ret) return ret; - memset(fd, 0, sizeof(*fd)); - fd->type = V4L2_MBUS_FRAME_DESC_TYPE_PARALLEL; state = v4l2_subdev_lock_and_get_active_state(sd); diff --git a/drivers/media/i2c/ds90ub953.c b/drivers/media/i2c/ds90ub953.c index dc394e22a4..6440223128 100644 --- a/drivers/media/i2c/ds90ub953.c +++ b/drivers/media/i2c/ds90ub953.c @@ -499,8 +499,6 @@ static int ub953_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, if (ret) return ret; - memset(fd, 0, sizeof(*fd)); - fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; state = v4l2_subdev_lock_and_get_active_state(sd); diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 8ba5750f5a..b8f3e5ca03 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -2786,8 +2786,6 @@ static int ub960_get_frame_desc(struct v4l2_subdev *sd, unsigned int pad, if (!ub960_pad_is_source(priv, pad)) return -EINVAL; - memset(fd, 0, sizeof(*fd)); - fd->type = V4L2_MBUS_FRAME_DESC_TYPE_CSI2; state = v4l2_subdev_lock_and_get_active_state(&priv->sd); diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c index fd56ba1387..f6ea9b7b97 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -477,6 +477,50 @@ static const struct hi556_reg mode_1296x972_regs[] = { {0x0958, 0xbb80}, }; +static const struct hi556_reg mode_1296x722_regs[] = { + {0x0a00, 0x0000}, + {0x0b0a, 0x8259}, + {0x0f30, 0x5b15}, + {0x0f32, 0x7167}, + {0x004a, 0x0100}, + {0x004c, 0x0000}, + {0x004e, 0x0100}, + {0x000c, 0x0122}, + {0x0008, 0x0b00}, + {0x005a, 0x0404}, + {0x0012, 0x000c}, + {0x0018, 0x0a33}, + {0x0022, 0x0008}, + {0x0028, 0x0017}, + {0x0024, 0x0022}, + {0x002a, 0x002b}, + {0x0026, 0x012a}, + {0x002c, 0x06cf}, + {0x002e, 0x3311}, + {0x0030, 0x3311}, + {0x0032, 0x3311}, + {0x0006, 0x0814}, + {0x0a22, 0x0000}, + {0x0a12, 0x0510}, + {0x0a14, 0x02d2}, + {0x003e, 0x0000}, + {0x0074, 0x0812}, + {0x0070, 0x0409}, + {0x0804, 0x0308}, + {0x0806, 0x0100}, + {0x0a04, 0x016a}, + {0x090c, 0x09c0}, + {0x090e, 0x0010}, + {0x0902, 0x4319}, + {0x0914, 0xc106}, + {0x0916, 0x040e}, + {0x0918, 0x0304}, + {0x091a, 0x0708}, + {0x091c, 0x0e06}, + {0x091e, 0x0300}, + {0x0958, 0xbb80}, +}; + static const char * const hi556_test_pattern_menu[] = { "Disabled", "Solid Colour", @@ -556,7 +600,25 @@ static const struct hi556_mode supported_modes[] = { .regs = mode_1296x972_regs, }, .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX, - } + }, + { + .width = 1296, + .height = 722, + .crop = { + .left = HI556_PIXEL_ARRAY_LEFT, + .top = 250, + .width = HI556_PIXEL_ARRAY_WIDTH, + .height = 1444 + }, + .fll_def = HI556_FLL_30FPS, + .fll_min = HI556_FLL_30FPS_MIN, + .llp = 0x0b00, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_1296x722_regs), + .regs = mode_1296x722_regs, + }, + .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX, + }, }; struct hi556 { @@ -577,9 +639,6 @@ struct hi556 { /* To serialize asynchronus callbacks */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - /* True if the device has been identified */ bool identified; }; @@ -976,9 +1035,6 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (hi556->streaming == enable) - return 0; - mutex_lock(&hi556->mutex); if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -998,47 +1054,8 @@ static int hi556_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - hi556->streaming = enable; - mutex_unlock(&hi556->mutex); - - return ret; -} - -static int __maybe_unused hi556_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct hi556 *hi556 = to_hi556(sd); - - mutex_lock(&hi556->mutex); - if (hi556->streaming) - hi556_stop_streaming(hi556); - - mutex_unlock(&hi556->mutex); - - return 0; -} - -static int __maybe_unused hi556_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct hi556 *hi556 = to_hi556(sd); - int ret; - - mutex_lock(&hi556->mutex); - if (hi556->streaming) { - ret = hi556_start_streaming(hi556); - if (ret) - goto error; - } - mutex_unlock(&hi556->mutex); - return 0; - -error: - hi556_stop_streaming(hi556); - hi556->streaming = 0; - mutex_unlock(&hi556->mutex); return ret; } @@ -1331,10 +1348,6 @@ probe_error_v4l2_ctrl_handler_free: return ret; } -static const struct dev_pm_ops hi556_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(hi556_suspend, hi556_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id hi556_acpi_ids[] = { {"INT3537"}, @@ -1347,7 +1360,6 @@ MODULE_DEVICE_TABLE(acpi, hi556_acpi_ids); static struct i2c_driver hi556_i2c_driver = { .driver = { .name = "hi556", - .pm = &hi556_pm_ops, .acpi_match_table = ACPI_PTR(hi556_acpi_ids), }, .probe = hi556_probe, diff --git a/drivers/media/i2c/hi846.c b/drivers/media/i2c/hi846.c index fa0038749a..825fc8dc48 100644 --- a/drivers/media/i2c/hi846.c +++ b/drivers/media/i2c/hi846.c @@ -1607,17 +1607,12 @@ static int hi846_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (hi846->streaming == enable) - return 0; - mutex_lock(&hi846->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) goto out; - } ret = hi846_start_streaming(hi846); } @@ -1680,9 +1675,6 @@ static int __maybe_unused hi846_suspend(struct device *dev) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct hi846 *hi846 = to_hi846(sd); - if (hi846->streaming) - hi846_stop_streaming(hi846); - return hi846_power_off(hi846); } @@ -1691,26 +1683,8 @@ static int __maybe_unused hi846_resume(struct device *dev) struct i2c_client *client = to_i2c_client(dev); struct v4l2_subdev *sd = i2c_get_clientdata(client); struct hi846 *hi846 = to_hi846(sd); - int ret; - - ret = hi846_power_on(hi846); - if (ret) - return ret; - if (hi846->streaming) { - ret = hi846_start_streaming(hi846); - if (ret) { - dev_err(dev, "%s: start streaming failed: %d\n", - __func__, ret); - goto error; - } - } - - return 0; - -error: - hi846_power_off(hi846); - return ret; + return hi846_power_on(hi846); } static int hi846_set_format(struct v4l2_subdev *sd, @@ -2173,8 +2147,6 @@ static void hi846_remove(struct i2c_client *client) } static const struct dev_pm_ops hi846_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) SET_RUNTIME_PM_OPS(hi846_suspend, hi846_resume, NULL) }; diff --git a/drivers/media/i2c/hi847.c b/drivers/media/i2c/hi847.c index 32547d7a26..4075c38980 100644 --- a/drivers/media/i2c/hi847.c +++ b/drivers/media/i2c/hi847.c @@ -2184,9 +2184,6 @@ struct hi847 { /* To serialize asynchronus callbacks */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; static u64 to_pixel_rate(u32 f_index) @@ -2618,14 +2615,10 @@ static int hi847_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (hi847->streaming == enable) - return 0; - mutex_lock(&hi847->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) { mutex_unlock(&hi847->mutex); return ret; } @@ -2641,49 +2634,8 @@ static int hi847_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - hi847->streaming = enable; - mutex_unlock(&hi847->mutex); - - return ret; -} - -static int __maybe_unused hi847_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct hi847 *hi847 = to_hi847(sd); - - mutex_lock(&hi847->mutex); - if (hi847->streaming) - hi847_stop_streaming(hi847); - - mutex_unlock(&hi847->mutex); - - return 0; -} - -static int __maybe_unused hi847_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct hi847 *hi847 = to_hi847(sd); - int ret; - - mutex_lock(&hi847->mutex); - if (hi847->streaming) { - ret = hi847_start_streaming(hi847); - if (ret) - goto error; - } - mutex_unlock(&hi847->mutex); - return 0; - -error: - hi847_stop_streaming(hi847); - hi847->streaming = 0; - mutex_unlock(&hi847->mutex); return ret; } @@ -2980,10 +2932,6 @@ probe_error_v4l2_ctrl_handler_free: return ret; } -static const struct dev_pm_ops hi847_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(hi847_suspend, hi847_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id hi847_acpi_ids[] = { {"HYV0847"}, @@ -2996,7 +2944,6 @@ MODULE_DEVICE_TABLE(acpi, hi847_acpi_ids); static struct i2c_driver hi847_i2c_driver = { .driver = { .name = "hi847", - .pm = &hi847_pm_ops, .acpi_match_table = ACPI_PTR(hi847_acpi_ids), }, .probe = hi847_probe, diff --git a/drivers/media/i2c/imx208.c b/drivers/media/i2c/imx208.c index ee5a286753..a9b0aea1ae 100644 --- a/drivers/media/i2c/imx208.c +++ b/drivers/media/i2c/imx208.c @@ -290,9 +290,6 @@ struct imx208 { */ struct mutex imx208_mx; - /* Streaming on/off */ - bool streaming; - /* OTP data */ bool otp_read; char otp_data[IMX208_OTP_SIZE]; @@ -714,15 +711,13 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&imx208->imx208_mx); - if (imx208->streaming == enable) { - mutex_unlock(&imx208->imx208_mx); - return 0; - } if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) - goto err_rpm_put; + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) { + mutex_unlock(&imx208->imx208_mx); + return ret; + } /* * Apply default & customized values @@ -736,7 +731,6 @@ static int imx208_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - imx208->streaming = enable; mutex_unlock(&imx208->imx208_mx); /* vflip and hflip cannot change during streaming */ @@ -752,40 +746,6 @@ err_rpm_put: return ret; } -static int __maybe_unused imx208_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx208 *imx208 = to_imx208(sd); - - if (imx208->streaming) - imx208_stop_streaming(imx208); - - return 0; -} - -static int __maybe_unused imx208_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx208 *imx208 = to_imx208(sd); - int ret; - - if (imx208->streaming) { - ret = imx208_start_streaming(imx208); - if (ret) - goto error; - } - - return 0; - -error: - imx208_stop_streaming(imx208); - imx208->streaming = 0; - - return ret; -} - /* Verify chip ID */ static const struct v4l2_subdev_video_ops imx208_video_ops = { .s_stream = imx208_set_stream, @@ -819,11 +779,9 @@ static int imx208_read_otp(struct imx208 *imx208) if (imx208->otp_read) goto out_unlock; - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) goto out_unlock; - } ret = imx208_identify_module(imx208); if (ret) @@ -1081,10 +1039,6 @@ static void imx208_remove(struct i2c_client *client) mutex_destroy(&imx208->imx208_mx); } -static const struct dev_pm_ops imx208_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx208_suspend, imx208_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id imx208_acpi_ids[] = { { "INT3478" }, @@ -1097,7 +1051,6 @@ MODULE_DEVICE_TABLE(acpi, imx208_acpi_ids); static struct i2c_driver imx208_i2c_driver = { .driver = { .name = "imx208", - .pm = &imx208_pm_ops, .acpi_match_table = ACPI_PTR(imx208_acpi_ids), }, .probe = imx208_probe, diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 2f9c8582f9..4f77ea02cc 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -58,8 +58,6 @@ struct imx214 { * and start streaming. */ struct mutex mutex; - - bool streaming; }; struct reg_8 { @@ -775,9 +773,6 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable) struct imx214 *imx214 = to_imx214(subdev); int ret; - if (imx214->streaming == enable) - return 0; - if (enable) { ret = pm_runtime_resume_and_get(imx214->dev); if (ret < 0) @@ -793,7 +788,6 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable) pm_runtime_put(imx214->dev); } - imx214->streaming = enable; return 0; err_rpm_put: @@ -909,39 +903,6 @@ done: return ret; } -static int __maybe_unused imx214_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx214 *imx214 = to_imx214(sd); - - if (imx214->streaming) - imx214_stop_streaming(imx214); - - return 0; -} - -static int __maybe_unused imx214_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct imx214 *imx214 = to_imx214(sd); - int ret; - - if (imx214->streaming) { - ret = imx214_start_streaming(imx214); - if (ret) - goto error; - } - - return 0; - -error: - imx214_stop_streaming(imx214); - imx214->streaming = 0; - return ret; -} - static int imx214_probe(struct i2c_client *client) { struct device *dev = &client->dev; @@ -1102,7 +1063,6 @@ static const struct of_device_id imx214_of_match[] = { MODULE_DEVICE_TABLE(of, imx214_of_match); static const struct dev_pm_ops imx214_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx214_suspend, imx214_resume) SET_RUNTIME_PM_OPS(imx214_power_off, imx214_power_on, NULL) }; diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c index 3afa3f79c8..8436880dcf 100644 --- a/drivers/media/i2c/imx219.c +++ b/drivers/media/i2c/imx219.c @@ -18,6 +18,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> +#include <linux/minmax.h> #include <linux/module.h> #include <linux/pm_runtime.h> #include <linux/regulator/consumer.h> @@ -71,20 +72,10 @@ /* V_TIMING internal */ #define IMX219_REG_VTS CCI_REG16(0x0160) -#define IMX219_VTS_15FPS 0x0dc6 -#define IMX219_VTS_30FPS_1080P 0x06e3 -#define IMX219_VTS_30FPS_BINNED 0x06e3 -#define IMX219_VTS_30FPS_640x480 0x06e3 #define IMX219_VTS_MAX 0xffff #define IMX219_VBLANK_MIN 4 -/*Frame Length Line*/ -#define IMX219_FLL_MIN 0x08a6 -#define IMX219_FLL_MAX 0xffff -#define IMX219_FLL_STEP 1 -#define IMX219_FLL_DEFAULT 0x0c98 - /* HBLANK control - read only */ #define IMX219_PPL_DEFAULT 3448 @@ -100,10 +91,11 @@ #define IMX219_REG_ORIENTATION CCI_REG8(0x0172) /* Binning Mode */ -#define IMX219_REG_BINNING_MODE CCI_REG16(0x0174) -#define IMX219_BINNING_NONE 0x0000 -#define IMX219_BINNING_2X2 0x0101 -#define IMX219_BINNING_2X2_ANALOG 0x0303 +#define IMX219_REG_BINNING_MODE_H CCI_REG8(0x0174) +#define IMX219_REG_BINNING_MODE_V CCI_REG8(0x0175) +#define IMX219_BINNING_NONE 0x00 +#define IMX219_BINNING_X2 0x01 +#define IMX219_BINNING_X2_ANALOG 0x03 #define IMX219_REG_CSI_DATA_FORMAT_A CCI_REG16(0x018c) @@ -133,10 +125,6 @@ #define IMX219_TESTP_COLOUR_MIN 0 #define IMX219_TESTP_COLOUR_MAX 0x03ff #define IMX219_TESTP_COLOUR_STEP 1 -#define IMX219_TESTP_RED_DEFAULT IMX219_TESTP_COLOUR_MAX -#define IMX219_TESTP_GREENR_DEFAULT 0 -#define IMX219_TESTP_BLUE_DEFAULT 0 -#define IMX219_TESTP_GREENB_DEFAULT 0 #define IMX219_REG_TP_WINDOW_WIDTH CCI_REG16(0x0624) #define IMX219_REG_TP_WINDOW_HEIGHT CCI_REG16(0x0626) @@ -159,11 +147,6 @@ #define IMX219_PIXEL_ARRAY_WIDTH 3280U #define IMX219_PIXEL_ARRAY_HEIGHT 2464U -struct imx219_reg_list { - unsigned int num_of_regs; - const struct cci_reg_sequence *regs; -}; - /* Mode : resolution and related config&values */ struct imx219_mode { /* Frame width */ @@ -171,17 +154,8 @@ struct imx219_mode { /* Frame height */ unsigned int height; - /* Analog crop rectangle. */ - struct v4l2_rect crop; - /* V-timing */ unsigned int vts_def; - - /* Default register values */ - struct imx219_reg_list reg_list; - - /* 2x2 binning is used */ - bool binning; }; static const struct cci_reg_sequence imx219_common_regs[] = { @@ -228,65 +202,6 @@ static const struct cci_reg_sequence imx219_common_regs[] = { { IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(IMX219_XCLK_FREQ / 1000000) }, }; -/* - * Register sets lifted off the i2C interface from the Raspberry Pi firmware - * driver. - * 3280x2464 = mode 2, 1920x1080 = mode 1, 1640x1232 = mode 4, 640x480 = mode 7. - */ -static const struct cci_reg_sequence mode_3280x2464_regs[] = { - { IMX219_REG_X_ADD_STA_A, 0 }, - { IMX219_REG_X_ADD_END_A, 3279 }, - { IMX219_REG_Y_ADD_STA_A, 0 }, - { IMX219_REG_Y_ADD_END_A, 2463 }, - { IMX219_REG_X_OUTPUT_SIZE, 3280 }, - { IMX219_REG_Y_OUTPUT_SIZE, 2464 }, - { IMX219_REG_TP_WINDOW_WIDTH, 3280 }, - { IMX219_REG_TP_WINDOW_HEIGHT, 2464 }, -}; - -static const struct cci_reg_sequence mode_1920_1080_regs[] = { - { IMX219_REG_X_ADD_STA_A, 680 }, - { IMX219_REG_X_ADD_END_A, 2599 }, - { IMX219_REG_Y_ADD_STA_A, 692 }, - { IMX219_REG_Y_ADD_END_A, 1771 }, - { IMX219_REG_X_OUTPUT_SIZE, 1920 }, - { IMX219_REG_Y_OUTPUT_SIZE, 1080 }, - { IMX219_REG_TP_WINDOW_WIDTH, 1920 }, - { IMX219_REG_TP_WINDOW_HEIGHT, 1080 }, -}; - -static const struct cci_reg_sequence mode_1640_1232_regs[] = { - { IMX219_REG_X_ADD_STA_A, 0 }, - { IMX219_REG_X_ADD_END_A, 3279 }, - { IMX219_REG_Y_ADD_STA_A, 0 }, - { IMX219_REG_Y_ADD_END_A, 2463 }, - { IMX219_REG_X_OUTPUT_SIZE, 1640 }, - { IMX219_REG_Y_OUTPUT_SIZE, 1232 }, - { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, - { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, -}; - -static const struct cci_reg_sequence mode_640_480_regs[] = { - { IMX219_REG_X_ADD_STA_A, 1000 }, - { IMX219_REG_X_ADD_END_A, 2279 }, - { IMX219_REG_Y_ADD_STA_A, 752 }, - { IMX219_REG_Y_ADD_END_A, 1711 }, - { IMX219_REG_X_OUTPUT_SIZE, 640 }, - { IMX219_REG_Y_OUTPUT_SIZE, 480 }, - { IMX219_REG_TP_WINDOW_WIDTH, 1640 }, - { IMX219_REG_TP_WINDOW_HEIGHT, 1232 }, -}; - -static const struct cci_reg_sequence raw8_framefmt_regs[] = { - { IMX219_REG_CSI_DATA_FORMAT_A, 0x0808 }, - { IMX219_REG_OPPXCK_DIV, 8 }, -}; - -static const struct cci_reg_sequence raw10_framefmt_regs[] = { - { IMX219_REG_CSI_DATA_FORMAT_A, 0x0a0a }, - { IMX219_REG_OPPXCK_DIV, 10 }, -}; - static const s64 imx219_link_freq_menu[] = { IMX219_DEFAULT_LINK_FREQ, }; @@ -375,69 +290,25 @@ static const struct imx219_mode supported_modes[] = { /* 8MPix 15fps mode */ .width = 3280, .height = 2464, - .crop = { - .left = IMX219_PIXEL_ARRAY_LEFT, - .top = IMX219_PIXEL_ARRAY_TOP, - .width = 3280, - .height = 2464 - }, - .vts_def = IMX219_VTS_15FPS, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs), - .regs = mode_3280x2464_regs, - }, - .binning = false, + .vts_def = 3526, }, { /* 1080P 30fps cropped */ .width = 1920, .height = 1080, - .crop = { - .left = 688, - .top = 700, - .width = 1920, - .height = 1080 - }, - .vts_def = IMX219_VTS_30FPS_1080P, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_1920_1080_regs), - .regs = mode_1920_1080_regs, - }, - .binning = false, + .vts_def = 1763, }, { /* 2x2 binned 30fps mode */ .width = 1640, .height = 1232, - .crop = { - .left = IMX219_PIXEL_ARRAY_LEFT, - .top = IMX219_PIXEL_ARRAY_TOP, - .width = 3280, - .height = 2464 - }, - .vts_def = IMX219_VTS_30FPS_BINNED, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_1640_1232_regs), - .regs = mode_1640_1232_regs, - }, - .binning = true, + .vts_def = 1763, }, { /* 640x480 30fps mode */ .width = 640, .height = 480, - .crop = { - .left = 1008, - .top = 760, - .width = 1280, - .height = 960 - }, - .vts_def = IMX219_VTS_30FPS_640x480, - .reg_list = { - .num_of_regs = ARRAY_SIZE(mode_640_480_regs), - .regs = mode_640_480_regs, - }, - .binning = true, + .vts_def = 1763, }, }; @@ -462,12 +333,6 @@ struct imx219 { struct v4l2_ctrl *vblank; struct v4l2_ctrl *hblank; - /* Current mode */ - const struct imx219_mode *mode; - - /* Streaming on/off */ - bool streaming; - /* Two or Four lanes */ u8 lanes; }; @@ -495,18 +360,27 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) return imx219_mbus_formats[i]; } +/* ----------------------------------------------------------------------------- + * Controls + */ + static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) { struct imx219 *imx219 = container_of(ctrl->handler, struct imx219, ctrl_handler); struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct v4l2_mbus_framefmt *format; + struct v4l2_subdev_state *state; int ret = 0; + state = v4l2_subdev_get_locked_active_state(&imx219->sd); + format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); + if (ctrl->id == V4L2_CID_VBLANK) { int exposure_max, exposure_def; /* Update max exposure while meeting expected vblanking */ - exposure_max = imx219->mode->height + ctrl->val - 4; + exposure_max = format->height + ctrl->val - 4; exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? exposure_max : IMX219_EXPOSURE_DEFAULT; __v4l2_ctrl_modify_range(imx219->exposure, @@ -546,7 +420,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_VBLANK: cci_write(imx219->regmap, IMX219_REG_VTS, - imx219->mode->height + ctrl->val, &ret); + format->height + ctrl->val, &ret); break; case V4L2_CID_TEST_PATTERN_RED: cci_write(imx219->regmap, IMX219_REG_TESTP_RED, @@ -581,207 +455,211 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = { .s_ctrl = imx219_set_ctrl, }; -static void imx219_update_pad_format(struct imx219 *imx219, - const struct imx219_mode *mode, - struct v4l2_mbus_framefmt *fmt, u32 code) +static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) { - /* Bayer order varies with flips */ - fmt->code = imx219_get_format_code(imx219, code); - fmt->width = mode->width; - fmt->height = mode->height; - fmt->field = V4L2_FIELD_NONE; - fmt->colorspace = V4L2_COLORSPACE_RAW; - fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; - fmt->xfer_func = V4L2_XFER_FUNC_NONE; + return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; } -static int imx219_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state) +/* Initialize control handlers */ +static int imx219_init_controls(struct imx219 *imx219) { - struct imx219 *imx219 = to_imx219(sd); - struct v4l2_mbus_framefmt *format; - struct v4l2_rect *crop; - - /* Initialize the format. */ - format = v4l2_subdev_get_pad_format(sd, state, 0); - imx219_update_pad_format(imx219, &supported_modes[0], format, - MEDIA_BUS_FMT_SRGGB10_1X10); - - /* Initialize the crop rectangle. */ - crop = v4l2_subdev_get_pad_crop(sd, state, 0); - crop->top = IMX219_PIXEL_ARRAY_TOP; - crop->left = IMX219_PIXEL_ARRAY_LEFT; - crop->width = IMX219_PIXEL_ARRAY_WIDTH; - crop->height = IMX219_PIXEL_ARRAY_HEIGHT; - - return 0; -} + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + const struct imx219_mode *mode = &supported_modes[0]; + struct v4l2_ctrl_handler *ctrl_hdlr; + struct v4l2_fwnode_device_properties props; + int exposure_max, exposure_def, hblank; + int i, ret; -static int imx219_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_mbus_code_enum *code) -{ - struct imx219 *imx219 = to_imx219(sd); + ctrl_hdlr = &imx219->ctrl_handler; + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); + if (ret) + return ret; - if (code->index >= (ARRAY_SIZE(imx219_mbus_formats) / 4)) - return -EINVAL; + /* By default, PIXEL_RATE is read only */ + imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_PIXEL_RATE, + imx219_get_pixel_rate(imx219), + imx219_get_pixel_rate(imx219), 1, + imx219_get_pixel_rate(imx219)); - code->code = imx219_get_format_code(imx219, imx219_mbus_formats[code->index * 4]); + imx219->link_freq = + v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_LINK_FREQ, + ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, + (imx219->lanes == 2) ? imx219_link_freq_menu : + imx219_link_freq_4lane_menu); + if (imx219->link_freq) + imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; - return 0; -} + /* Initial vblank/hblank/exposure parameters based on current mode */ + imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_VBLANK, IMX219_VBLANK_MIN, + IMX219_VTS_MAX - mode->height, 1, + mode->vts_def - mode->height); + hblank = IMX219_PPL_DEFAULT - mode->width; + imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_HBLANK, hblank, hblank, + 1, hblank); + if (imx219->hblank) + imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; + exposure_max = mode->vts_def - 4; + exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? + exposure_max : IMX219_EXPOSURE_DEFAULT; + imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_EXPOSURE, + IMX219_EXPOSURE_MIN, exposure_max, + IMX219_EXPOSURE_STEP, + exposure_def); -static int imx219_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) -{ - struct imx219 *imx219 = to_imx219(sd); - u32 code; + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, + IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX, + IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT); - if (fse->index >= ARRAY_SIZE(supported_modes)) - return -EINVAL; + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN, + IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX, + IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT); - code = imx219_get_format_code(imx219, fse->code); - if (fse->code != code) - return -EINVAL; + imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, 0); + if (imx219->hflip) + imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - fse->min_width = supported_modes[fse->index].width; - fse->max_width = fse->min_width; - fse->min_height = supported_modes[fse->index].height; - fse->max_height = fse->min_height; + imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + if (imx219->vflip) + imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - return 0; -} + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(imx219_test_pattern_menu) - 1, + 0, 0, imx219_test_pattern_menu); + for (i = 0; i < 4; i++) { + /* + * The assumption is that + * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1 + * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2 + * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3 + */ + v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, + V4L2_CID_TEST_PATTERN_RED + i, + IMX219_TESTP_COLOUR_MIN, + IMX219_TESTP_COLOUR_MAX, + IMX219_TESTP_COLOUR_STEP, + IMX219_TESTP_COLOUR_MAX); + /* The "Solid color" pattern is white by default */ + } -static int imx219_set_pad_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct imx219 *imx219 = to_imx219(sd); - const struct imx219_mode *mode; - int exposure_max, exposure_def, hblank; - struct v4l2_mbus_framefmt *format; - struct v4l2_rect *crop; + if (ctrl_hdlr->error) { + ret = ctrl_hdlr->error; + dev_err(&client->dev, "%s control init failed (%d)\n", + __func__, ret); + goto error; + } - mode = v4l2_find_nearest_size(supported_modes, - ARRAY_SIZE(supported_modes), - width, height, - fmt->format.width, fmt->format.height); + ret = v4l2_fwnode_device_parse(&client->dev, &props); + if (ret) + goto error; - imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); + ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, + &props); + if (ret) + goto error; - format = v4l2_subdev_get_pad_format(sd, sd_state, 0); - crop = v4l2_subdev_get_pad_crop(sd, sd_state, 0); + imx219->sd.ctrl_handler = ctrl_hdlr; - *format = fmt->format; - *crop = mode->crop; + return 0; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { - imx219->mode = mode; - /* Update limits and set FPS to default */ - __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, - IMX219_VTS_MAX - mode->height, 1, - mode->vts_def - mode->height); - __v4l2_ctrl_s_ctrl(imx219->vblank, - mode->vts_def - mode->height); - /* Update max exposure while meeting expected vblanking */ - exposure_max = mode->vts_def - 4; - exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? - exposure_max : IMX219_EXPOSURE_DEFAULT; - __v4l2_ctrl_modify_range(imx219->exposure, - imx219->exposure->minimum, - exposure_max, imx219->exposure->step, - exposure_def); - /* - * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank - * depends on mode->width only, and is not changeble in any - * way other than changing the mode. - */ - hblank = IMX219_PPL_DEFAULT - mode->width; - __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, - hblank); - } +error: + v4l2_ctrl_handler_free(ctrl_hdlr); - return 0; + return ret; } -static int imx219_set_framefmt(struct imx219 *imx219, - const struct v4l2_mbus_framefmt *format) +static void imx219_free_controls(struct imx219 *imx219) { - switch (format->code) { - case MEDIA_BUS_FMT_SRGGB8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SGBRG8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - return cci_multi_reg_write(imx219->regmap, raw8_framefmt_regs, - ARRAY_SIZE(raw8_framefmt_regs), NULL); - - case MEDIA_BUS_FMT_SRGGB10_1X10: - case MEDIA_BUS_FMT_SGRBG10_1X10: - case MEDIA_BUS_FMT_SGBRG10_1X10: - case MEDIA_BUS_FMT_SBGGR10_1X10: - return cci_multi_reg_write(imx219->regmap, raw10_framefmt_regs, - ARRAY_SIZE(raw10_framefmt_regs), NULL); - } - - return -EINVAL; + v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); } -static int imx219_set_binning(struct imx219 *imx219, - const struct v4l2_mbus_framefmt *format) +/* ----------------------------------------------------------------------------- + * Subdev operations + */ + +static int imx219_set_framefmt(struct imx219 *imx219, + struct v4l2_subdev_state *state) { - if (!imx219->mode->binning) - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_NONE, NULL); + const struct v4l2_mbus_framefmt *format; + const struct v4l2_rect *crop; + unsigned int bpp; + u64 bin_h, bin_v; + int ret = 0; + + format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); + crop = v4l2_subdev_get_pad_crop(&imx219->sd, state, 0); switch (format->code) { case MEDIA_BUS_FMT_SRGGB8_1X8: case MEDIA_BUS_FMT_SGRBG8_1X8: case MEDIA_BUS_FMT_SGBRG8_1X8: case MEDIA_BUS_FMT_SBGGR8_1X8: - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_2X2_ANALOG, NULL); + bpp = 8; + break; case MEDIA_BUS_FMT_SRGGB10_1X10: case MEDIA_BUS_FMT_SGRBG10_1X10: case MEDIA_BUS_FMT_SGBRG10_1X10: case MEDIA_BUS_FMT_SBGGR10_1X10: - return cci_write(imx219->regmap, IMX219_REG_BINNING_MODE, - IMX219_BINNING_2X2, NULL); + default: + bpp = 10; + break; } - return -EINVAL; -} + cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, + crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); + cci_write(imx219->regmap, IMX219_REG_X_ADD_END_A, + crop->left - IMX219_PIXEL_ARRAY_LEFT + crop->width - 1, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_ADD_STA_A, + crop->top - IMX219_PIXEL_ARRAY_TOP, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, + crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); + + switch (crop->width / format->width) { + case 1: + default: + bin_h = IMX219_BINNING_NONE; + break; + case 2: + bin_h = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; + break; + } -static int imx219_get_selection(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_selection *sel) -{ - switch (sel->target) { - case V4L2_SEL_TGT_CROP: { - sel->r = *v4l2_subdev_get_pad_crop(sd, sd_state, 0); - return 0; + switch (crop->height / format->height) { + case 1: + default: + bin_v = IMX219_BINNING_NONE; + break; + case 2: + bin_v = bpp == 8 ? IMX219_BINNING_X2_ANALOG : IMX219_BINNING_X2; + break; } - case V4L2_SEL_TGT_NATIVE_SIZE: - sel->r.top = 0; - sel->r.left = 0; - sel->r.width = IMX219_NATIVE_WIDTH; - sel->r.height = IMX219_NATIVE_HEIGHT; + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, bin_h, &ret); + cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, bin_v, &ret); - return 0; + cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, + format->width, &ret); + cci_write(imx219->regmap, IMX219_REG_Y_OUTPUT_SIZE, + format->height, &ret); - case V4L2_SEL_TGT_CROP_DEFAULT: - case V4L2_SEL_TGT_CROP_BOUNDS: - sel->r.top = IMX219_PIXEL_ARRAY_TOP; - sel->r.left = IMX219_PIXEL_ARRAY_LEFT; - sel->r.width = IMX219_PIXEL_ARRAY_WIDTH; - sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT; + cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_WIDTH, + format->width, &ret); + cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_HEIGHT, + format->height, &ret); - return 0; - } + cci_write(imx219->regmap, IMX219_REG_CSI_DATA_FORMAT_A, + (bpp << 8) | bpp, &ret); + cci_write(imx219->regmap, IMX219_REG_OPPXCK_DIV, bpp, &ret); - return -EINVAL; + return ret; } static int imx219_configure_lanes(struct imx219 *imx219) @@ -795,8 +673,6 @@ static int imx219_start_streaming(struct imx219 *imx219, struct v4l2_subdev_state *state) { struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - const struct v4l2_mbus_framefmt *format; - const struct imx219_reg_list *reg_list; int ret; ret = pm_runtime_resume_and_get(&client->dev); @@ -818,30 +694,14 @@ static int imx219_start_streaming(struct imx219 *imx219, goto err_rpm_put; } - /* Apply default values of current mode */ - reg_list = &imx219->mode->reg_list; - ret = cci_multi_reg_write(imx219->regmap, reg_list->regs, - reg_list->num_of_regs, NULL); - if (ret) { - dev_err(&client->dev, "%s failed to set mode\n", __func__); - goto err_rpm_put; - } - - format = v4l2_subdev_get_pad_format(&imx219->sd, state, 0); - ret = imx219_set_framefmt(imx219, format); + /* Apply format and crop settings. */ + ret = imx219_set_framefmt(imx219, state); if (ret) { dev_err(&client->dev, "%s failed to set frame format: %d\n", __func__, ret); goto err_rpm_put; } - ret = imx219_set_binning(imx219, format); - if (ret) { - dev_err(&client->dev, "%s failed to set binning: %d\n", - __func__, ret); - goto err_rpm_put; - } - /* Apply customized values from user */ ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); if (ret) @@ -889,141 +749,176 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable) state = v4l2_subdev_lock_and_get_active_state(sd); - if (imx219->streaming == enable) - goto unlock; - - if (enable) { - /* - * Apply default & customized values - * and then start streaming. - */ + if (enable) ret = imx219_start_streaming(imx219, state); - if (ret) - goto unlock; - } else { + else imx219_stop_streaming(imx219); - } - - imx219->streaming = enable; -unlock: v4l2_subdev_unlock_state(state); return ret; } -/* Power/clock management functions */ -static int imx219_power_on(struct device *dev) +static void imx219_update_pad_format(struct imx219 *imx219, + const struct imx219_mode *mode, + struct v4l2_mbus_framefmt *fmt, u32 code) { - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx219 *imx219 = to_imx219(sd); - int ret; + /* Bayer order varies with flips */ + fmt->code = imx219_get_format_code(imx219, code); + fmt->width = mode->width; + fmt->height = mode->height; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_RAW; + fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; + fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; + fmt->xfer_func = V4L2_XFER_FUNC_NONE; +} - ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES, - imx219->supplies); - if (ret) { - dev_err(dev, "%s: failed to enable regulators\n", - __func__); - return ret; - } +static int imx219_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code) +{ + struct imx219 *imx219 = to_imx219(sd); - ret = clk_prepare_enable(imx219->xclk); - if (ret) { - dev_err(dev, "%s: failed to enable clock\n", - __func__); - goto reg_off; - } + if (code->index >= (ARRAY_SIZE(imx219_mbus_formats) / 4)) + return -EINVAL; - gpiod_set_value_cansleep(imx219->reset_gpio, 1); - usleep_range(IMX219_XCLR_MIN_DELAY_US, - IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US); + code->code = imx219_get_format_code(imx219, imx219_mbus_formats[code->index * 4]); return 0; - -reg_off: - regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); - - return ret; } -static int imx219_power_off(struct device *dev) +static int imx219_enum_frame_size(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_size_enum *fse) { - struct v4l2_subdev *sd = dev_get_drvdata(dev); struct imx219 *imx219 = to_imx219(sd); + u32 code; - gpiod_set_value_cansleep(imx219->reset_gpio, 0); - regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); - clk_disable_unprepare(imx219->xclk); + if (fse->index >= ARRAY_SIZE(supported_modes)) + return -EINVAL; + + code = imx219_get_format_code(imx219, fse->code); + if (fse->code != code) + return -EINVAL; + + fse->min_width = supported_modes[fse->index].width; + fse->max_width = fse->min_width; + fse->min_height = supported_modes[fse->index].height; + fse->max_height = fse->min_height; return 0; } -static int __maybe_unused imx219_suspend(struct device *dev) +static int imx219_set_pad_format(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) { - struct v4l2_subdev *sd = dev_get_drvdata(dev); struct imx219 *imx219 = to_imx219(sd); + const struct imx219_mode *mode; + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + unsigned int bin_h, bin_v; - if (imx219->streaming) - imx219_stop_streaming(imx219); + mode = v4l2_find_nearest_size(supported_modes, + ARRAY_SIZE(supported_modes), + width, height, + fmt->format.width, fmt->format.height); - return 0; -} + imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); -static int __maybe_unused imx219_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx219 *imx219 = to_imx219(sd); - struct v4l2_subdev_state *state; - int ret; + format = v4l2_subdev_get_pad_format(sd, state, 0); + *format = fmt->format; - if (imx219->streaming) { - state = v4l2_subdev_lock_and_get_active_state(sd); - ret = imx219_start_streaming(imx219, state); - v4l2_subdev_unlock_state(state); - if (ret) - goto error; - } + /* + * Use binning to maximize the crop rectangle size, and centre it in the + * sensor. + */ + bin_h = min(IMX219_PIXEL_ARRAY_WIDTH / format->width, 2U); + bin_v = min(IMX219_PIXEL_ARRAY_HEIGHT / format->height, 2U); - return 0; + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + crop->width = format->width * bin_h; + crop->height = format->height * bin_v; + crop->left = (IMX219_NATIVE_WIDTH - crop->width) / 2; + crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; -error: - imx219_stop_streaming(imx219); - imx219->streaming = false; + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { + int exposure_max; + int exposure_def; + int hblank; - return ret; + /* Update limits and set FPS to default */ + __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, + IMX219_VTS_MAX - mode->height, 1, + mode->vts_def - mode->height); + __v4l2_ctrl_s_ctrl(imx219->vblank, + mode->vts_def - mode->height); + /* Update max exposure while meeting expected vblanking */ + exposure_max = mode->vts_def - 4; + exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? + exposure_max : IMX219_EXPOSURE_DEFAULT; + __v4l2_ctrl_modify_range(imx219->exposure, + imx219->exposure->minimum, + exposure_max, imx219->exposure->step, + exposure_def); + /* + * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank + * depends on mode->width only, and is not changeble in any + * way other than changing the mode. + */ + hblank = IMX219_PPL_DEFAULT - mode->width; + __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, + hblank); + } + + return 0; } -static int imx219_get_regulators(struct imx219 *imx219) +static int imx219_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) { - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - unsigned int i; + switch (sel->target) { + case V4L2_SEL_TGT_CROP: { + sel->r = *v4l2_subdev_get_pad_crop(sd, state, 0); + return 0; + } - for (i = 0; i < IMX219_NUM_SUPPLIES; i++) - imx219->supplies[i].supply = imx219_supply_name[i]; + case V4L2_SEL_TGT_NATIVE_SIZE: + sel->r.top = 0; + sel->r.left = 0; + sel->r.width = IMX219_NATIVE_WIDTH; + sel->r.height = IMX219_NATIVE_HEIGHT; - return devm_regulator_bulk_get(&client->dev, - IMX219_NUM_SUPPLIES, - imx219->supplies); -} + return 0; -/* Verify chip ID */ -static int imx219_identify_module(struct imx219 *imx219) -{ - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - int ret; - u64 val; + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.top = IMX219_PIXEL_ARRAY_TOP; + sel->r.left = IMX219_PIXEL_ARRAY_LEFT; + sel->r.width = IMX219_PIXEL_ARRAY_WIDTH; + sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT; - ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); - if (ret) { - dev_err(&client->dev, "failed to read chip id %x\n", - IMX219_CHIP_ID); - return ret; + return 0; } - if (val != IMX219_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", - IMX219_CHIP_ID, val); - return -EIO; - } + return -EINVAL; +} + +static int imx219_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_subdev_format fmt = { + .which = V4L2_SUBDEV_FORMAT_TRY, + .pad = 0, + .format = { + .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .width = supported_modes[0].width, + .height = supported_modes[0].height, + }, + }; + + imx219_set_pad_format(sd, state, &fmt); return 0; } @@ -1053,129 +948,93 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = { }; -static unsigned long imx219_get_pixel_rate(struct imx219 *imx219) -{ - return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; -} +/* ----------------------------------------------------------------------------- + * Power management + */ -/* Initialize control handlers */ -static int imx219_init_controls(struct imx219 *imx219) +static int imx219_power_on(struct device *dev) { - struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); - struct v4l2_ctrl_handler *ctrl_hdlr; - unsigned int height = imx219->mode->height; - struct v4l2_fwnode_device_properties props; - int exposure_max, exposure_def, hblank; - int i, ret; + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct imx219 *imx219 = to_imx219(sd); + int ret; - ctrl_hdlr = &imx219->ctrl_handler; - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12); - if (ret) + ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES, + imx219->supplies); + if (ret) { + dev_err(dev, "%s: failed to enable regulators\n", + __func__); return ret; + } - /* By default, PIXEL_RATE is read only */ - imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_PIXEL_RATE, - imx219_get_pixel_rate(imx219), - imx219_get_pixel_rate(imx219), 1, - imx219_get_pixel_rate(imx219)); + ret = clk_prepare_enable(imx219->xclk); + if (ret) { + dev_err(dev, "%s: failed to enable clock\n", + __func__); + goto reg_off; + } - imx219->link_freq = - v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_LINK_FREQ, - ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, - (imx219->lanes == 2) ? imx219_link_freq_menu : - imx219_link_freq_4lane_menu); - if (imx219->link_freq) - imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + gpiod_set_value_cansleep(imx219->reset_gpio, 1); + usleep_range(IMX219_XCLR_MIN_DELAY_US, + IMX219_XCLR_MIN_DELAY_US + IMX219_XCLR_DELAY_RANGE_US); - /* Initial vblank/hblank/exposure parameters based on current mode */ - imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_VBLANK, IMX219_VBLANK_MIN, - IMX219_VTS_MAX - height, 1, - imx219->mode->vts_def - height); - hblank = IMX219_PPL_DEFAULT - imx219->mode->width; - imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HBLANK, hblank, hblank, - 1, hblank); - if (imx219->hblank) - imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; - exposure_max = imx219->mode->vts_def - 4; - exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ? - exposure_max : IMX219_EXPOSURE_DEFAULT; - imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_EXPOSURE, - IMX219_EXPOSURE_MIN, exposure_max, - IMX219_EXPOSURE_STEP, - exposure_def); + return 0; - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, - IMX219_ANA_GAIN_MIN, IMX219_ANA_GAIN_MAX, - IMX219_ANA_GAIN_STEP, IMX219_ANA_GAIN_DEFAULT); +reg_off: + regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, V4L2_CID_DIGITAL_GAIN, - IMX219_DGTL_GAIN_MIN, IMX219_DGTL_GAIN_MAX, - IMX219_DGTL_GAIN_STEP, IMX219_DGTL_GAIN_DEFAULT); + return ret; +} - imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_HFLIP, 0, 1, 1, 0); - if (imx219->hflip) - imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; +static int imx219_power_off(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct imx219 *imx219 = to_imx219(sd); - imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); - if (imx219->vflip) - imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; + gpiod_set_value_cansleep(imx219->reset_gpio, 0); + regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); + clk_disable_unprepare(imx219->xclk); - v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_TEST_PATTERN, - ARRAY_SIZE(imx219_test_pattern_menu) - 1, - 0, 0, imx219_test_pattern_menu); - for (i = 0; i < 4; i++) { - /* - * The assumption is that - * V4L2_CID_TEST_PATTERN_GREENR == V4L2_CID_TEST_PATTERN_RED + 1 - * V4L2_CID_TEST_PATTERN_BLUE == V4L2_CID_TEST_PATTERN_RED + 2 - * V4L2_CID_TEST_PATTERN_GREENB == V4L2_CID_TEST_PATTERN_RED + 3 - */ - v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, - V4L2_CID_TEST_PATTERN_RED + i, - IMX219_TESTP_COLOUR_MIN, - IMX219_TESTP_COLOUR_MAX, - IMX219_TESTP_COLOUR_STEP, - IMX219_TESTP_COLOUR_MAX); - /* The "Solid color" pattern is white by default */ - } + return 0; +} - if (ctrl_hdlr->error) { - ret = ctrl_hdlr->error; - dev_err(&client->dev, "%s control init failed (%d)\n", - __func__, ret); - goto error; - } +/* ----------------------------------------------------------------------------- + * Probe & remove + */ - ret = v4l2_fwnode_device_parse(&client->dev, &props); - if (ret) - goto error; +static int imx219_get_regulators(struct imx219 *imx219) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + unsigned int i; - ret = v4l2_ctrl_new_fwnode_properties(ctrl_hdlr, &imx219_ctrl_ops, - &props); - if (ret) - goto error; + for (i = 0; i < IMX219_NUM_SUPPLIES; i++) + imx219->supplies[i].supply = imx219_supply_name[i]; - imx219->sd.ctrl_handler = ctrl_hdlr; + return devm_regulator_bulk_get(&client->dev, + IMX219_NUM_SUPPLIES, + imx219->supplies); +} - return 0; +/* Verify chip ID */ +static int imx219_identify_module(struct imx219 *imx219) +{ + struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); + int ret; + u64 val; -error: - v4l2_ctrl_handler_free(ctrl_hdlr); + ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); + if (ret) { + dev_err(&client->dev, "failed to read chip id %x\n", + IMX219_CHIP_ID); + return ret; + } - return ret; -} + if (val != IMX219_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", + IMX219_CHIP_ID, val); + return -EIO; + } -static void imx219_free_controls(struct imx219 *imx219) -{ - v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); + return 0; } static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219) @@ -1287,10 +1146,8 @@ static int imx219_probe(struct i2c_client *client) if (ret) goto error_power_off; - /* Set default mode to max resolution */ - imx219->mode = &supported_modes[0]; - - /* sensor doesn't enter LP-11 state upon power up until and unless + /* + * Sensor doesn't enter LP-11 state upon power up until and unless * streaming is started, so upon power up switch the modes to: * streaming -> standby */ @@ -1385,7 +1242,6 @@ static const struct of_device_id imx219_dt_ids[] = { MODULE_DEVICE_TABLE(of, imx219_dt_ids); static const struct dev_pm_ops imx219_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx219_suspend, imx219_resume) SET_RUNTIME_PM_OPS(imx219_power_off, imx219_power_on, NULL) }; diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c index e196565e84..b3827f4bc0 100644 --- a/drivers/media/i2c/imx258.c +++ b/drivers/media/i2c/imx258.c @@ -622,9 +622,6 @@ struct imx258 { */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - struct clk *clk; }; @@ -1035,10 +1032,6 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&imx258->mutex); - if (imx258->streaming == enable) { - mutex_unlock(&imx258->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -1057,7 +1050,6 @@ static int imx258_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - imx258->streaming = enable; mutex_unlock(&imx258->mutex); return ret; @@ -1070,37 +1062,6 @@ err_unlock: return ret; } -static int __maybe_unused imx258_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx258 *imx258 = to_imx258(sd); - - if (imx258->streaming) - imx258_stop_streaming(imx258); - - return 0; -} - -static int __maybe_unused imx258_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx258 *imx258 = to_imx258(sd); - int ret; - - if (imx258->streaming) { - ret = imx258_start_streaming(imx258); - if (ret) - goto error; - } - - return 0; - -error: - imx258_stop_streaming(imx258); - imx258->streaming = 0; - return ret; -} - /* Verify chip ID */ static int imx258_identify_module(struct imx258 *imx258) { @@ -1369,7 +1330,6 @@ static void imx258_remove(struct i2c_client *client) } static const struct dev_pm_ops imx258_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx258_suspend, imx258_resume) SET_RUNTIME_PM_OPS(imx258_power_off, imx258_power_on, NULL) }; diff --git a/drivers/media/i2c/imx296.c b/drivers/media/i2c/imx296.c index 3b4539b622..94aac9d273 100644 --- a/drivers/media/i2c/imx296.c +++ b/drivers/media/i2c/imx296.c @@ -201,8 +201,6 @@ struct imx296 { const struct imx296_clk_params *clk_params; bool mono; - bool streaming; - struct v4l2_subdev subdev; struct media_pad pad; @@ -321,7 +319,7 @@ static int imx296_s_ctrl(struct v4l2_ctrl *ctrl) unsigned int vmax; int ret = 0; - if (!sensor->streaming) + if (!pm_runtime_get_if_in_use(sensor->dev)) return 0; state = v4l2_subdev_get_locked_active_state(&sensor->subdev); @@ -376,6 +374,8 @@ static int imx296_s_ctrl(struct v4l2_ctrl *ctrl) break; } + pm_runtime_put(sensor->dev); + return ret; } @@ -607,8 +607,6 @@ static int imx296_s_stream(struct v4l2_subdev *sd, int enable) pm_runtime_mark_last_busy(sensor->dev); pm_runtime_put_autosuspend(sensor->dev); - sensor->streaming = false; - goto unlock; } @@ -620,13 +618,6 @@ static int imx296_s_stream(struct v4l2_subdev *sd, int enable) if (ret < 0) goto err_pm; - /* - * Set streaming to true to ensure __v4l2_ctrl_handler_setup() will set - * the controls. The flag is reset to false further down if an error - * occurs. - */ - sensor->streaming = true; - ret = __v4l2_ctrl_handler_setup(&sensor->ctrls); if (ret < 0) goto err_pm; @@ -646,7 +637,6 @@ err_pm: * likely has no other chance to recover. */ pm_runtime_put_sync(sensor->dev); - sensor->streaming = false; goto unlock; } diff --git a/drivers/media/i2c/imx319.c b/drivers/media/i2c/imx319.c index 52ebb096e1..5378f607f3 100644 --- a/drivers/media/i2c/imx319.c +++ b/drivers/media/i2c/imx319.c @@ -138,8 +138,6 @@ struct imx319 { */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; /* True if the device has been identified */ bool identified; }; @@ -2166,10 +2164,6 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&imx319->mutex); - if (imx319->streaming == enable) { - mutex_unlock(&imx319->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -2188,8 +2182,6 @@ static int imx319_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - imx319->streaming = enable; - /* vflip and hflip cannot change during streaming */ __v4l2_ctrl_grab(imx319->vflip, enable); __v4l2_ctrl_grab(imx319->hflip, enable); @@ -2206,37 +2198,6 @@ err_unlock: return ret; } -static int __maybe_unused imx319_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx319 *imx319 = to_imx319(sd); - - if (imx319->streaming) - imx319_stop_streaming(imx319); - - return 0; -} - -static int __maybe_unused imx319_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx319 *imx319 = to_imx319(sd); - int ret; - - if (imx319->streaming) { - ret = imx319_start_streaming(imx319); - if (ret) - goto error; - } - - return 0; - -error: - imx319_stop_streaming(imx319); - imx319->streaming = 0; - return ret; -} - static const struct v4l2_subdev_core_ops imx319_subdev_core_ops = { .subscribe_event = v4l2_ctrl_subdev_subscribe_event, .unsubscribe_event = v4l2_event_subdev_unsubscribe, @@ -2542,10 +2503,6 @@ static void imx319_remove(struct i2c_client *client) mutex_destroy(&imx319->mutex); } -static const struct dev_pm_ops imx319_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx319_suspend, imx319_resume) -}; - static const struct acpi_device_id imx319_acpi_ids[] __maybe_unused = { { "SONY319A" }, { /* sentinel */ } @@ -2555,7 +2512,6 @@ MODULE_DEVICE_TABLE(acpi, imx319_acpi_ids); static struct i2c_driver imx319_i2c_driver = { .driver = { .name = "imx319", - .pm = &imx319_pm_ops, .acpi_match_table = ACPI_PTR(imx319_acpi_ids), }, .probe = imx319_probe, diff --git a/drivers/media/i2c/imx334.c b/drivers/media/i2c/imx334.c index d722c9b7cd..1196fe9350 100644 --- a/drivers/media/i2c/imx334.c +++ b/drivers/media/i2c/imx334.c @@ -56,6 +56,24 @@ #define IMX334_REG_MIN 0x00 #define IMX334_REG_MAX 0xfffff +/* Test Pattern Control */ +#define IMX334_REG_TP 0x329e +#define IMX334_TP_COLOR_HBARS 0xA +#define IMX334_TP_COLOR_VBARS 0xB + +#define IMX334_TPG_EN_DOUT 0x329c +#define IMX334_TP_ENABLE 0x1 +#define IMX334_TP_DISABLE 0x0 + +#define IMX334_TPG_COLORW 0x32a0 +#define IMX334_TPG_COLORW_120P 0x13 + +#define IMX334_TP_CLK_EN 0x3148 +#define IMX334_TP_CLK_EN_VAL 0x10 +#define IMX334_TP_CLK_DIS_VAL 0x0 + +#define IMX334_DIG_CLP_MODE 0x3280 + /** * struct imx334_reg - imx334 sensor register * @address: Register address @@ -120,7 +138,6 @@ struct imx334_mode { * @mutex: Mutex for serializing sensor controls * @menu_skip_mask: Menu skip mask for link_freq_ctrl * @cur_code: current selected format code - * @streaming: Flag indicating streaming state */ struct imx334 { struct device *dev; @@ -143,7 +160,6 @@ struct imx334 { struct mutex mutex; unsigned long menu_skip_mask; u32 cur_code; - bool streaming; }; static const s64 link_freq[] = { @@ -430,6 +446,18 @@ static const struct imx334_reg mode_3840x2160_regs[] = { {0x3a29, 0x00}, }; +static const char * const imx334_test_pattern_menu[] = { + "Disabled", + "Vertical Color Bars", + "Horizontal Color Bars", +}; + +static const int imx334_test_pattern_val[] = { + IMX334_TP_DISABLE, + IMX334_TP_COLOR_HBARS, + IMX334_TP_COLOR_VBARS, +}; + static const struct imx334_reg raw10_framefmt_regs[] = { {0x3050, 0x00}, {0x319d, 0x00}, @@ -716,6 +744,26 @@ static int imx334_set_ctrl(struct v4l2_ctrl *ctrl) case V4L2_CID_HBLANK: ret = 0; break; + case V4L2_CID_TEST_PATTERN: + if (ctrl->val) { + imx334_write_reg(imx334, IMX334_TP_CLK_EN, 1, + IMX334_TP_CLK_EN_VAL); + imx334_write_reg(imx334, IMX334_DIG_CLP_MODE, 1, 0x0); + imx334_write_reg(imx334, IMX334_TPG_COLORW, 1, + IMX334_TPG_COLORW_120P); + imx334_write_reg(imx334, IMX334_REG_TP, 1, + imx334_test_pattern_val[ctrl->val]); + imx334_write_reg(imx334, IMX334_TPG_EN_DOUT, 1, + IMX334_TP_ENABLE); + } else { + imx334_write_reg(imx334, IMX334_DIG_CLP_MODE, 1, 0x1); + imx334_write_reg(imx334, IMX334_TP_CLK_EN, 1, + IMX334_TP_CLK_DIS_VAL); + imx334_write_reg(imx334, IMX334_TPG_EN_DOUT, 1, + IMX334_TP_DISABLE); + } + ret = 0; + break; default: dev_err(imx334->dev, "Invalid control %d", ctrl->id); ret = -EINVAL; @@ -1001,11 +1049,6 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&imx334->mutex); - if (imx334->streaming == enable) { - mutex_unlock(&imx334->mutex); - return 0; - } - if (enable) { ret = pm_runtime_resume_and_get(imx334->dev); if (ret < 0) @@ -1019,8 +1062,6 @@ static int imx334_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(imx334->dev); } - imx334->streaming = enable; - mutex_unlock(&imx334->mutex); return 0; @@ -1222,7 +1263,7 @@ static int imx334_init_controls(struct imx334 *imx334) u32 lpfr; int ret; - ret = v4l2_ctrl_handler_init(ctrl_hdlr, 6); + ret = v4l2_ctrl_handler_init(ctrl_hdlr, 7); if (ret) return ret; @@ -1282,6 +1323,11 @@ static int imx334_init_controls(struct imx334 *imx334) if (imx334->hblank_ctrl) imx334->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; + v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx334_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(imx334_test_pattern_menu) - 1, + 0, 0, imx334_test_pattern_menu); + if (ctrl_hdlr->error) { dev_err(imx334->dev, "control init failed: %d", ctrl_hdlr->error); diff --git a/drivers/media/i2c/imx335.c b/drivers/media/i2c/imx335.c index 482a0b7f04..964a81bec5 100644 --- a/drivers/media/i2c/imx335.c +++ b/drivers/media/i2c/imx335.c @@ -119,7 +119,6 @@ struct imx335_mode { * @vblank: Vertical blanking in lines * @cur_mode: Pointer to current selected sensor mode * @mutex: Mutex for serializing sensor controls - * @streaming: Flag indicating streaming state */ struct imx335 { struct device *dev; @@ -140,7 +139,6 @@ struct imx335 { u32 vblank; const struct imx335_mode *cur_mode; struct mutex mutex; - bool streaming; }; static const s64 link_freq[] = { @@ -705,11 +703,6 @@ static int imx335_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&imx335->mutex); - if (imx335->streaming == enable) { - mutex_unlock(&imx335->mutex); - return 0; - } - if (enable) { ret = pm_runtime_resume_and_get(imx335->dev); if (ret) @@ -723,8 +716,6 @@ static int imx335_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(imx335->dev); } - imx335->streaming = enable; - mutex_unlock(&imx335->mutex); return 0; @@ -971,8 +962,8 @@ static int imx335_init_controls(struct imx335 *imx335) imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_HBLANK, - IMX335_REG_MIN, - IMX335_REG_MAX, + mode->hblank, + mode->hblank, 1, mode->hblank); if (imx335->hblank_ctrl) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c index 059a41b7ee..81bb61407b 100644 --- a/drivers/media/i2c/imx355.c +++ b/drivers/media/i2c/imx355.c @@ -123,9 +123,6 @@ struct imx355 { * Protect access to sensor v4l2 controls. */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; static const struct imx355_reg imx355_global_regs[] = { @@ -1436,10 +1433,6 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&imx355->mutex); - if (imx355->streaming == enable) { - mutex_unlock(&imx355->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -1458,8 +1451,6 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - imx355->streaming = enable; - /* vflip and hflip cannot change during streaming */ __v4l2_ctrl_grab(imx355->vflip, enable); __v4l2_ctrl_grab(imx355->hflip, enable); @@ -1476,37 +1467,6 @@ err_unlock: return ret; } -static int __maybe_unused imx355_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx355 *imx355 = to_imx355(sd); - - if (imx355->streaming) - imx355_stop_streaming(imx355); - - return 0; -} - -static int __maybe_unused imx355_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct imx355 *imx355 = to_imx355(sd); - int ret; - - if (imx355->streaming) { - ret = imx355_start_streaming(imx355); - if (ret) - goto error; - } - - return 0; - -error: - imx355_stop_streaming(imx355); - imx355->streaming = 0; - return ret; -} - /* Verify chip ID */ static int imx355_identify_module(struct imx355 *imx355) { @@ -1831,10 +1791,6 @@ static void imx355_remove(struct i2c_client *client) mutex_destroy(&imx355->mutex); } -static const struct dev_pm_ops imx355_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume) -}; - static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = { { "SONY355A" }, { /* sentinel */ } @@ -1844,7 +1800,6 @@ MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids); static struct i2c_driver imx355_i2c_driver = { .driver = { .name = "imx355", - .pm = &imx355_pm_ops, .acpi_match_table = ACPI_PTR(imx355_acpi_ids), }, .probe = imx355_probe, diff --git a/drivers/media/i2c/imx412.c b/drivers/media/i2c/imx412.c index c7e862ae40..962b3136c3 100644 --- a/drivers/media/i2c/imx412.c +++ b/drivers/media/i2c/imx412.c @@ -127,7 +127,6 @@ static const char * const imx412_supply_names[] = { * @vblank: Vertical blanking in lines * @cur_mode: Pointer to current selected sensor mode * @mutex: Mutex for serializing sensor controls - * @streaming: Flag indicating streaming state */ struct imx412 { struct device *dev; @@ -149,7 +148,6 @@ struct imx412 { u32 vblank; const struct imx412_mode *cur_mode; struct mutex mutex; - bool streaming; }; static const s64 link_freq[] = { @@ -857,11 +855,6 @@ static int imx412_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&imx412->mutex); - if (imx412->streaming == enable) { - mutex_unlock(&imx412->mutex); - return 0; - } - if (enable) { ret = pm_runtime_resume_and_get(imx412->dev); if (ret) @@ -875,8 +868,6 @@ static int imx412_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(imx412->dev); } - imx412->streaming = enable; - mutex_unlock(&imx412->mutex); return 0; diff --git a/drivers/media/i2c/imx415.c b/drivers/media/i2c/imx415.c index 3f00172df3..b3fa71a168 100644 --- a/drivers/media/i2c/imx415.c +++ b/drivers/media/i2c/imx415.c @@ -353,8 +353,6 @@ struct imx415 { const struct imx415_clk_params *clk_params; - bool streaming; - struct v4l2_subdev subdev; struct media_pad pad; @@ -542,8 +540,9 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl) struct v4l2_subdev_state *state; unsigned int vmax; unsigned int flip; + int ret; - if (!sensor->streaming) + if (!pm_runtime_get_if_in_use(sensor->dev)) return 0; state = v4l2_subdev_get_locked_active_state(&sensor->subdev); @@ -554,24 +553,33 @@ static int imx415_s_ctrl(struct v4l2_ctrl *ctrl) /* clamp the exposure value to VMAX. */ vmax = format->height + sensor->vblank->cur.val; ctrl->val = min_t(int, ctrl->val, vmax); - return imx415_write(sensor, IMX415_SHR0, vmax - ctrl->val); + ret = imx415_write(sensor, IMX415_SHR0, vmax - ctrl->val); + break; case V4L2_CID_ANALOGUE_GAIN: /* analogue gain in 0.3 dB step size */ - return imx415_write(sensor, IMX415_GAIN_PCG_0, ctrl->val); + ret = imx415_write(sensor, IMX415_GAIN_PCG_0, ctrl->val); + break; case V4L2_CID_HFLIP: case V4L2_CID_VFLIP: flip = (sensor->hflip->val << IMX415_HREVERSE_SHIFT) | (sensor->vflip->val << IMX415_VREVERSE_SHIFT); - return imx415_write(sensor, IMX415_REVERSE, flip); + ret = imx415_write(sensor, IMX415_REVERSE, flip); + break; case V4L2_CID_TEST_PATTERN: - return imx415_set_testpattern(sensor, ctrl->val); + ret = imx415_set_testpattern(sensor, ctrl->val); + break; default: - return -EINVAL; + ret = -EINVAL; + break; } + + pm_runtime_put(sensor->dev); + + return ret; } static const struct v4l2_ctrl_ops imx415_ctrl_ops = { @@ -766,8 +774,6 @@ static int imx415_s_stream(struct v4l2_subdev *sd, int enable) pm_runtime_mark_last_busy(sensor->dev); pm_runtime_put_autosuspend(sensor->dev); - sensor->streaming = false; - goto unlock; } @@ -779,13 +785,6 @@ static int imx415_s_stream(struct v4l2_subdev *sd, int enable) if (ret) goto err_pm; - /* - * Set streaming to true to ensure __v4l2_ctrl_handler_setup() will set - * the controls. The flag is reset to false further down if an error - * occurs. - */ - sensor->streaming = true; - ret = __v4l2_ctrl_handler_setup(&sensor->ctrls); if (ret < 0) goto err_pm; @@ -807,7 +806,6 @@ err_pm: * likely has no other chance to recover. */ pm_runtime_put_sync(sensor->dev); - sensor->streaming = false; goto unlock; } @@ -842,15 +840,6 @@ static int imx415_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int imx415_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *state, - struct v4l2_subdev_format *fmt) -{ - fmt->format = *v4l2_subdev_get_pad_format(sd, state, fmt->pad); - - return 0; -} - static int imx415_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *state, struct v4l2_subdev_format *fmt) @@ -913,7 +902,7 @@ static const struct v4l2_subdev_video_ops imx415_subdev_video_ops = { static const struct v4l2_subdev_pad_ops imx415_subdev_pad_ops = { .enum_mbus_code = imx415_enum_mbus_code, .enum_frame_size = imx415_enum_frame_size, - .get_fmt = imx415_get_format, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = imx415_set_format, .get_selection = imx415_get_selection, .init_cfg = imx415_init_cfg, diff --git a/drivers/media/i2c/msp3400-driver.c b/drivers/media/i2c/msp3400-driver.c index bec7680148..0ed8561edf 100644 --- a/drivers/media/i2c/msp3400-driver.c +++ b/drivers/media/i2c/msp3400-driver.c @@ -561,7 +561,7 @@ static int msp_log_status(struct v4l2_subdev *sd) struct msp_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); const char *p; - char prefix[V4L2_SUBDEV_NAME_SIZE + 20]; + char prefix[sizeof(sd->name) + 20]; if (state->opmode == OPMODE_AUTOSELECT) msp_detect_stereo(client); diff --git a/drivers/media/i2c/mt9m001.c b/drivers/media/i2c/mt9m001.c index ce9568e839..79192cf79d 100644 --- a/drivers/media/i2c/mt9m001.c +++ b/drivers/media/i2c/mt9m001.c @@ -93,7 +93,6 @@ struct mt9m001 { struct v4l2_ctrl *autoexposure; struct v4l2_ctrl *exposure; }; - bool streaming; struct mutex mutex; struct v4l2_rect rect; /* Sensor window */ struct clk *clk; @@ -213,9 +212,6 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&mt9m001->mutex); - if (mt9m001->streaming == enable) - goto done; - if (enable) { ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) @@ -239,8 +235,6 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - mt9m001->streaming = enable; -done: mutex_unlock(&mt9m001->mutex); return 0; diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c index df8d9c9e6a..1f44b72e8a 100644 --- a/drivers/media/i2c/mt9m111.c +++ b/drivers/media/i2c/mt9m111.c @@ -244,9 +244,7 @@ struct mt9m111 { bool is_streaming; /* user point of view - 0: falling 1: rising edge */ unsigned int pclk_sample:1; -#ifdef CONFIG_MEDIA_CONTROLLER struct media_pad pad; -#endif }; static const struct mt9m111_mode_info mt9m111_mode_data[MT9M111_NUM_MODES] = { @@ -527,13 +525,9 @@ static int mt9m111_get_fmt(struct v4l2_subdev *sd, return -EINVAL; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mf = v4l2_subdev_get_try_format(sd, sd_state, format->pad); format->format = *mf; return 0; -#else - return -EINVAL; -#endif } mf->width = mt9m111->width; @@ -1120,7 +1114,6 @@ static int mt9m111_s_stream(struct v4l2_subdev *sd, int enable) static int mt9m111_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, sd_state, 0); @@ -1132,7 +1125,7 @@ static int mt9m111_init_cfg(struct v4l2_subdev *sd, format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; format->quantization = V4L2_QUANTIZATION_DEFAULT; format->xfer_func = V4L2_XFER_FUNC_DEFAULT; -#endif + return 0; } @@ -1315,13 +1308,11 @@ static int mt9m111_probe(struct i2c_client *client) return ret; } -#ifdef CONFIG_MEDIA_CONTROLLER mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE; mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad); if (ret < 0) goto out_hdlfree; -#endif mt9m111->current_mode = &mt9m111_mode_data[MT9M111_MODE_SXGA_15FPS]; mt9m111->frame_interval.numerator = 1; @@ -1350,10 +1341,8 @@ static int mt9m111_probe(struct i2c_client *client) return 0; out_entityclean: -#ifdef CONFIG_MEDIA_CONTROLLER media_entity_cleanup(&mt9m111->subdev.entity); out_hdlfree: -#endif v4l2_ctrl_handler_free(&mt9m111->hdl); return ret; diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c new file mode 100644 index 0000000000..1a535c098d --- /dev/null +++ b/drivers/media/i2c/mt9m114.c @@ -0,0 +1,2481 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * mt9m114.c onsemi MT9M114 sensor driver + * + * Copyright (c) 2020-2023 Laurent Pinchart <laurent.pinchart@ideasonboard.com> + * Copyright (c) 2012 Analog Devices Inc. + * + * Almost complete rewrite of work by Scott Jiang <Scott.Jiang.Linux@gmail.com> + * itself based on work from Andrew Chew <achew@nvidia.com>. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/types.h> +#include <linux/videodev2.h> + +#include <media/v4l2-async.h> +#include <media/v4l2-cci.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-mediabus.h> +#include <media/v4l2-subdev.h> + +/* Sysctl registers */ +#define MT9M114_CHIP_ID CCI_REG16(0x0000) +#define MT9M114_COMMAND_REGISTER CCI_REG16(0x0080) +#define MT9M114_COMMAND_REGISTER_APPLY_PATCH BIT(0) +#define MT9M114_COMMAND_REGISTER_SET_STATE BIT(1) +#define MT9M114_COMMAND_REGISTER_REFRESH BIT(2) +#define MT9M114_COMMAND_REGISTER_WAIT_FOR_EVENT BIT(3) +#define MT9M114_COMMAND_REGISTER_OK BIT(15) +#define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a) +#define MT9M114_RESET_SOC BIT(0) +#define MT9M114_PAD_SLEW CCI_REG16(0x001e) +#define MT9M114_PAD_CONTROL CCI_REG16(0x0032) + +/* XDMA registers */ +#define MT9M114_ACCESS_CTL_STAT CCI_REG16(0x0982) +#define MT9M114_PHYSICAL_ADDRESS_ACCESS CCI_REG16(0x098a) +#define MT9M114_LOGICAL_ADDRESS_ACCESS CCI_REG16(0x098e) + +/* Sensor Core registers */ +#define MT9M114_COARSE_INTEGRATION_TIME CCI_REG16(0x3012) +#define MT9M114_FINE_INTEGRATION_TIME CCI_REG16(0x3014) +#define MT9M114_RESET_REGISTER CCI_REG16(0x301a) +#define MT9M114_RESET_REGISTER_LOCK_REG BIT(3) +#define MT9M114_RESET_REGISTER_MASK_BAD BIT(9) +#define MT9M114_FLASH CCI_REG16(0x3046) +#define MT9M114_GREEN1_GAIN CCI_REG16(0x3056) +#define MT9M114_BLUE_GAIN CCI_REG16(0x3058) +#define MT9M114_RED_GAIN CCI_REG16(0x305a) +#define MT9M114_GREEN2_GAIN CCI_REG16(0x305c) +#define MT9M114_GLOBAL_GAIN CCI_REG16(0x305e) +#define MT9M114_GAIN_DIGITAL_GAIN(n) ((n) << 12) +#define MT9M114_GAIN_DIGITAL_GAIN_MASK (0xf << 12) +#define MT9M114_GAIN_ANALOG_GAIN(n) ((n) << 0) +#define MT9M114_GAIN_ANALOG_GAIN_MASK (0xff << 0) +#define MT9M114_CUSTOMER_REV CCI_REG16(0x31fe) + +/* Monitor registers */ +#define MT9M114_MON_MAJOR_VERSION CCI_REG16(0x8000) +#define MT9M114_MON_MINOR_VERSION CCI_REG16(0x8002) +#define MT9M114_MON_RELEASE_VERSION CCI_REG16(0x8004) + +/* Auto-Exposure Track registers */ +#define MT9M114_AE_TRACK_ALGO CCI_REG16(0xa804) +#define MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE BIT(0) +#define MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED CCI_REG8(0xa80a) + +/* Color Correction Matrix registers */ +#define MT9M114_CCM_ALGO CCI_REG16(0xb404) +#define MT9M114_CCM_EXEC_CALC_CCM_MATRIX BIT(4) +#define MT9M114_CCM_DELTA_GAIN CCI_REG8(0xb42a) + +/* Camera Control registers */ +#define MT9M114_CAM_SENSOR_CFG_Y_ADDR_START CCI_REG16(0xc800) +#define MT9M114_CAM_SENSOR_CFG_X_ADDR_START CCI_REG16(0xc802) +#define MT9M114_CAM_SENSOR_CFG_Y_ADDR_END CCI_REG16(0xc804) +#define MT9M114_CAM_SENSOR_CFG_X_ADDR_END CCI_REG16(0xc806) +#define MT9M114_CAM_SENSOR_CFG_PIXCLK CCI_REG32(0xc808) +#define MT9M114_CAM_SENSOR_CFG_ROW_SPEED CCI_REG16(0xc80c) +#define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN CCI_REG16(0xc80e) +#define MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX CCI_REG16(0xc810) +#define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES CCI_REG16(0xc812) +#define MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX 65535 +#define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK CCI_REG16(0xc814) +#define MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX 8191 +#define MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION CCI_REG16(0xc816) +#define MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW CCI_REG16(0xc818) +#define MT9M114_CAM_SENSOR_CFG_REG_0_DATA CCI_REG16(0xc826) +#define MT9M114_CAM_SENSOR_CONTROL_READ_MODE CCI_REG16(0xc834) +#define MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN BIT(0) +#define MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN BIT(1) +#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_NORMAL (0 << 4) +#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SKIPPING (1 << 4) +#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_AVERAGE (2 << 4) +#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING (3 << 4) +#define MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK (3 << 4) +#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_NORMAL (0 << 8) +#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SKIPPING (1 << 8) +#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING (3 << 8) +#define MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK (3 << 8) +#define MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN CCI_REG16(0xc836) +#define MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME CCI_REG16(0xc83c) +#define MT9M114_CAM_SENSOR_CONTROL_FINE_INTEGRATION_TIME CCI_REG16(0xc83e) +#define MT9M114_CAM_MODE_SELECT CCI_REG8(0xc84c) +#define MT9M114_CAM_MODE_SELECT_NORMAL (0 << 0) +#define MT9M114_CAM_MODE_SELECT_LENS_CALIBRATION (1 << 0) +#define MT9M114_CAM_MODE_SELECT_TEST_PATTERN (2 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT CCI_REG8(0xc84d) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID (1 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS (4 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM (5 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS (8 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B (10 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B (11 << 0) +#define MT9M114_CAM_MODE_TEST_PATTERN_RED CCI_REG16(0xc84e) +#define MT9M114_CAM_MODE_TEST_PATTERN_GREEN CCI_REG16(0xc850) +#define MT9M114_CAM_MODE_TEST_PATTERN_BLUE CCI_REG16(0xc852) +#define MT9M114_CAM_CROP_WINDOW_XOFFSET CCI_REG16(0xc854) +#define MT9M114_CAM_CROP_WINDOW_YOFFSET CCI_REG16(0xc856) +#define MT9M114_CAM_CROP_WINDOW_WIDTH CCI_REG16(0xc858) +#define MT9M114_CAM_CROP_WINDOW_HEIGHT CCI_REG16(0xc85a) +#define MT9M114_CAM_CROP_CROPMODE CCI_REG8(0xc85c) +#define MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN BIT(0) +#define MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN BIT(1) +#define MT9M114_CAM_OUTPUT_WIDTH CCI_REG16(0xc868) +#define MT9M114_CAM_OUTPUT_HEIGHT CCI_REG16(0xc86a) +#define MT9M114_CAM_OUTPUT_FORMAT CCI_REG16(0xc86c) +#define MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE BIT(0) +#define MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES BIT(1) +#define MT9M114_CAM_OUTPUT_FORMAT_MONO_ENABLE BIT(2) +#define MT9M114_CAM_OUTPUT_FORMAT_BT656_ENABLE BIT(3) +#define MT9M114_CAM_OUTPUT_FORMAT_BT656_CROP_SCALE_DISABLE BIT(4) +#define MT9M114_CAM_OUTPUT_FORMAT_FVLV_DISABLE BIT(5) +#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV (0 << 8) +#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB (1 << 8) +#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER (2 << 8) +#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_NONE (3 << 8) +#define MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK (3 << 8) +#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10 (0 << 10) +#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PRELSC_8_2 (1 << 10) +#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_POSTLSC_8_2 (2 << 10) +#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8 (3 << 10) +#define MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK (3 << 10) +#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB (0 << 12) +#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_555RGB (1 << 12) +#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444xRGB (2 << 12) +#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_444RGBx (3 << 12) +#define MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK (3 << 12) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV CCI_REG16(0xc86e) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_CLIP BIT(5) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_AUV_OFFSET BIT(4) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SELECT_601 BIT(3) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_NORMALISE BIT(2) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVEN_UV (0 << 0) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_ODD_UV (1 << 0) +#define MT9M114_CAM_OUTPUT_FORMAT_YUV_SAMPLING_EVENU_ODDV (2 << 0) +#define MT9M114_CAM_OUTPUT_Y_OFFSET CCI_REG8(0xc870) +#define MT9M114_CAM_AET_AEMODE CCI_REG8(0xc878) +#define MT9M114_CAM_AET_EXEC_SET_INDOOR BIT(0) +#define MT9M114_CAM_AET_DISCRETE_FRAMERATE BIT(1) +#define MT9M114_CAM_AET_ADAPTATIVE_TARGET_LUMA BIT(2) +#define MT9M114_CAM_AET_ADAPTATIVE_SKIP_FRAMES BIT(3) +#define MT9M114_CAM_AET_SKIP_FRAMES CCI_REG8(0xc879) +#define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA CCI_REG8(0xc87a) +#define MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK CCI_REG8(0xc87b) +#define MT9M114_CAM_AET_BLACK_CLIPPING_TARGET CCI_REG16(0xc87c) +#define MT9M114_CAM_AET_AE_MIN_VIRT_INT_TIME_PCLK CCI_REG16(0xc87e) +#define MT9M114_CAM_AET_AE_MIN_VIRT_DGAIN CCI_REG16(0xc880) +#define MT9M114_CAM_AET_AE_MAX_VIRT_DGAIN CCI_REG16(0xc882) +#define MT9M114_CAM_AET_AE_MIN_VIRT_AGAIN CCI_REG16(0xc884) +#define MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN CCI_REG16(0xc886) +#define MT9M114_CAM_AET_AE_VIRT_GAIN_TH_EG CCI_REG16(0xc888) +#define MT9M114_CAM_AET_AE_EG_GATE_PERCENTAGE CCI_REG8(0xc88a) +#define MT9M114_CAM_AET_FLICKER_FREQ_HZ CCI_REG8(0xc88b) +#define MT9M114_CAM_AET_MAX_FRAME_RATE CCI_REG16(0xc88c) +#define MT9M114_CAM_AET_MIN_FRAME_RATE CCI_REG16(0xc88e) +#define MT9M114_CAM_AET_TARGET_GAIN CCI_REG16(0xc890) +#define MT9M114_CAM_AWB_CCM_L(n) CCI_REG16(0xc892 + (n) * 2) +#define MT9M114_CAM_AWB_CCM_M(n) CCI_REG16(0xc8a4 + (n) * 2) +#define MT9M114_CAM_AWB_CCM_R(n) CCI_REG16(0xc8b6 + (n) * 2) +#define MT9M114_CAM_AWB_CCM_L_RG_GAIN CCI_REG16(0xc8c8) +#define MT9M114_CAM_AWB_CCM_L_BG_GAIN CCI_REG16(0xc8ca) +#define MT9M114_CAM_AWB_CCM_M_RG_GAIN CCI_REG16(0xc8cc) +#define MT9M114_CAM_AWB_CCM_M_BG_GAIN CCI_REG16(0xc8ce) +#define MT9M114_CAM_AWB_CCM_R_RG_GAIN CCI_REG16(0xc8d0) +#define MT9M114_CAM_AWB_CCM_R_BG_GAIN CCI_REG16(0xc8d2) +#define MT9M114_CAM_AWB_CCM_L_CTEMP CCI_REG16(0xc8d4) +#define MT9M114_CAM_AWB_CCM_M_CTEMP CCI_REG16(0xc8d6) +#define MT9M114_CAM_AWB_CCM_R_CTEMP CCI_REG16(0xc8d8) +#define MT9M114_CAM_AWB_AWB_XSCALE CCI_REG8(0xc8f2) +#define MT9M114_CAM_AWB_AWB_YSCALE CCI_REG8(0xc8f3) +#define MT9M114_CAM_AWB_AWB_WEIGHTS(n) CCI_REG16(0xc8f4 + (n) * 2) +#define MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ CCI_REG16(0xc904) +#define MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ CCI_REG16(0xc906) +#define MT9M114_CAM_AWB_AWBMODE CCI_REG8(0xc909) +#define MT9M114_CAM_AWB_MODE_AUTO BIT(1) +#define MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE BIT(0) +#define MT9M114_CAM_AWB_K_R_L CCI_REG8(0xc90c) +#define MT9M114_CAM_AWB_K_G_L CCI_REG8(0xc90d) +#define MT9M114_CAM_AWB_K_B_L CCI_REG8(0xc90e) +#define MT9M114_CAM_AWB_K_R_R CCI_REG8(0xc90f) +#define MT9M114_CAM_AWB_K_G_R CCI_REG8(0xc910) +#define MT9M114_CAM_AWB_K_B_R CCI_REG8(0xc911) +#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART CCI_REG16(0xc914) +#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART CCI_REG16(0xc916) +#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND CCI_REG16(0xc918) +#define MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND CCI_REG16(0xc91a) +#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART CCI_REG16(0xc91c) +#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART CCI_REG16(0xc91e) +#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND CCI_REG16(0xc920) +#define MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND CCI_REG16(0xc922) +#define MT9M114_CAM_LL_LLMODE CCI_REG16(0xc924) +#define MT9M114_CAM_LL_START_BRIGHTNESS CCI_REG16(0xc926) +#define MT9M114_CAM_LL_STOP_BRIGHTNESS CCI_REG16(0xc928) +#define MT9M114_CAM_LL_START_SATURATION CCI_REG8(0xc92a) +#define MT9M114_CAM_LL_END_SATURATION CCI_REG8(0xc92b) +#define MT9M114_CAM_LL_START_DESATURATION CCI_REG8(0xc92c) +#define MT9M114_CAM_LL_END_DESATURATION CCI_REG8(0xc92d) +#define MT9M114_CAM_LL_START_DEMOSAICING CCI_REG8(0xc92e) +#define MT9M114_CAM_LL_START_AP_GAIN CCI_REG8(0xc92f) +#define MT9M114_CAM_LL_START_AP_THRESH CCI_REG8(0xc930) +#define MT9M114_CAM_LL_STOP_DEMOSAICING CCI_REG8(0xc931) +#define MT9M114_CAM_LL_STOP_AP_GAIN CCI_REG8(0xc932) +#define MT9M114_CAM_LL_STOP_AP_THRESH CCI_REG8(0xc933) +#define MT9M114_CAM_LL_START_NR_RED CCI_REG8(0xc934) +#define MT9M114_CAM_LL_START_NR_GREEN CCI_REG8(0xc935) +#define MT9M114_CAM_LL_START_NR_BLUE CCI_REG8(0xc936) +#define MT9M114_CAM_LL_START_NR_THRESH CCI_REG8(0xc937) +#define MT9M114_CAM_LL_STOP_NR_RED CCI_REG8(0xc938) +#define MT9M114_CAM_LL_STOP_NR_GREEN CCI_REG8(0xc939) +#define MT9M114_CAM_LL_STOP_NR_BLUE CCI_REG8(0xc93a) +#define MT9M114_CAM_LL_STOP_NR_THRESH CCI_REG8(0xc93b) +#define MT9M114_CAM_LL_START_CONTRAST_BM CCI_REG16(0xc93c) +#define MT9M114_CAM_LL_STOP_CONTRAST_BM CCI_REG16(0xc93e) +#define MT9M114_CAM_LL_GAMMA CCI_REG16(0xc940) +#define MT9M114_CAM_LL_START_CONTRAST_GRADIENT CCI_REG8(0xc942) +#define MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT CCI_REG8(0xc943) +#define MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc944) +#define MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE CCI_REG8(0xc945) +#define MT9M114_CAM_LL_START_GAIN_METRIC CCI_REG16(0xc946) +#define MT9M114_CAM_LL_STOP_GAIN_METRIC CCI_REG16(0xc948) +#define MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA CCI_REG16(0xc94a) +#define MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA CCI_REG16(0xc94c) +#define MT9M114_CAM_LL_CLUSTER_DC_TH_BM CCI_REG16(0xc94e) +#define MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE CCI_REG8(0xc950) +#define MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR CCI_REG8(0xc951) +#define MT9M114_CAM_LL_START_TARGET_LUMA_BM CCI_REG16(0xc952) +#define MT9M114_CAM_LL_STOP_TARGET_LUMA_BM CCI_REG16(0xc954) +#define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e) +#define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e) +#define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0) +#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980) +#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m)) +#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982) +#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(p) ((p) << 8) +#define MT9M114_CAM_PORT_OUTPUT_CONTROL CCI_REG16(0xc984) +#define MT9M114_CAM_PORT_PORT_SELECT_PARALLEL (0 << 0) +#define MT9M114_CAM_PORT_PORT_SELECT_MIPI (1 << 0) +#define MT9M114_CAM_PORT_CLOCK_SLOWDOWN BIT(3) +#define MT9M114_CAM_PORT_TRUNCATE_RAW_BAYER BIT(4) +#define MT9M114_CAM_PORT_PIXCLK_GATE BIT(5) +#define MT9M114_CAM_PORT_CONT_MIPI_CLK BIT(6) +#define MT9M114_CAM_PORT_CHAN_NUM(vc) ((vc) << 8) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO CCI_REG16(0xc988) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_ZERO_VALUE(n) ((n) << 8) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_TRAIL CCI_REG16(0xc98a) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_EXIT_VALUE(n) ((n) << 8) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_HS_TRAIL_VALUE(n) ((n) << 0) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_PRE CCI_REG16(0xc98c) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_POST_VALUE(n) ((n) << 8) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_PRE_VALUE(n) ((n) << 0) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_ZERO CCI_REG16(0xc98e) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_TRAIL_VALUE(n) ((n) << 8) +#define MT9M114_CAM_PORT_MIPI_TIMING_T_CLK_ZERO_VALUE(n) ((n) << 0) + +/* System Manager registers */ +#define MT9M114_SYSMGR_NEXT_STATE CCI_REG8(0xdc00) +#define MT9M114_SYSMGR_CURRENT_STATE CCI_REG8(0xdc01) +#define MT9M114_SYSMGR_CMD_STATUS CCI_REG8(0xdc02) + +/* Patch Loader registers */ +#define MT9M114_PATCHLDR_LOADER_ADDRESS CCI_REG16(0xe000) +#define MT9M114_PATCHLDR_PATCH_ID CCI_REG16(0xe002) +#define MT9M114_PATCHLDR_FIRMWARE_ID CCI_REG32(0xe004) +#define MT9M114_PATCHLDR_APPLY_STATUS CCI_REG8(0xe008) +#define MT9M114_PATCHLDR_NUM_PATCHES CCI_REG8(0xe009) +#define MT9M114_PATCHLDR_PATCH_ID_0 CCI_REG16(0xe00a) +#define MT9M114_PATCHLDR_PATCH_ID_1 CCI_REG16(0xe00c) +#define MT9M114_PATCHLDR_PATCH_ID_2 CCI_REG16(0xe00e) +#define MT9M114_PATCHLDR_PATCH_ID_3 CCI_REG16(0xe010) +#define MT9M114_PATCHLDR_PATCH_ID_4 CCI_REG16(0xe012) +#define MT9M114_PATCHLDR_PATCH_ID_5 CCI_REG16(0xe014) +#define MT9M114_PATCHLDR_PATCH_ID_6 CCI_REG16(0xe016) +#define MT9M114_PATCHLDR_PATCH_ID_7 CCI_REG16(0xe018) + +/* SYS_STATE values (for SYSMGR_NEXT_STATE and SYSMGR_CURRENT_STATE) */ +#define MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE 0x28 +#define MT9M114_SYS_STATE_STREAMING 0x31 +#define MT9M114_SYS_STATE_START_STREAMING 0x34 +#define MT9M114_SYS_STATE_ENTER_SUSPEND 0x40 +#define MT9M114_SYS_STATE_SUSPENDED 0x41 +#define MT9M114_SYS_STATE_ENTER_STANDBY 0x50 +#define MT9M114_SYS_STATE_STANDBY 0x52 +#define MT9M114_SYS_STATE_LEAVE_STANDBY 0x54 + +/* Result status of last SET_STATE comamnd */ +#define MT9M114_SET_STATE_RESULT_ENOERR 0x00 +#define MT9M114_SET_STATE_RESULT_EINVAL 0x0c +#define MT9M114_SET_STATE_RESULT_ENOSPC 0x0d + +/* + * The minimum amount of horizontal and vertical blanking is undocumented. The + * minimum values that have been seen in register lists are 303 and 38, use + * them. + * + * Set the default to achieve 1280x960 at 30fps. + */ +#define MT9M114_MIN_HBLANK 303 +#define MT9M114_MIN_VBLANK 38 +#define MT9M114_DEF_HBLANK 323 +#define MT9M114_DEF_VBLANK 39 + +#define MT9M114_DEF_FRAME_RATE 30 +#define MT9M114_MAX_FRAME_RATE 120 + +#define MT9M114_PIXEL_ARRAY_WIDTH 1296U +#define MT9M114_PIXEL_ARRAY_HEIGHT 976U + +/* + * These values are not well documented and are semi-arbitrary. The pixel array + * minimum output size is 8 pixels larger than the minimum scaler cropped input + * width to account for the demosaicing. + */ +#define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH (32U + 8U) +#define MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT (32U + 8U) +#define MT9M114_SCALER_CROPPED_INPUT_WIDTH 32U +#define MT9M114_SCALER_CROPPED_INPUT_HEIGHT 32U + +/* Indices into the mt9m114.ifp.tpg array. */ +#define MT9M114_TPG_PATTERN 0 +#define MT9M114_TPG_RED 1 +#define MT9M114_TPG_GREEN 2 +#define MT9M114_TPG_BLUE 3 + +/* ----------------------------------------------------------------------------- + * Data Structures + */ + +enum mt9m114_format_flag { + MT9M114_FMT_FLAG_PARALLEL = BIT(0), + MT9M114_FMT_FLAG_CSI2 = BIT(1), +}; + +struct mt9m114_format_info { + u32 code; + u32 output_format; + u32 flags; +}; + +struct mt9m114 { + struct i2c_client *client; + struct regmap *regmap; + + struct clk *clk; + struct gpio_desc *reset; + struct regulator_bulk_data supplies[3]; + struct v4l2_fwnode_endpoint bus_cfg; + + struct { + unsigned int m; + unsigned int n; + unsigned int p; + } pll; + + unsigned int pixrate; + bool streaming; + + /* Pixel Array */ + struct { + struct v4l2_subdev sd; + struct media_pad pad; + + struct v4l2_ctrl_handler hdl; + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; + struct v4l2_ctrl *hblank; + struct v4l2_ctrl *vblank; + } pa; + + /* Image Flow Processor */ + struct { + struct v4l2_subdev sd; + struct media_pad pads[2]; + + struct v4l2_ctrl_handler hdl; + unsigned int frame_rate; + + struct v4l2_ctrl *tpg[4]; + } ifp; +}; + +/* ----------------------------------------------------------------------------- + * Formats + */ + +static const struct mt9m114_format_info mt9m114_format_infos[] = { + { + /* + * The first two entries are used as defaults, for parallel and + * CSI-2 buses respectively. Keep them in that order. + */ + .code = MEDIA_BUS_FMT_UYVY8_2X8, + .flags = MT9M114_FMT_FLAG_PARALLEL, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV, + }, { + .code = MEDIA_BUS_FMT_UYVY8_1X16, + .flags = MT9M114_FMT_FLAG_CSI2, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV, + }, { + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .flags = MT9M114_FMT_FLAG_PARALLEL, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV + | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, + }, { + .code = MEDIA_BUS_FMT_YUYV8_1X16, + .flags = MT9M114_FMT_FLAG_CSI2, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_FORMAT_YUV + | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, + }, { + .code = MEDIA_BUS_FMT_RGB565_2X8_LE, + .flags = MT9M114_FMT_FLAG_PARALLEL, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB + | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB + | MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES, + }, { + .code = MEDIA_BUS_FMT_RGB565_2X8_BE, + .flags = MT9M114_FMT_FLAG_PARALLEL, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB + | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB, + }, { + .code = MEDIA_BUS_FMT_RGB565_1X16, + .flags = MT9M114_FMT_FLAG_CSI2, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_565RGB + | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_RGB, + }, { + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_PROCESSED8 + | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER, + .flags = MT9M114_FMT_FLAG_PARALLEL | MT9M114_FMT_FLAG_CSI2, + }, { + /* Keep the format compatible with the IFP sink pad last. */ + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .output_format = MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_RAWR10 + | MT9M114_CAM_OUTPUT_FORMAT_FORMAT_BAYER, + .flags = MT9M114_FMT_FLAG_PARALLEL | MT9M114_FMT_FLAG_CSI2, + } +}; + +static const struct mt9m114_format_info * +mt9m114_default_format_info(struct mt9m114 *sensor) +{ + if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) + return &mt9m114_format_infos[1]; + else + return &mt9m114_format_infos[0]; +} + +static const struct mt9m114_format_info * +mt9m114_format_info(struct mt9m114 *sensor, unsigned int pad, u32 code) +{ + const unsigned int num_formats = ARRAY_SIZE(mt9m114_format_infos); + unsigned int flag; + unsigned int i; + + switch (pad) { + case 0: + return &mt9m114_format_infos[num_formats - 1]; + + case 1: + if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) + flag = MT9M114_FMT_FLAG_CSI2; + else + flag = MT9M114_FMT_FLAG_PARALLEL; + + for (i = 0; i < num_formats; ++i) { + const struct mt9m114_format_info *info = + &mt9m114_format_infos[i]; + + if (info->code == code && info->flags & flag) + return info; + } + + return mt9m114_default_format_info(sensor); + + default: + return NULL; + } +} + +/* ----------------------------------------------------------------------------- + * Initialization + */ + +static const struct cci_reg_sequence mt9m114_init[] = { + { MT9M114_RESET_REGISTER, MT9M114_RESET_REGISTER_MASK_BAD | + MT9M114_RESET_REGISTER_LOCK_REG | + 0x0010 }, + + /* Sensor optimization */ + { CCI_REG16(0x316a), 0x8270 }, + { CCI_REG16(0x316c), 0x8270 }, + { CCI_REG16(0x3ed0), 0x2305 }, + { CCI_REG16(0x3ed2), 0x77cf }, + { CCI_REG16(0x316e), 0x8202 }, + { CCI_REG16(0x3180), 0x87ff }, + { CCI_REG16(0x30d4), 0x6080 }, + { CCI_REG16(0xa802), 0x0008 }, + + { CCI_REG16(0x3e14), 0xff39 }, + + /* APGA */ + { MT9M114_CAM_PGA_PGA_CONTROL, 0x0000 }, + + /* Automatic White balance */ + { MT9M114_CAM_AWB_CCM_L(0), 0x0267 }, + { MT9M114_CAM_AWB_CCM_L(1), 0xff1a }, + { MT9M114_CAM_AWB_CCM_L(2), 0xffb3 }, + { MT9M114_CAM_AWB_CCM_L(3), 0xff80 }, + { MT9M114_CAM_AWB_CCM_L(4), 0x0166 }, + { MT9M114_CAM_AWB_CCM_L(5), 0x0003 }, + { MT9M114_CAM_AWB_CCM_L(6), 0xff9a }, + { MT9M114_CAM_AWB_CCM_L(7), 0xfeb4 }, + { MT9M114_CAM_AWB_CCM_L(8), 0x024d }, + { MT9M114_CAM_AWB_CCM_M(0), 0x01bf }, + { MT9M114_CAM_AWB_CCM_M(1), 0xff01 }, + { MT9M114_CAM_AWB_CCM_M(2), 0xfff3 }, + { MT9M114_CAM_AWB_CCM_M(3), 0xff75 }, + { MT9M114_CAM_AWB_CCM_M(4), 0x0198 }, + { MT9M114_CAM_AWB_CCM_M(5), 0xfffd }, + { MT9M114_CAM_AWB_CCM_M(6), 0xff9a }, + { MT9M114_CAM_AWB_CCM_M(7), 0xfee7 }, + { MT9M114_CAM_AWB_CCM_M(8), 0x02a8 }, + { MT9M114_CAM_AWB_CCM_R(0), 0x01d9 }, + { MT9M114_CAM_AWB_CCM_R(1), 0xff26 }, + { MT9M114_CAM_AWB_CCM_R(2), 0xfff3 }, + { MT9M114_CAM_AWB_CCM_R(3), 0xffb3 }, + { MT9M114_CAM_AWB_CCM_R(4), 0x0132 }, + { MT9M114_CAM_AWB_CCM_R(5), 0xffe8 }, + { MT9M114_CAM_AWB_CCM_R(6), 0xffda }, + { MT9M114_CAM_AWB_CCM_R(7), 0xfecd }, + { MT9M114_CAM_AWB_CCM_R(8), 0x02c2 }, + { MT9M114_CAM_AWB_CCM_L_RG_GAIN, 0x0075 }, + { MT9M114_CAM_AWB_CCM_L_BG_GAIN, 0x011c }, + { MT9M114_CAM_AWB_CCM_M_RG_GAIN, 0x009a }, + { MT9M114_CAM_AWB_CCM_M_BG_GAIN, 0x0105 }, + { MT9M114_CAM_AWB_CCM_R_RG_GAIN, 0x00a4 }, + { MT9M114_CAM_AWB_CCM_R_BG_GAIN, 0x00ac }, + { MT9M114_CAM_AWB_CCM_L_CTEMP, 0x0a8c }, + { MT9M114_CAM_AWB_CCM_M_CTEMP, 0x0f0a }, + { MT9M114_CAM_AWB_CCM_R_CTEMP, 0x1964 }, + { MT9M114_CAM_AWB_AWB_XSHIFT_PRE_ADJ, 51 }, + { MT9M114_CAM_AWB_AWB_YSHIFT_PRE_ADJ, 60 }, + { MT9M114_CAM_AWB_AWB_XSCALE, 3 }, + { MT9M114_CAM_AWB_AWB_YSCALE, 2 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(0), 0x0000 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(1), 0x0000 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(2), 0x0000 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(3), 0xe724 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(4), 0x1583 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(5), 0x2045 }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(6), 0x03ff }, + { MT9M114_CAM_AWB_AWB_WEIGHTS(7), 0x007c }, + { MT9M114_CAM_AWB_K_R_L, 0x80 }, + { MT9M114_CAM_AWB_K_G_L, 0x80 }, + { MT9M114_CAM_AWB_K_B_L, 0x80 }, + { MT9M114_CAM_AWB_K_R_R, 0x88 }, + { MT9M114_CAM_AWB_K_G_R, 0x80 }, + { MT9M114_CAM_AWB_K_B_R, 0x80 }, + + /* Low-Light Image Enhancements */ + { MT9M114_CAM_LL_START_BRIGHTNESS, 0x0020 }, + { MT9M114_CAM_LL_STOP_BRIGHTNESS, 0x009a }, + { MT9M114_CAM_LL_START_GAIN_METRIC, 0x0070 }, + { MT9M114_CAM_LL_STOP_GAIN_METRIC, 0x00f3 }, + { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE, 0x20 }, + { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE, 0x9a }, + { MT9M114_CAM_LL_START_SATURATION, 0x80 }, + { MT9M114_CAM_LL_END_SATURATION, 0x4b }, + { MT9M114_CAM_LL_START_DESATURATION, 0x00 }, + { MT9M114_CAM_LL_END_DESATURATION, 0xff }, + { MT9M114_CAM_LL_START_DEMOSAICING, 0x3c }, + { MT9M114_CAM_LL_START_AP_GAIN, 0x02 }, + { MT9M114_CAM_LL_START_AP_THRESH, 0x06 }, + { MT9M114_CAM_LL_STOP_DEMOSAICING, 0x64 }, + { MT9M114_CAM_LL_STOP_AP_GAIN, 0x01 }, + { MT9M114_CAM_LL_STOP_AP_THRESH, 0x0c }, + { MT9M114_CAM_LL_START_NR_RED, 0x3c }, + { MT9M114_CAM_LL_START_NR_GREEN, 0x3c }, + { MT9M114_CAM_LL_START_NR_BLUE, 0x3c }, + { MT9M114_CAM_LL_START_NR_THRESH, 0x0f }, + { MT9M114_CAM_LL_STOP_NR_RED, 0x64 }, + { MT9M114_CAM_LL_STOP_NR_GREEN, 0x64 }, + { MT9M114_CAM_LL_STOP_NR_BLUE, 0x64 }, + { MT9M114_CAM_LL_STOP_NR_THRESH, 0x32 }, + { MT9M114_CAM_LL_START_CONTRAST_BM, 0x0020 }, + { MT9M114_CAM_LL_STOP_CONTRAST_BM, 0x009a }, + { MT9M114_CAM_LL_GAMMA, 0x00dc }, + { MT9M114_CAM_LL_START_CONTRAST_GRADIENT, 0x38 }, + { MT9M114_CAM_LL_STOP_CONTRAST_GRADIENT, 0x30 }, + { MT9M114_CAM_LL_START_CONTRAST_LUMA_PERCENTAGE, 0x50 }, + { MT9M114_CAM_LL_STOP_CONTRAST_LUMA_PERCENTAGE, 0x19 }, + { MT9M114_CAM_LL_START_FADE_TO_BLACK_LUMA, 0x0230 }, + { MT9M114_CAM_LL_STOP_FADE_TO_BLACK_LUMA, 0x0010 }, + { MT9M114_CAM_LL_CLUSTER_DC_TH_BM, 0x01cd }, + { MT9M114_CAM_LL_CLUSTER_DC_GATE_PERCENTAGE, 0x05 }, + { MT9M114_CAM_LL_SUMMING_SENSITIVITY_FACTOR, 0x40 }, + + /* Auto-Exposure */ + { MT9M114_CAM_AET_TARGET_AVERAGE_LUMA_DARK, 0x1b }, + { MT9M114_CAM_AET_AEMODE, 0x00 }, + { MT9M114_CAM_AET_TARGET_GAIN, 0x0080 }, + { MT9M114_CAM_AET_AE_MAX_VIRT_AGAIN, 0x0100 }, + { MT9M114_CAM_AET_BLACK_CLIPPING_TARGET, 0x005a }, + + { MT9M114_CCM_DELTA_GAIN, 0x05 }, + { MT9M114_AE_TRACK_AE_TRACKING_DAMPENING_SPEED, 0x20 }, + + /* Pixel array timings and integration time */ + { MT9M114_CAM_SENSOR_CFG_ROW_SPEED, 1 }, + { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MIN, 219 }, + { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 1459 }, + { MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION, 96 }, + { MT9M114_CAM_SENSOR_CFG_REG_0_DATA, 32 }, + + /* Miscellaneous settings */ + { MT9M114_PAD_SLEW, 0x0777 }, +}; + +/* ----------------------------------------------------------------------------- + * Hardware Configuration + */ + +/* Wait for a command to complete. */ +static int mt9m114_poll_command(struct mt9m114 *sensor, u32 command) +{ + unsigned int i; + u64 value; + int ret; + + for (i = 0; i < 100; ++i) { + ret = cci_read(sensor->regmap, MT9M114_COMMAND_REGISTER, &value, + NULL); + if (ret < 0) + return ret; + + if (!(value & command)) + break; + + usleep_range(5000, 6000); + } + + if (value & command) { + dev_err(&sensor->client->dev, "Command %u completion timeout\n", + command); + return -ETIMEDOUT; + } + + if (!(value & MT9M114_COMMAND_REGISTER_OK)) { + dev_err(&sensor->client->dev, "Command %u failed\n", command); + return -EIO; + } + + return 0; +} + +/* Wait for a state to be entered. */ +static int mt9m114_poll_state(struct mt9m114 *sensor, u32 state) +{ + unsigned int i; + u64 value; + int ret; + + for (i = 0; i < 100; ++i) { + ret = cci_read(sensor->regmap, MT9M114_SYSMGR_CURRENT_STATE, + &value, NULL); + if (ret < 0) + return ret; + + if (value == state) + return 0; + + usleep_range(1000, 1500); + } + + dev_err(&sensor->client->dev, "Timeout waiting for state 0x%02x\n", + state); + return -ETIMEDOUT; +} + +static int mt9m114_set_state(struct mt9m114 *sensor, u8 next_state) +{ + int ret = 0; + + /* Set the next desired state and start the state transition. */ + cci_write(sensor->regmap, MT9M114_SYSMGR_NEXT_STATE, next_state, &ret); + cci_write(sensor->regmap, MT9M114_COMMAND_REGISTER, + MT9M114_COMMAND_REGISTER_OK | + MT9M114_COMMAND_REGISTER_SET_STATE, &ret); + if (ret < 0) + return ret; + + /* Wait for the state transition to complete. */ + ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); + if (ret < 0) + return ret; + + return 0; +} + +static int mt9m114_initialize(struct mt9m114 *sensor) +{ + u32 value; + int ret; + + ret = cci_multi_reg_write(sensor->regmap, mt9m114_init, + ARRAY_SIZE(mt9m114_init), NULL); + if (ret < 0) { + dev_err(&sensor->client->dev, + "Failed to initialize the sensor\n"); + return ret; + } + + /* Configure the PLL. */ + cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, + MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret); + cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N, + MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m, + sensor->pll.n), + &ret); + cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P, + MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret); + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK, + sensor->pixrate, &ret); + + /* Configure the output mode. */ + if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { + value = MT9M114_CAM_PORT_PORT_SELECT_MIPI + | MT9M114_CAM_PORT_CHAN_NUM(0) + | 0x8000; + if (!(sensor->bus_cfg.bus.mipi_csi2.flags & + V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK)) + value |= MT9M114_CAM_PORT_CONT_MIPI_CLK; + } else { + value = MT9M114_CAM_PORT_PORT_SELECT_PARALLEL + | 0x8000; + } + cci_write(sensor->regmap, MT9M114_CAM_PORT_OUTPUT_CONTROL, value, &ret); + if (ret < 0) + return ret; + + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); + if (ret < 0) + return ret; + + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); + if (ret < 0) + return ret; + + return 0; +} + +static int mt9m114_configure(struct mt9m114 *sensor, + struct v4l2_subdev_state *pa_state, + struct v4l2_subdev_state *ifp_state) +{ + const struct v4l2_mbus_framefmt *pa_format; + const struct v4l2_rect *pa_crop; + const struct mt9m114_format_info *ifp_info; + const struct v4l2_mbus_framefmt *ifp_format; + const struct v4l2_rect *ifp_crop; + const struct v4l2_rect *ifp_compose; + unsigned int hratio, vratio; + u64 output_format; + u64 read_mode; + int ret = 0; + + pa_format = v4l2_subdev_get_pad_format(&sensor->pa.sd, pa_state, 0); + pa_crop = v4l2_subdev_get_pad_crop(&sensor->pa.sd, pa_state, 0); + + ifp_format = v4l2_subdev_get_pad_format(&sensor->ifp.sd, ifp_state, 1); + ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code); + ifp_crop = v4l2_subdev_get_pad_crop(&sensor->ifp.sd, ifp_state, 0); + ifp_compose = v4l2_subdev_get_pad_compose(&sensor->ifp.sd, ifp_state, 0); + + ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, + &read_mode, NULL); + if (ret < 0) + return ret; + + ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, + &output_format, NULL); + if (ret < 0) + return ret; + + hratio = pa_crop->width / pa_format->width; + vratio = pa_crop->height / pa_format->height; + + /* + * Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW + * register isn't clearly documented, but is always set to the number + * of active rows minus 4 divided by the vertical binning factor in all + * example sensor modes. + */ + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START, + pa_crop->left, &ret); + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START, + pa_crop->top, &ret); + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END, + pa_crop->width + pa_crop->left - 1, &ret); + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END, + pa_crop->height + pa_crop->top - 1, &ret); + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW, + (pa_crop->height - 4) / vratio - 1, &ret); + + read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK | + MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK); + + if (hratio > 1) + read_mode |= MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_SUMMING; + if (vratio > 1) + read_mode |= MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_SUMMING; + + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, + read_mode, &ret); + + /* + * Color pipeline (IFP) cropping and scaling. Subtract 4 from the left + * and top coordinates to compensate for the lines and columns removed + * by demosaicing that are taken into account in the crop rectangle but + * not in the hardware. + */ + cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET, + ifp_crop->left - 4, &ret); + cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET, + ifp_crop->top - 4, &ret); + cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH, + ifp_crop->width, &ret); + cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT, + ifp_crop->height, &ret); + + cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH, + ifp_compose->width, &ret); + cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT, + ifp_compose->height, &ret); + + /* AWB and AE windows, use the full frame. */ + cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART, + 0, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART, + 0, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND, + ifp_compose->width - 1, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND, + ifp_compose->height - 1, &ret); + + cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART, + 0, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART, + 0, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND, + ifp_compose->width / 5 - 1, &ret); + cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND, + ifp_compose->height / 5 - 1, &ret); + + cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE, + MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN | + MT9M114_CAM_CROP_MODE_AE_AUTO_CROP_EN, &ret); + + /* Set the media bus code. */ + output_format &= ~(MT9M114_CAM_OUTPUT_FORMAT_RGB_FORMAT_MASK | + MT9M114_CAM_OUTPUT_FORMAT_BAYER_FORMAT_MASK | + MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK | + MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES | + MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE); + output_format |= ifp_info->output_format; + + cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, + output_format, &ret); + + return ret; +} + +static int mt9m114_set_frame_rate(struct mt9m114 *sensor) +{ + u16 frame_rate = sensor->ifp.frame_rate << 8; + int ret = 0; + + cci_write(sensor->regmap, MT9M114_CAM_AET_MIN_FRAME_RATE, + frame_rate, &ret); + cci_write(sensor->regmap, MT9M114_CAM_AET_MAX_FRAME_RATE, + frame_rate, &ret); + + return ret; +} + +static int mt9m114_start_streaming(struct mt9m114 *sensor, + struct v4l2_subdev_state *pa_state, + struct v4l2_subdev_state *ifp_state) +{ + int ret; + + ret = pm_runtime_resume_and_get(&sensor->client->dev); + if (ret) + return ret; + + ret = mt9m114_configure(sensor, pa_state, ifp_state); + if (ret) + goto error; + + ret = mt9m114_set_frame_rate(sensor); + if (ret) + goto error; + + ret = __v4l2_ctrl_handler_setup(&sensor->pa.hdl); + if (ret) + goto error; + + ret = __v4l2_ctrl_handler_setup(&sensor->ifp.hdl); + if (ret) + goto error; + + /* + * The Change-Config state is transient and moves to the streaming + * state automatically. + */ + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); + if (ret) + goto error; + + sensor->streaming = true; + + return 0; + +error: + pm_runtime_mark_last_busy(&sensor->client->dev); + pm_runtime_put_autosuspend(&sensor->client->dev); + + return ret; +} + +static int mt9m114_stop_streaming(struct mt9m114 *sensor) +{ + int ret; + + sensor->streaming = false; + + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_SUSPEND); + + pm_runtime_mark_last_busy(&sensor->client->dev); + pm_runtime_put_autosuspend(&sensor->client->dev); + + return ret; +} + +/* ----------------------------------------------------------------------------- + * Common Subdev Operations + */ + +static const struct media_entity_operations mt9m114_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +/* ----------------------------------------------------------------------------- + * Pixel Array Control Operations + */ + +static inline struct mt9m114 *pa_ctrl_to_mt9m114(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mt9m114, pa.hdl); +} + +static int mt9m114_pa_g_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); + u64 value; + int ret; + + if (!pm_runtime_get_if_in_use(&sensor->client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_EXPOSURE: + ret = cci_read(sensor->regmap, + MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME, + &value, NULL); + if (ret) + break; + + ctrl->val = value; + break; + + case V4L2_CID_ANALOGUE_GAIN: + ret = cci_read(sensor->regmap, + MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, + &value, NULL); + if (ret) + break; + + ctrl->val = value; + break; + + default: + ret = -EINVAL; + break; + } + + pm_runtime_mark_last_busy(&sensor->client->dev); + pm_runtime_put_autosuspend(&sensor->client->dev); + + return ret; +} + +static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mt9m114 *sensor = pa_ctrl_to_mt9m114(ctrl); + const struct v4l2_mbus_framefmt *format; + struct v4l2_subdev_state *state; + int ret = 0; + u64 mask; + + /* V4L2 controls values are applied only when power is up. */ + if (!pm_runtime_get_if_in_use(&sensor->client->dev)) + return 0; + + state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd); + format = v4l2_subdev_get_pad_format(&sensor->pa.sd, state, 0); + + switch (ctrl->id) { + case V4L2_CID_HBLANK: + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK, + ctrl->val + format->width, &ret); + break; + + case V4L2_CID_VBLANK: + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, + ctrl->val + format->height, &ret); + break; + + case V4L2_CID_EXPOSURE: + cci_write(sensor->regmap, + MT9M114_CAM_SENSOR_CONTROL_COARSE_INTEGRATION_TIME, + ctrl->val, &ret); + break; + + case V4L2_CID_ANALOGUE_GAIN: + /* + * The CAM_SENSOR_CONTROL_ANALOG_GAIN contains linear analog + * gain values that are mapped to the GLOBAL_GAIN register + * values by the sensor firmware. + */ + cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, + ctrl->val, &ret); + break; + + case V4L2_CID_HFLIP: + mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN; + ret = cci_update_bits(sensor->regmap, + MT9M114_CAM_SENSOR_CONTROL_READ_MODE, + mask, ctrl->val ? mask : 0, NULL); + break; + + case V4L2_CID_VFLIP: + mask = MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN; + ret = cci_update_bits(sensor->regmap, + MT9M114_CAM_SENSOR_CONTROL_READ_MODE, + mask, ctrl->val ? mask : 0, NULL); + break; + + default: + ret = -EINVAL; + break; + } + + pm_runtime_mark_last_busy(&sensor->client->dev); + pm_runtime_put_autosuspend(&sensor->client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops mt9m114_pa_ctrl_ops = { + .g_volatile_ctrl = mt9m114_pa_g_ctrl, + .s_ctrl = mt9m114_pa_s_ctrl, +}; + +static void mt9m114_pa_ctrl_update_exposure(struct mt9m114 *sensor, bool manual) +{ + /* + * Update the volatile flag on the manual exposure and gain controls. + * If the controls have switched to manual, read their current value + * from the hardware to ensure that control read and write operations + * will behave correctly + */ + if (manual) { + mt9m114_pa_g_ctrl(sensor->pa.exposure); + sensor->pa.exposure->cur.val = sensor->pa.exposure->val; + sensor->pa.exposure->flags &= ~V4L2_CTRL_FLAG_VOLATILE; + + mt9m114_pa_g_ctrl(sensor->pa.gain); + sensor->pa.gain->cur.val = sensor->pa.gain->val; + sensor->pa.gain->flags &= ~V4L2_CTRL_FLAG_VOLATILE; + } else { + sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; + sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; + } +} + +static void mt9m114_pa_ctrl_update_blanking(struct mt9m114 *sensor, + const struct v4l2_mbus_framefmt *format) +{ + unsigned int max_blank; + + /* Update the blanking controls ranges based on the output size. */ + max_blank = MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK_MAX + - format->width; + __v4l2_ctrl_modify_range(sensor->pa.hblank, MT9M114_MIN_HBLANK, + max_blank, 1, MT9M114_DEF_HBLANK); + + max_blank = MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES_MAX + - format->height; + __v4l2_ctrl_modify_range(sensor->pa.vblank, MT9M114_MIN_VBLANK, + max_blank, 1, MT9M114_DEF_VBLANK); +} + +/* ----------------------------------------------------------------------------- + * Pixel Array Subdev Operations + */ + +static inline struct mt9m114 *pa_to_mt9m114(struct v4l2_subdev *sd) +{ + return container_of(sd, struct mt9m114, pa.sd); +} + +static int mt9m114_pa_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + + crop->left = 0; + crop->top = 0; + crop->width = MT9M114_PIXEL_ARRAY_WIDTH; + crop->height = MT9M114_PIXEL_ARRAY_HEIGHT; + + format = v4l2_subdev_get_pad_format(sd, state, 0); + + format->width = MT9M114_PIXEL_ARRAY_WIDTH; + format->height = MT9M114_PIXEL_ARRAY_HEIGHT; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; + format->field = V4L2_FIELD_NONE; + format->colorspace = V4L2_COLORSPACE_RAW; + format->ycbcr_enc = V4L2_YCBCR_ENC_601; + format->quantization = V4L2_QUANTIZATION_FULL_RANGE; + format->xfer_func = V4L2_XFER_FUNC_NONE; + + return 0; +} + +static int mt9m114_pa_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code) +{ + if (code->index > 0) + return -EINVAL; + + code->code = MEDIA_BUS_FMT_SGRBG10_1X10; + + return 0; +} + +static int mt9m114_pa_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_size_enum *fse) +{ + if (fse->index > 1) + return -EINVAL; + + if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) + return -EINVAL; + + /* Report binning capability through frame size enumeration. */ + fse->min_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); + fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); + fse->min_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); + fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); + + return 0; +} + +static int mt9m114_pa_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct mt9m114 *sensor = pa_to_mt9m114(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + unsigned int hscale; + unsigned int vscale; + + crop = v4l2_subdev_get_pad_crop(sd, state, fmt->pad); + format = v4l2_subdev_get_pad_format(sd, state, fmt->pad); + + /* The sensor can bin horizontally and vertically. */ + hscale = DIV_ROUND_CLOSEST(crop->width, fmt->format.width ? : 1); + vscale = DIV_ROUND_CLOSEST(crop->height, fmt->format.height ? : 1); + format->width = crop->width / clamp(hscale, 1U, 2U); + format->height = crop->height / clamp(vscale, 1U, 2U); + + fmt->format = *format; + + if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) + mt9m114_pa_ctrl_update_blanking(sensor, format); + + return 0; +} + +static int mt9m114_pa_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + sel->r = *v4l2_subdev_get_pad_crop(sd, state, sel->pad); + return 0; + + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_NATIVE_SIZE: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = MT9M114_PIXEL_ARRAY_WIDTH; + sel->r.height = MT9M114_PIXEL_ARRAY_HEIGHT; + return 0; + + default: + return -EINVAL; + } +} + +static int mt9m114_pa_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct mt9m114 *sensor = pa_to_mt9m114(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + + if (sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + + crop = v4l2_subdev_get_pad_crop(sd, state, sel->pad); + format = v4l2_subdev_get_pad_format(sd, state, sel->pad); + + /* + * Clamp the crop rectangle. The vertical coordinates must be even, and + * the horizontal coordinates must be a multiple of 4. + * + * FIXME: The horizontal coordinates must be a multiple of 8 when + * binning, but binning is configured after setting the selection, so + * we can't know tell here if it will be used. + */ + crop->left = ALIGN(sel->r.left, 4); + crop->top = ALIGN(sel->r.top, 2); + crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 4), + MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH, + MT9M114_PIXEL_ARRAY_WIDTH - crop->left); + crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), + MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT, + MT9M114_PIXEL_ARRAY_HEIGHT - crop->top); + + sel->r = *crop; + + /* Reset the format. */ + format->width = crop->width; + format->height = crop->height; + + if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) + mt9m114_pa_ctrl_update_blanking(sensor, format); + + return 0; +} + +static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = { + .init_cfg = mt9m114_pa_init_cfg, + .enum_mbus_code = mt9m114_pa_enum_mbus_code, + .enum_frame_size = mt9m114_pa_enum_framesizes, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = mt9m114_pa_set_fmt, + .get_selection = mt9m114_pa_get_selection, + .set_selection = mt9m114_pa_set_selection, +}; + +static const struct v4l2_subdev_ops mt9m114_pa_ops = { + .pad = &mt9m114_pa_pad_ops, +}; + +static int mt9m114_pa_init(struct mt9m114 *sensor) +{ + struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl; + struct v4l2_subdev *sd = &sensor->pa.sd; + struct media_pad *pads = &sensor->pa.pad; + const struct v4l2_mbus_framefmt *format; + struct v4l2_subdev_state *state; + unsigned int max_exposure; + int ret; + + /* Initialize the subdev. */ + v4l2_subdev_init(sd, &mt9m114_pa_ops); + v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array"); + + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->owner = THIS_MODULE; + sd->dev = &sensor->client->dev; + v4l2_set_subdevdata(sd, sensor->client); + + /* Initialize the media entity. */ + sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; + sd->entity.ops = &mt9m114_entity_ops; + pads[0].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&sd->entity, 1, pads); + if (ret < 0) + return ret; + + /* Initialize the control handler. */ + v4l2_ctrl_handler_init(hdl, 7); + + /* The range of the HBLANK and VBLANK controls will be updated below. */ + sensor->pa.hblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_HBLANK, + MT9M114_DEF_HBLANK, + MT9M114_DEF_HBLANK, 1, + MT9M114_DEF_HBLANK); + sensor->pa.vblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_VBLANK, + MT9M114_DEF_VBLANK, + MT9M114_DEF_VBLANK, 1, + MT9M114_DEF_VBLANK); + + /* + * The maximum coarse integration time is the frame length in lines + * minus two. The default is taken directly from the datasheet, but + * makes little sense as auto-exposure is enabled by default. + */ + max_exposure = MT9M114_PIXEL_ARRAY_HEIGHT + MT9M114_MIN_VBLANK - 2; + sensor->pa.exposure = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_EXPOSURE, 1, + max_exposure, 1, 16); + if (sensor->pa.exposure) + sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; + + sensor->pa.gain = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_ANALOGUE_GAIN, 1, + 511, 1, 32); + if (sensor->pa.gain) + sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; + + v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_PIXEL_RATE, + sensor->pixrate, sensor->pixrate, 1, + sensor->pixrate); + + v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_HFLIP, + 0, 1, 1, 0); + v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, + V4L2_CID_VFLIP, + 0, 1, 1, 0); + + if (hdl->error) { + ret = hdl->error; + goto error; + } + + sd->state_lock = hdl->lock; + + ret = v4l2_subdev_init_finalize(sd); + if (ret) + goto error; + + /* Update the range of the blanking controls based on the format. */ + state = v4l2_subdev_lock_and_get_active_state(sd); + format = v4l2_subdev_get_pad_format(sd, state, 0); + mt9m114_pa_ctrl_update_blanking(sensor, format); + v4l2_subdev_unlock_state(state); + + sd->ctrl_handler = hdl; + + return 0; + +error: + v4l2_ctrl_handler_free(&sensor->pa.hdl); + media_entity_cleanup(&sensor->pa.sd.entity); + return ret; +} + +static void mt9m114_pa_cleanup(struct mt9m114 *sensor) +{ + v4l2_ctrl_handler_free(&sensor->pa.hdl); + media_entity_cleanup(&sensor->pa.sd.entity); +} + +/* ----------------------------------------------------------------------------- + * Image Flow Processor Control Operations + */ + +static const char * const mt9m114_test_pattern_menu[] = { + "Disabled", + "Solid Color", + "100% Color Bars", + "Pseudo-Random", + "Fade-to-Gray Color Bars", + "Walking Ones 10-bit", + "Walking Ones 8-bit", +}; + +/* Keep in sync with mt9m114_test_pattern_menu */ +static const unsigned int mt9m114_test_pattern_value[] = { + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_SOLID_BARS, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_RANDOM, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_FADING_BARS, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_10B, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT_WALKING_1S_8B, +}; + +static inline struct mt9m114 *ifp_ctrl_to_mt9m114(struct v4l2_ctrl *ctrl) +{ + return container_of(ctrl->handler, struct mt9m114, ifp.hdl); +} + +static int mt9m114_ifp_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct mt9m114 *sensor = ifp_ctrl_to_mt9m114(ctrl); + u32 value; + int ret = 0; + + if (ctrl->id == V4L2_CID_EXPOSURE_AUTO) + mt9m114_pa_ctrl_update_exposure(sensor, + ctrl->val != V4L2_EXPOSURE_AUTO); + + /* V4L2 controls values are applied only when power is up. */ + if (!pm_runtime_get_if_in_use(&sensor->client->dev)) + return 0; + + switch (ctrl->id) { + case V4L2_CID_AUTO_WHITE_BALANCE: + /* Control both the AWB mode and the CCM algorithm. */ + if (ctrl->val) + value = MT9M114_CAM_AWB_MODE_AUTO + | MT9M114_CAM_AWB_MODE_EXCLUSIVE_AE; + else + value = 0; + + cci_write(sensor->regmap, MT9M114_CAM_AWB_AWBMODE, value, &ret); + + if (ctrl->val) + value = MT9M114_CCM_EXEC_CALC_CCM_MATRIX | 0x22; + else + value = 0; + + cci_write(sensor->regmap, MT9M114_CCM_ALGO, value, &ret); + break; + + case V4L2_CID_EXPOSURE_AUTO: + if (ctrl->val == V4L2_EXPOSURE_AUTO) + value = MT9M114_AE_TRACK_EXEC_AUTOMATIC_EXPOSURE + | 0x00fe; + else + value = 0; + + cci_write(sensor->regmap, MT9M114_AE_TRACK_ALGO, value, &ret); + if (ret) + break; + + break; + + case V4L2_CID_TEST_PATTERN: + case V4L2_CID_TEST_PATTERN_RED: + case V4L2_CID_TEST_PATTERN_GREENR: + case V4L2_CID_TEST_PATTERN_BLUE: { + unsigned int pattern = sensor->ifp.tpg[MT9M114_TPG_PATTERN]->val; + + if (pattern) { + cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, + MT9M114_CAM_MODE_SELECT_TEST_PATTERN, &ret); + cci_write(sensor->regmap, + MT9M114_CAM_MODE_TEST_PATTERN_SELECT, + mt9m114_test_pattern_value[pattern - 1], &ret); + cci_write(sensor->regmap, + MT9M114_CAM_MODE_TEST_PATTERN_RED, + sensor->ifp.tpg[MT9M114_TPG_RED]->val, &ret); + cci_write(sensor->regmap, + MT9M114_CAM_MODE_TEST_PATTERN_GREEN, + sensor->ifp.tpg[MT9M114_TPG_GREEN]->val, &ret); + cci_write(sensor->regmap, + MT9M114_CAM_MODE_TEST_PATTERN_BLUE, + sensor->ifp.tpg[MT9M114_TPG_BLUE]->val, &ret); + } else { + cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, + MT9M114_CAM_MODE_SELECT_NORMAL, &ret); + } + + /* + * A Config-Change needs to be issued for the change to take + * effect. If we're not streaming ignore this, the change will + * be applied when the stream is started. + */ + if (ret || !sensor->streaming) + break; + + ret = mt9m114_set_state(sensor, + MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE); + break; + } + + default: + ret = -EINVAL; + break; + } + + pm_runtime_mark_last_busy(&sensor->client->dev); + pm_runtime_put_autosuspend(&sensor->client->dev); + + return ret; +} + +static const struct v4l2_ctrl_ops mt9m114_ifp_ctrl_ops = { + .s_ctrl = mt9m114_ifp_s_ctrl, +}; + +/* ----------------------------------------------------------------------------- + * Image Flow Processor Subdev Operations + */ + +static inline struct mt9m114 *ifp_to_mt9m114(struct v4l2_subdev *sd) +{ + return container_of(sd, struct mt9m114, ifp.sd); +} + +static int mt9m114_ifp_s_stream(struct v4l2_subdev *sd, int enable) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + struct v4l2_subdev_state *pa_state; + struct v4l2_subdev_state *ifp_state; + int ret; + + if (!enable) + return mt9m114_stop_streaming(sensor); + + ifp_state = v4l2_subdev_lock_and_get_active_state(&sensor->ifp.sd); + pa_state = v4l2_subdev_lock_and_get_active_state(&sensor->pa.sd); + + ret = mt9m114_start_streaming(sensor, pa_state, ifp_state); + + v4l2_subdev_unlock_state(pa_state); + v4l2_subdev_unlock_state(ifp_state); + + return ret; +} + +static int mt9m114_ifp_g_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval) +{ + struct v4l2_fract *ival = &interval->interval; + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + + mutex_lock(sensor->ifp.hdl.lock); + + ival->numerator = 1; + ival->denominator = sensor->ifp.frame_rate; + + mutex_unlock(sensor->ifp.hdl.lock); + + return 0; +} + +static int mt9m114_ifp_s_frame_interval(struct v4l2_subdev *sd, + struct v4l2_subdev_frame_interval *interval) +{ + struct v4l2_fract *ival = &interval->interval; + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + int ret = 0; + + mutex_lock(sensor->ifp.hdl.lock); + + if (ival->numerator != 0 && ival->denominator != 0) + sensor->ifp.frame_rate = min_t(unsigned int, + ival->denominator / ival->numerator, + MT9M114_MAX_FRAME_RATE); + else + sensor->ifp.frame_rate = MT9M114_MAX_FRAME_RATE; + + ival->numerator = 1; + ival->denominator = sensor->ifp.frame_rate; + + if (sensor->streaming) + ret = mt9m114_set_frame_rate(sensor); + + mutex_unlock(sensor->ifp.hdl.lock); + + return ret; +} + +static int mt9m114_ifp_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + struct v4l2_rect *compose; + + format = v4l2_subdev_get_pad_format(sd, state, 0); + + format->width = MT9M114_PIXEL_ARRAY_WIDTH; + format->height = MT9M114_PIXEL_ARRAY_HEIGHT; + format->code = MEDIA_BUS_FMT_SGRBG10_1X10; + format->field = V4L2_FIELD_NONE; + format->colorspace = V4L2_COLORSPACE_RAW; + format->ycbcr_enc = V4L2_YCBCR_ENC_601; + format->quantization = V4L2_QUANTIZATION_FULL_RANGE; + format->xfer_func = V4L2_XFER_FUNC_NONE; + + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + + crop->left = 4; + crop->top = 4; + crop->width = format->width - 8; + crop->height = format->height - 8; + + compose = v4l2_subdev_get_pad_compose(sd, state, 0); + + compose->left = 0; + compose->top = 0; + compose->width = crop->width; + compose->height = crop->height; + + format = v4l2_subdev_get_pad_format(sd, state, 1); + + format->width = compose->width; + format->height = compose->height; + format->code = mt9m114_default_format_info(sensor)->code; + format->field = V4L2_FIELD_NONE; + format->colorspace = V4L2_COLORSPACE_SRGB; + format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; + format->quantization = V4L2_QUANTIZATION_DEFAULT; + format->xfer_func = V4L2_XFER_FUNC_DEFAULT; + + return 0; +} + +static int mt9m114_ifp_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_mbus_code_enum *code) +{ + const unsigned int num_formats = ARRAY_SIZE(mt9m114_format_infos); + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + unsigned int index = 0; + unsigned int flag; + unsigned int i; + + switch (code->pad) { + case 0: + if (code->index != 0) + return -EINVAL; + + code->code = mt9m114_format_infos[num_formats - 1].code; + return 0; + + case 1: + if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) + flag = MT9M114_FMT_FLAG_CSI2; + else + flag = MT9M114_FMT_FLAG_PARALLEL; + + for (i = 0; i < num_formats; ++i) { + const struct mt9m114_format_info *info = + &mt9m114_format_infos[i]; + + if (info->flags & flag) { + if (index == code->index) { + code->code = info->code; + return 0; + } + + index++; + } + } + + return -EINVAL; + + default: + return -EINVAL; + } +} + +static int mt9m114_ifp_enum_framesizes(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_size_enum *fse) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + const struct mt9m114_format_info *info; + + if (fse->index > 0) + return -EINVAL; + + info = mt9m114_format_info(sensor, fse->pad, fse->code); + if (!info || info->code != fse->code) + return -EINVAL; + + if (fse->pad == 0) { + fse->min_width = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH; + fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH; + fse->min_height = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT; + fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT; + } else { + const struct v4l2_rect *crop; + + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + + fse->max_width = crop->width; + fse->max_height = crop->height; + + fse->min_width = fse->max_width / 4; + fse->min_height = fse->max_height / 4; + } + + return 0; +} + +static int mt9m114_ifp_enum_frameintervals(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_frame_interval_enum *fie) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + const struct mt9m114_format_info *info; + + if (fie->index > 0) + return -EINVAL; + + info = mt9m114_format_info(sensor, fie->pad, fie->code); + if (!info || info->code != fie->code) + return -EINVAL; + + fie->interval.numerator = 1; + fie->interval.denominator = MT9M114_MAX_FRAME_RATE; + + return 0; +} + +static int mt9m114_ifp_set_fmt(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_format *fmt) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + struct v4l2_mbus_framefmt *format; + + format = v4l2_subdev_get_pad_format(sd, state, fmt->pad); + + if (fmt->pad == 0) { + /* Only the size can be changed on the sink pad. */ + format->width = clamp(ALIGN(fmt->format.width, 8), + MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH, + MT9M114_PIXEL_ARRAY_WIDTH); + format->height = clamp(ALIGN(fmt->format.height, 8), + MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT, + MT9M114_PIXEL_ARRAY_HEIGHT); + } else { + const struct mt9m114_format_info *info; + + /* Only the media bus code can be changed on the source pad. */ + info = mt9m114_format_info(sensor, 1, fmt->format.code); + + format->code = info->code; + + /* If the output format is RAW10, bypass the scaler. */ + if (format->code == MEDIA_BUS_FMT_SGRBG10_1X10) + *format = *v4l2_subdev_get_pad_format(sd, state, 0); + } + + fmt->format = *format; + + return 0; +} + +static int mt9m114_ifp_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + const struct v4l2_mbus_framefmt *format; + const struct v4l2_rect *crop; + int ret = 0; + + /* Crop and compose are only supported on the sink pad. */ + if (sel->pad != 0) + return -EINVAL; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + sel->r = *v4l2_subdev_get_pad_crop(sd, state, 0); + break; + + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP_BOUNDS: + /* + * The crop default and bounds are equal to the sink + * format size minus 4 pixels on each side for demosaicing. + */ + format = v4l2_subdev_get_pad_format(sd, state, 0); + + sel->r.left = 4; + sel->r.top = 4; + sel->r.width = format->width - 8; + sel->r.height = format->height - 8; + break; + + case V4L2_SEL_TGT_COMPOSE: + sel->r = *v4l2_subdev_get_pad_compose(sd, state, 0); + break; + + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + /* + * The compose default and bounds sizes are equal to the sink + * crop rectangle size. + */ + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = crop->width; + sel->r.height = crop->height; + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static int mt9m114_ifp_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + struct v4l2_subdev_selection *sel) +{ + struct v4l2_mbus_framefmt *format; + struct v4l2_rect *crop; + struct v4l2_rect *compose; + + if (sel->target != V4L2_SEL_TGT_CROP && + sel->target != V4L2_SEL_TGT_COMPOSE) + return -EINVAL; + + /* Crop and compose are only supported on the sink pad. */ + if (sel->pad != 0) + return -EINVAL; + + format = v4l2_subdev_get_pad_format(sd, state, 0); + crop = v4l2_subdev_get_pad_crop(sd, state, 0); + compose = v4l2_subdev_get_pad_compose(sd, state, 0); + + if (sel->target == V4L2_SEL_TGT_CROP) { + /* + * Clamp the crop rectangle. Demosaicing removes 4 pixels on + * each side of the image. + */ + crop->left = clamp_t(unsigned int, ALIGN(sel->r.left, 2), 4, + format->width - 4 - + MT9M114_SCALER_CROPPED_INPUT_WIDTH); + crop->top = clamp_t(unsigned int, ALIGN(sel->r.top, 2), 4, + format->height - 4 - + MT9M114_SCALER_CROPPED_INPUT_HEIGHT); + crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), + MT9M114_SCALER_CROPPED_INPUT_WIDTH, + format->width - 4 - crop->left); + crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), + MT9M114_SCALER_CROPPED_INPUT_HEIGHT, + format->height - 4 - crop->top); + + sel->r = *crop; + + /* Propagate to the compose rectangle. */ + compose->width = crop->width; + compose->height = crop->height; + } else { + /* + * Clamp the compose rectangle. The scaler can only downscale. + */ + compose->left = 0; + compose->top = 0; + compose->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), + MT9M114_SCALER_CROPPED_INPUT_WIDTH, + crop->width); + compose->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), + MT9M114_SCALER_CROPPED_INPUT_HEIGHT, + crop->height); + + sel->r = *compose; + } + + /* Propagate the compose rectangle to the source format. */ + format = v4l2_subdev_get_pad_format(sd, state, 1); + format->width = compose->width; + format->height = compose->height; + + return 0; +} + +static void mt9m114_ifp_unregistered(struct v4l2_subdev *sd) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + + v4l2_device_unregister_subdev(&sensor->pa.sd); +} + +static int mt9m114_ifp_registered(struct v4l2_subdev *sd) +{ + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + int ret; + + ret = v4l2_device_register_subdev(sd->v4l2_dev, &sensor->pa.sd); + if (ret < 0) { + dev_err(&sensor->client->dev, + "Failed to register pixel array subdev\n"); + return ret; + } + + ret = media_create_pad_link(&sensor->pa.sd.entity, 0, + &sensor->ifp.sd.entity, 0, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret < 0) { + dev_err(&sensor->client->dev, + "Failed to link pixel array to ifp\n"); + v4l2_device_unregister_subdev(&sensor->pa.sd); + return ret; + } + + return 0; +} + +static const struct v4l2_subdev_video_ops mt9m114_ifp_video_ops = { + .s_stream = mt9m114_ifp_s_stream, + .g_frame_interval = mt9m114_ifp_g_frame_interval, + .s_frame_interval = mt9m114_ifp_s_frame_interval, +}; + +static const struct v4l2_subdev_pad_ops mt9m114_ifp_pad_ops = { + .init_cfg = mt9m114_ifp_init_cfg, + .enum_mbus_code = mt9m114_ifp_enum_mbus_code, + .enum_frame_size = mt9m114_ifp_enum_framesizes, + .enum_frame_interval = mt9m114_ifp_enum_frameintervals, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = mt9m114_ifp_set_fmt, + .get_selection = mt9m114_ifp_get_selection, + .set_selection = mt9m114_ifp_set_selection, +}; + +static const struct v4l2_subdev_ops mt9m114_ifp_ops = { + .video = &mt9m114_ifp_video_ops, + .pad = &mt9m114_ifp_pad_ops, +}; + +static const struct v4l2_subdev_internal_ops mt9m114_ifp_internal_ops = { + .registered = mt9m114_ifp_registered, + .unregistered = mt9m114_ifp_unregistered, +}; + +static int mt9m114_ifp_init(struct mt9m114 *sensor) +{ + struct v4l2_subdev *sd = &sensor->ifp.sd; + struct media_pad *pads = sensor->ifp.pads; + struct v4l2_ctrl_handler *hdl = &sensor->ifp.hdl; + struct v4l2_ctrl *link_freq; + int ret; + + /* Initialize the subdev. */ + v4l2_i2c_subdev_init(sd, sensor->client, &mt9m114_ifp_ops); + v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " ifp"); + + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; + sd->internal_ops = &mt9m114_ifp_internal_ops; + + /* Initialize the media entity. */ + sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; + sd->entity.ops = &mt9m114_entity_ops; + pads[0].flags = MEDIA_PAD_FL_SINK; + pads[1].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&sd->entity, 2, pads); + if (ret < 0) + return ret; + + sensor->ifp.frame_rate = MT9M114_DEF_FRAME_RATE; + + /* Initialize the control handler. */ + v4l2_ctrl_handler_init(hdl, 8); + v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 1); + v4l2_ctrl_new_std_menu(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, + V4L2_EXPOSURE_MANUAL, 0, + V4L2_EXPOSURE_AUTO); + + link_freq = v4l2_ctrl_new_int_menu(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_LINK_FREQ, + sensor->bus_cfg.nr_of_link_frequencies - 1, + 0, sensor->bus_cfg.link_frequencies); + if (link_freq) + link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; + + v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_PIXEL_RATE, + sensor->pixrate, sensor->pixrate, 1, + sensor->pixrate); + + sensor->ifp.tpg[MT9M114_TPG_PATTERN] = + v4l2_ctrl_new_std_menu_items(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_TEST_PATTERN, + ARRAY_SIZE(mt9m114_test_pattern_menu) - 1, + 0, 0, mt9m114_test_pattern_menu); + sensor->ifp.tpg[MT9M114_TPG_RED] = + v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_TEST_PATTERN_RED, + 0, 1023, 1, 1023); + sensor->ifp.tpg[MT9M114_TPG_GREEN] = + v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_TEST_PATTERN_GREENR, + 0, 1023, 1, 1023); + sensor->ifp.tpg[MT9M114_TPG_BLUE] = + v4l2_ctrl_new_std(hdl, &mt9m114_ifp_ctrl_ops, + V4L2_CID_TEST_PATTERN_BLUE, + 0, 1023, 1, 1023); + + v4l2_ctrl_cluster(ARRAY_SIZE(sensor->ifp.tpg), sensor->ifp.tpg); + + if (hdl->error) { + ret = hdl->error; + goto error; + } + + sd->ctrl_handler = hdl; + sd->state_lock = hdl->lock; + + ret = v4l2_subdev_init_finalize(sd); + if (ret) + goto error; + + return 0; + +error: + v4l2_ctrl_handler_free(&sensor->ifp.hdl); + media_entity_cleanup(&sensor->ifp.sd.entity); + return ret; +} + +static void mt9m114_ifp_cleanup(struct mt9m114 *sensor) +{ + v4l2_ctrl_handler_free(&sensor->ifp.hdl); + media_entity_cleanup(&sensor->ifp.sd.entity); +} + +/* ----------------------------------------------------------------------------- + * Power Management + */ + +static int mt9m114_power_on(struct mt9m114 *sensor) +{ + int ret; + + /* Enable power and clocks. */ + ret = regulator_bulk_enable(ARRAY_SIZE(sensor->supplies), + sensor->supplies); + if (ret < 0) + return ret; + + ret = clk_prepare_enable(sensor->clk); + if (ret < 0) + goto error_regulator; + + /* Perform a hard reset if available, or a soft reset otherwise. */ + if (sensor->reset) { + long freq = clk_get_rate(sensor->clk); + unsigned int duration; + + /* + * The minimum duration is 50 clock cycles, thus typically + * around 2µs. Double it to be safe. + */ + duration = DIV_ROUND_UP(2 * 50 * 1000000, freq); + + gpiod_set_value(sensor->reset, 1); + fsleep(duration); + gpiod_set_value(sensor->reset, 0); + } else { + /* + * The power may have just been turned on, we need to wait for + * the sensor to be ready to accept I2C commands. + */ + usleep_range(44500, 50000); + + cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, + MT9M114_RESET_SOC, &ret); + cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 0, + &ret); + + if (ret < 0) { + dev_err(&sensor->client->dev, "Soft reset failed\n"); + goto error_clock; + } + } + + /* + * Wait for the sensor to be ready to accept I2C commands by polling the + * command register to wait for initialization to complete. + */ + usleep_range(44500, 50000); + + ret = mt9m114_poll_command(sensor, MT9M114_COMMAND_REGISTER_SET_STATE); + if (ret < 0) + goto error_clock; + + if (sensor->bus_cfg.bus_type == V4L2_MBUS_PARALLEL) { + /* + * In parallel mode (OE set to low), the sensor will enter the + * streaming state after initialization. Enter the standby + * manually to stop streaming. + */ + ret = mt9m114_set_state(sensor, + MT9M114_SYS_STATE_ENTER_STANDBY); + if (ret < 0) + goto error_clock; + } + + /* + * Before issuing any Set-State command, we must ensure that the sensor + * reaches the standby mode (either initiated manually above in + * parallel mode, or automatically after reset in MIPI mode). + */ + ret = mt9m114_poll_state(sensor, MT9M114_SYS_STATE_STANDBY); + if (ret < 0) + goto error_clock; + + return 0; + +error_clock: + clk_disable_unprepare(sensor->clk); +error_regulator: + regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); + return ret; +} + +static void mt9m114_power_off(struct mt9m114 *sensor) +{ + clk_disable_unprepare(sensor->clk); + regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); +} + +static int __maybe_unused mt9m114_runtime_resume(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + int ret; + + ret = mt9m114_power_on(sensor); + if (ret) + return ret; + + ret = mt9m114_initialize(sensor); + if (ret) { + mt9m114_power_off(sensor); + return ret; + } + + return 0; +} + +static int __maybe_unused mt9m114_runtime_suspend(struct device *dev) +{ + struct v4l2_subdev *sd = dev_get_drvdata(dev); + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + + mt9m114_power_off(sensor); + + return 0; +} + +static const struct dev_pm_ops mt9m114_pm_ops = { + SET_RUNTIME_PM_OPS(mt9m114_runtime_suspend, mt9m114_runtime_resume, NULL) +}; + +/* ----------------------------------------------------------------------------- + * Probe & Remove + */ + +static int mt9m114_clk_init(struct mt9m114 *sensor) +{ + unsigned int link_freq; + + /* Hardcode the PLL multiplier and dividers to default settings. */ + sensor->pll.m = 32; + sensor->pll.n = 1; + sensor->pll.p = 7; + + /* + * Calculate the pixel rate and link frequency. The CSI-2 bus is clocked + * for 16-bit per pixel, transmitted in DDR over a single lane. For + * parallel mode, the sensor ouputs one pixel in two PIXCLK cycles. + */ + sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m + / ((sensor->pll.n + 1) * (sensor->pll.p + 1)); + + link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY + ? sensor->pixrate * 8 : sensor->pixrate * 2; + + if (sensor->bus_cfg.nr_of_link_frequencies != 1 || + sensor->bus_cfg.link_frequencies[0] != link_freq) { + dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n"); + return -EINVAL; + } + + return 0; +} + +static int mt9m114_identify(struct mt9m114 *sensor) +{ + u64 major, minor, release, customer; + u64 value; + int ret; + + ret = cci_read(sensor->regmap, MT9M114_CHIP_ID, &value, NULL); + if (ret) { + dev_err(&sensor->client->dev, "Failed to read chip ID\n"); + return -ENXIO; + } + + if (value != 0x2481) { + dev_err(&sensor->client->dev, "Invalid chip ID 0x%04llx\n", + value); + return -ENXIO; + } + + cci_read(sensor->regmap, MT9M114_MON_MAJOR_VERSION, &major, &ret); + cci_read(sensor->regmap, MT9M114_MON_MINOR_VERSION, &minor, &ret); + cci_read(sensor->regmap, MT9M114_MON_RELEASE_VERSION, &release, &ret); + cci_read(sensor->regmap, MT9M114_CUSTOMER_REV, &customer, &ret); + if (ret) { + dev_err(&sensor->client->dev, "Failed to read version\n"); + return -ENXIO; + } + + dev_dbg(&sensor->client->dev, + "monitor v%llu.%llu.%04llx customer rev 0x%04llx\n", + major, minor, release, customer); + + return 0; +} + +static int mt9m114_parse_dt(struct mt9m114 *sensor) +{ + struct fwnode_handle *fwnode = dev_fwnode(&sensor->client->dev); + struct fwnode_handle *ep; + int ret; + + ep = fwnode_graph_get_next_endpoint(fwnode, NULL); + if (!ep) { + dev_err(&sensor->client->dev, "No endpoint found\n"); + return -EINVAL; + } + + sensor->bus_cfg.bus_type = V4L2_MBUS_UNKNOWN; + ret = v4l2_fwnode_endpoint_alloc_parse(ep, &sensor->bus_cfg); + fwnode_handle_put(ep); + if (ret < 0) { + dev_err(&sensor->client->dev, "Failed to parse endpoint\n"); + goto error; + } + + switch (sensor->bus_cfg.bus_type) { + case V4L2_MBUS_CSI2_DPHY: + case V4L2_MBUS_PARALLEL: + break; + + default: + dev_err(&sensor->client->dev, "unsupported bus type %u\n", + sensor->bus_cfg.bus_type); + ret = -EINVAL; + goto error; + } + + return 0; + +error: + v4l2_fwnode_endpoint_free(&sensor->bus_cfg); + return ret; +} + +static int mt9m114_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct mt9m114 *sensor; + int ret; + + sensor = devm_kzalloc(dev, sizeof(*sensor), GFP_KERNEL); + if (!sensor) + return -ENOMEM; + + sensor->client = client; + + sensor->regmap = devm_cci_regmap_init_i2c(client, 16); + if (IS_ERR(sensor->regmap)) { + dev_err(dev, "Unable to initialize I2C\n"); + return -ENODEV; + } + + ret = mt9m114_parse_dt(sensor); + if (ret < 0) + return ret; + + /* Acquire clocks, GPIOs and regulators. */ + sensor->clk = devm_clk_get(dev, NULL); + if (IS_ERR(sensor->clk)) { + ret = PTR_ERR(sensor->clk); + dev_err_probe(dev, ret, "Failed to get clock\n"); + goto error_ep_free; + } + + sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(sensor->reset)) { + ret = PTR_ERR(sensor->reset); + dev_err_probe(dev, ret, "Failed to get reset GPIO\n"); + goto error_ep_free; + } + + sensor->supplies[0].supply = "vddio"; + sensor->supplies[1].supply = "vdd"; + sensor->supplies[2].supply = "vaa"; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sensor->supplies), + sensor->supplies); + if (ret < 0) { + dev_err_probe(dev, ret, "Failed to get regulators\n"); + goto error_ep_free; + } + + ret = mt9m114_clk_init(sensor); + if (ret) + goto error_ep_free; + + /* + * Identify the sensor. The driver supports runtime PM, but needs to + * work when runtime PM is disabled in the kernel. To that end, power + * the sensor on manually here, and initialize it after identification + * to reach the same state as if resumed through runtime PM. + */ + ret = mt9m114_power_on(sensor); + if (ret < 0) { + dev_err_probe(dev, ret, "Could not power on the device\n"); + goto error_ep_free; + } + + ret = mt9m114_identify(sensor); + if (ret < 0) + goto error_power_off; + + ret = mt9m114_initialize(sensor); + if (ret < 0) + goto error_power_off; + + /* + * Enable runtime PM with autosuspend. As the device has been powered + * manually, mark it as active, and increase the usage count without + * resuming the device. + */ + pm_runtime_set_active(dev); + pm_runtime_get_noresume(dev); + pm_runtime_enable(dev); + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + + /* Initialize the subdevices. */ + ret = mt9m114_pa_init(sensor); + if (ret < 0) + goto error_pm_cleanup; + + ret = mt9m114_ifp_init(sensor); + if (ret < 0) + goto error_pa_cleanup; + + ret = v4l2_async_register_subdev(&sensor->ifp.sd); + if (ret < 0) + goto error_ifp_cleanup; + + /* + * Decrease the PM usage count. The device will get suspended after the + * autosuspend delay, turning the power off. + */ + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return 0; + +error_ifp_cleanup: + mt9m114_ifp_cleanup(sensor); +error_pa_cleanup: + mt9m114_pa_cleanup(sensor); +error_pm_cleanup: + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); +error_power_off: + mt9m114_power_off(sensor); +error_ep_free: + v4l2_fwnode_endpoint_free(&sensor->bus_cfg); + return ret; +} + +static void mt9m114_remove(struct i2c_client *client) +{ + struct v4l2_subdev *sd = i2c_get_clientdata(client); + struct mt9m114 *sensor = ifp_to_mt9m114(sd); + struct device *dev = &client->dev; + + v4l2_async_unregister_subdev(&sensor->ifp.sd); + + mt9m114_ifp_cleanup(sensor); + mt9m114_pa_cleanup(sensor); + v4l2_fwnode_endpoint_free(&sensor->bus_cfg); + + /* + * Disable runtime PM. In case runtime PM is disabled in the kernel, + * make sure to turn power off manually. + */ + pm_runtime_disable(dev); + if (!pm_runtime_status_suspended(dev)) + mt9m114_power_off(sensor); + pm_runtime_set_suspended(dev); +} + +static const struct of_device_id mt9m114_of_ids[] = { + { .compatible = "onnn,mt9m114" }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mt9m114_of_ids); + +static struct i2c_driver mt9m114_driver = { + .driver = { + .name = "mt9m114", + .pm = &mt9m114_pm_ops, + .of_match_table = mt9m114_of_ids, + }, + .probe = mt9m114_probe, + .remove = mt9m114_remove, +}; + +module_i2c_driver(mt9m114_driver); + +MODULE_DESCRIPTION("onsemi MT9M114 Sensor Driver"); +MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c index 774861ba77..37a634b92c 100644 --- a/drivers/media/i2c/mt9v011.c +++ b/drivers/media/i2c/mt9v011.c @@ -49,9 +49,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); struct mt9v011 { struct v4l2_subdev sd; -#ifdef CONFIG_MEDIA_CONTROLLER struct media_pad pad; -#endif struct v4l2_ctrl_handler ctrls; unsigned width, height; unsigned xtal; @@ -483,9 +481,7 @@ static int mt9v011_probe(struct i2c_client *c) u16 version; struct mt9v011 *core; struct v4l2_subdev *sd; -#ifdef CONFIG_MEDIA_CONTROLLER int ret; -#endif /* Check if the adapter supports the needed features */ if (!i2c_check_functionality(c->adapter, @@ -499,14 +495,12 @@ static int mt9v011_probe(struct i2c_client *c) sd = &core->sd; v4l2_i2c_subdev_init(sd, c, &mt9v011_ops); -#ifdef CONFIG_MEDIA_CONTROLLER core->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &core->pad); if (ret < 0) return ret; -#endif /* Check if the sensor is really a MT9V011 */ version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION); diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 00e7bc6e32..1c6f6cea12 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -14,6 +14,7 @@ #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/log2.h> +#include <linux/mod_devicetable.h> #include <linux/mutex.h> #include <linux/of.h> #include <linux/of_graph.h> @@ -1046,7 +1047,6 @@ done: static int mt9v032_probe(struct i2c_client *client) { - const struct i2c_device_id *did = i2c_client_get_device_id(client); struct mt9v032_platform_data *pdata = mt9v032_get_pdata(client); struct mt9v032 *mt9v032; unsigned int i; @@ -1076,7 +1076,7 @@ static int mt9v032_probe(struct i2c_client *client) mutex_init(&mt9v032->power_lock); mt9v032->pdata = pdata; - mt9v032->model = (const void *)did->driver_data; + mt9v032->model = i2c_get_match_data(client); v4l2_ctrl_handler_init(&mt9v032->ctrls, 11 + ARRAY_SIZE(mt9v032_aegc_controls)); @@ -1272,29 +1272,27 @@ static const struct i2c_device_id mt9v032_id[] = { { "mt9v032m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V032_MONO] }, { "mt9v034", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_COLOR] }, { "mt9v034m", (kernel_ulong_t)&mt9v032_models[MT9V032_MODEL_V034_MONO] }, - { } + { /* Sentinel */ } }; MODULE_DEVICE_TABLE(i2c, mt9v032_id); -#if IS_ENABLED(CONFIG_OF) static const struct of_device_id mt9v032_of_match[] = { - { .compatible = "aptina,mt9v022" }, - { .compatible = "aptina,mt9v022m" }, - { .compatible = "aptina,mt9v024" }, - { .compatible = "aptina,mt9v024m" }, - { .compatible = "aptina,mt9v032" }, - { .compatible = "aptina,mt9v032m" }, - { .compatible = "aptina,mt9v034" }, - { .compatible = "aptina,mt9v034m" }, + { .compatible = "aptina,mt9v022", .data = &mt9v032_models[MT9V032_MODEL_V022_COLOR] }, + { .compatible = "aptina,mt9v022m", .data = &mt9v032_models[MT9V032_MODEL_V022_MONO] }, + { .compatible = "aptina,mt9v024", .data = &mt9v032_models[MT9V032_MODEL_V024_COLOR] }, + { .compatible = "aptina,mt9v024m", .data = &mt9v032_models[MT9V032_MODEL_V024_MONO] }, + { .compatible = "aptina,mt9v032", .data = &mt9v032_models[MT9V032_MODEL_V032_COLOR] }, + { .compatible = "aptina,mt9v032m", .data = &mt9v032_models[MT9V032_MODEL_V032_MONO] }, + { .compatible = "aptina,mt9v034", .data = &mt9v032_models[MT9V032_MODEL_V034_COLOR] }, + { .compatible = "aptina,mt9v034m", .data = &mt9v032_models[MT9V032_MODEL_V034_MONO] }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, mt9v032_of_match); -#endif static struct i2c_driver mt9v032_driver = { .driver = { .name = "mt9v032", - .of_match_table = of_match_ptr(mt9v032_of_match), + .of_match_table = mt9v032_of_match, }, .probe = mt9v032_probe, .remove = mt9v032_remove, diff --git a/drivers/media/i2c/mt9v111.c b/drivers/media/i2c/mt9v111.c index 1f7edc0f5b..f859b49e13 100644 --- a/drivers/media/i2c/mt9v111.c +++ b/drivers/media/i2c/mt9v111.c @@ -121,9 +121,7 @@ struct mt9v111_dev { u8 addr_space; struct v4l2_subdev sd; -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) struct media_pad pad; -#endif struct v4l2_ctrl *auto_awb; struct v4l2_ctrl *auto_exp; @@ -797,11 +795,7 @@ static struct v4l2_mbus_framefmt *__mt9v111_get_pad_format( { switch (which) { case V4L2_SUBDEV_FORMAT_TRY: -#if IS_ENABLED(CONFIG_VIDEO_V4L2_SUBDEV_API) return v4l2_subdev_get_try_format(&mt9v111->sd, sd_state, pad); -#else - return &sd_state->pads->try_fmt; -#endif case V4L2_SUBDEV_FORMAT_ACTIVE: return &mt9v111->fmt; default: @@ -987,11 +981,9 @@ static const struct v4l2_subdev_ops mt9v111_ops = { .pad = &mt9v111_pad_ops, }; -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) static const struct media_entity_operations mt9v111_subdev_entity_ops = { .link_validate = v4l2_subdev_link_validate, }; -#endif /* --- V4L2 ctrl --- */ static int mt9v111_s_ctrl(struct v4l2_ctrl *ctrl) @@ -1203,7 +1195,6 @@ static int mt9v111_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&mt9v111->sd, client, &mt9v111_ops); -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) mt9v111->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; mt9v111->sd.entity.ops = &mt9v111_subdev_entity_ops; mt9v111->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -1212,7 +1203,6 @@ static int mt9v111_probe(struct i2c_client *client) ret = media_entity_pads_init(&mt9v111->sd.entity, 1, &mt9v111->pad); if (ret) goto error_free_entity; -#endif ret = mt9v111_chip_probe(mt9v111); if (ret) @@ -1225,9 +1215,7 @@ static int mt9v111_probe(struct i2c_client *client) return 0; error_free_entity: -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&mt9v111->sd.entity); -#endif error_free_ctrls: v4l2_ctrl_handler_free(&mt9v111->ctrls); @@ -1245,9 +1233,7 @@ static void mt9v111_remove(struct i2c_client *client) v4l2_async_unregister_subdev(sd); -#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&sd->entity); -#endif v4l2_ctrl_handler_free(&mt9v111->ctrls); diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c index 365ce56845..51378ba16a 100644 --- a/drivers/media/i2c/og01a1b.c +++ b/drivers/media/i2c/og01a1b.c @@ -434,9 +434,6 @@ struct og01a1b { /* To serialize asynchronus callbacks */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; static u64 to_pixel_rate(u32 f_index) @@ -732,14 +729,10 @@ static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (og01a1b->streaming == enable) - return 0; - mutex_lock(&og01a1b->mutex); if (enable) { - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_noidle(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) { mutex_unlock(&og01a1b->mutex); return ret; } @@ -755,50 +748,11 @@ static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - og01a1b->streaming = enable; mutex_unlock(&og01a1b->mutex); return ret; } -static int __maybe_unused og01a1b_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct og01a1b *og01a1b = to_og01a1b(sd); - - mutex_lock(&og01a1b->mutex); - if (og01a1b->streaming) - og01a1b_stop_streaming(og01a1b); - - mutex_unlock(&og01a1b->mutex); - - return 0; -} - -static int __maybe_unused og01a1b_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct og01a1b *og01a1b = to_og01a1b(sd); - int ret; - - mutex_lock(&og01a1b->mutex); - if (og01a1b->streaming) { - ret = og01a1b_start_streaming(og01a1b); - if (ret) { - og01a1b->streaming = false; - og01a1b_stop_streaming(og01a1b); - mutex_unlock(&og01a1b->mutex); - return ret; - } - } - - mutex_unlock(&og01a1b->mutex); - - return 0; -} - static int og01a1b_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -1096,10 +1050,6 @@ probe_error_v4l2_ctrl_handler_free: return ret; } -static const struct dev_pm_ops og01a1b_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(og01a1b_suspend, og01a1b_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id og01a1b_acpi_ids[] = { {"OVTI01AC"}, @@ -1112,7 +1062,6 @@ MODULE_DEVICE_TABLE(acpi, og01a1b_acpi_ids); static struct i2c_driver og01a1b_i2c_driver = { .driver = { .name = "og01a1b", - .pm = &og01a1b_pm_ops, .acpi_match_table = ACPI_PTR(og01a1b_acpi_ids), }, .probe = og01a1b_probe, diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c index 9afe9bf503..02de09edc3 100644 --- a/drivers/media/i2c/ov01a10.c +++ b/drivers/media/i2c/ov01a10.c @@ -287,9 +287,6 @@ struct ov01a10 { struct v4l2_ctrl *exposure; const struct ov01a10_mode *cur_mode; - - /* streaming state */ - bool streaming; }; static inline struct ov01a10 *to_ov01a10(struct v4l2_subdev *subdev) @@ -672,8 +669,6 @@ static int ov01a10_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; state = v4l2_subdev_lock_and_get_active_state(sd); - if (ov01a10->streaming == enable) - goto unlock; if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -685,55 +680,12 @@ static int ov01a10_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); goto unlock; } - - goto done; - } - - ov01a10_stop_streaming(ov01a10); - pm_runtime_put(&client->dev); -done: - ov01a10->streaming = enable; -unlock: - v4l2_subdev_unlock_state(state); - - return ret; -} - -static int __maybe_unused ov01a10_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov01a10 *ov01a10 = to_ov01a10(sd); - struct v4l2_subdev_state *state; - - state = v4l2_subdev_lock_and_get_active_state(sd); - if (ov01a10->streaming) - ov01a10_stop_streaming(ov01a10); - - v4l2_subdev_unlock_state(state); - - return 0; -} - -static int __maybe_unused ov01a10_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov01a10 *ov01a10 = to_ov01a10(sd); - struct v4l2_subdev_state *state; - int ret = 0; - - state = v4l2_subdev_lock_and_get_active_state(sd); - if (!ov01a10->streaming) - goto exit; - - ret = ov01a10_start_streaming(ov01a10); - if (ret) { - ov01a10->streaming = false; + } else { ov01a10_stop_streaming(ov01a10); + pm_runtime_put(&client->dev); } -exit: +unlock: v4l2_subdev_unlock_state(state); return ret; @@ -983,10 +935,6 @@ err_handler_free: return ret; } -static const struct dev_pm_ops ov01a10_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov01a10_suspend, ov01a10_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id ov01a10_acpi_ids[] = { { "OVTI01A0" }, @@ -999,7 +947,6 @@ MODULE_DEVICE_TABLE(acpi, ov01a10_acpi_ids); static struct i2c_driver ov01a10_i2c_driver = { .driver = { .name = "ov01a10", - .pm = &ov01a10_pm_ops, .acpi_match_table = ACPI_PTR(ov01a10_acpi_ids), }, .probe = ov01a10_probe, diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c index 741d977a76..848e47a464 100644 --- a/drivers/media/i2c/ov02a10.c +++ b/drivers/media/i2c/ov02a10.c @@ -570,8 +570,6 @@ unlock_and_return: } static const struct dev_pm_ops ov02a10_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, - pm_runtime_force_resume) SET_RUNTIME_PM_OPS(ov02a10_power_off, ov02a10_power_on, NULL) }; diff --git a/drivers/media/i2c/ov08d10.c b/drivers/media/i2c/ov08d10.c index 7d55d4ca24..3d49e3fa8e 100644 --- a/drivers/media/i2c/ov08d10.c +++ b/drivers/media/i2c/ov08d10.c @@ -536,9 +536,6 @@ struct ov08d10 { /* To serialize asynchronus callbacks */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - /* lanes index */ u8 nlanes; @@ -1103,9 +1100,6 @@ static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (ov08d10->streaming == enable) - return 0; - mutex_lock(&ov08d10->mutex); if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -1125,8 +1119,6 @@ static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov08d10->streaming = enable; - /* vflip and hflip cannot change during streaming */ __v4l2_ctrl_grab(ov08d10->vflip, enable); __v4l2_ctrl_grab(ov08d10->hflip, enable); @@ -1136,45 +1128,6 @@ static int ov08d10_set_stream(struct v4l2_subdev *sd, int enable) return ret; } -static int __maybe_unused ov08d10_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov08d10 *ov08d10 = to_ov08d10(sd); - - mutex_lock(&ov08d10->mutex); - if (ov08d10->streaming) - ov08d10_stop_streaming(ov08d10); - - mutex_unlock(&ov08d10->mutex); - - return 0; -} - -static int __maybe_unused ov08d10_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov08d10 *ov08d10 = to_ov08d10(sd); - int ret; - - mutex_lock(&ov08d10->mutex); - - if (ov08d10->streaming) { - ret = ov08d10_start_streaming(ov08d10); - if (ret) { - ov08d10->streaming = false; - ov08d10_stop_streaming(ov08d10); - mutex_unlock(&ov08d10->mutex); - return ret; - } - } - - mutex_unlock(&ov08d10->mutex); - - return 0; -} - static int ov08d10_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -1501,10 +1454,6 @@ probe_error_v4l2_ctrl_handler_free: return ret; } -static const struct dev_pm_ops ov08d10_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov08d10_suspend, ov08d10_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id ov08d10_acpi_ids[] = { { "OVTI08D1" }, @@ -1517,7 +1466,6 @@ MODULE_DEVICE_TABLE(acpi, ov08d10_acpi_ids); static struct i2c_driver ov08d10_i2c_driver = { .driver = { .name = "ov08d10", - .pm = &ov08d10_pm_ops, .acpi_match_table = ACPI_PTR(ov08d10_acpi_ids), }, .probe = ov08d10_probe, diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 637da4df69..b41b6866a0 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -2432,9 +2432,6 @@ struct ov08x40 { /* Mutex for serialized access */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; #define to_ov08x40(_sd) container_of(_sd, struct ov08x40, sd) @@ -2915,10 +2912,6 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov08x->mutex); - if (ov08x->streaming == enable) { - mutex_unlock(&ov08x->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -2937,7 +2930,6 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov08x->streaming = enable; mutex_unlock(&ov08x->mutex); return ret; @@ -2950,37 +2942,6 @@ err_unlock: return ret; } -static int __maybe_unused ov08x40_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov08x40 *ov08x = to_ov08x40(sd); - - if (ov08x->streaming) - ov08x40_stop_streaming(ov08x); - - return 0; -} - -static int __maybe_unused ov08x40_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov08x40 *ov08x = to_ov08x40(sd); - int ret; - - if (ov08x->streaming) { - ret = ov08x40_start_streaming(ov08x); - if (ret) - goto error; - } - - return 0; - -error: - ov08x40_stop_streaming(ov08x); - ov08x->streaming = false; - return ret; -} - /* Verify chip ID */ static int ov08x40_identify_module(struct ov08x40 *ov08x) { @@ -3294,10 +3255,6 @@ static void ov08x40_remove(struct i2c_client *client) pm_runtime_set_suspended(&client->dev); } -static const struct dev_pm_ops ov08x40_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov08x40_suspend, ov08x40_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id ov08x40_acpi_ids[] = { {"OVTI08F4"}, @@ -3310,7 +3267,6 @@ MODULE_DEVICE_TABLE(acpi, ov08x40_acpi_ids); static struct i2c_driver ov08x40_i2c_driver = { .driver = { .name = "ov08x40", - .pm = &ov08x40_pm_ops, .acpi_match_table = ACPI_PTR(ov08x40_acpi_ids), }, .probe = ov08x40_probe, diff --git a/drivers/media/i2c/ov13858.c b/drivers/media/i2c/ov13858.c index 35652b3623..4c419014dd 100644 --- a/drivers/media/i2c/ov13858.c +++ b/drivers/media/i2c/ov13858.c @@ -1044,9 +1044,6 @@ struct ov13858 { /* Mutex for serialized access */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; #define to_ov13858(_sd) container_of(_sd, struct ov13858, sd) @@ -1467,10 +1464,6 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov13858->mutex); - if (ov13858->streaming == enable) { - mutex_unlock(&ov13858->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -1489,7 +1482,6 @@ static int ov13858_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov13858->streaming = enable; mutex_unlock(&ov13858->mutex); return ret; @@ -1502,37 +1494,6 @@ err_unlock: return ret; } -static int __maybe_unused ov13858_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13858 *ov13858 = to_ov13858(sd); - - if (ov13858->streaming) - ov13858_stop_streaming(ov13858); - - return 0; -} - -static int __maybe_unused ov13858_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13858 *ov13858 = to_ov13858(sd); - int ret; - - if (ov13858->streaming) { - ret = ov13858_start_streaming(ov13858); - if (ret) - goto error; - } - - return 0; - -error: - ov13858_stop_streaming(ov13858); - ov13858->streaming = false; - return ret; -} - /* Verify chip ID */ static int ov13858_identify_module(struct ov13858 *ov13858) { @@ -1787,10 +1748,6 @@ static const struct i2c_device_id ov13858_id_table[] = { MODULE_DEVICE_TABLE(i2c, ov13858_id_table); -static const struct dev_pm_ops ov13858_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov13858_suspend, ov13858_resume) -}; - #ifdef CONFIG_ACPI static const struct acpi_device_id ov13858_acpi_ids[] = { {"OVTID858"}, @@ -1803,7 +1760,6 @@ MODULE_DEVICE_TABLE(acpi, ov13858_acpi_ids); static struct i2c_driver ov13858_i2c_driver = { .driver = { .name = "ov13858", - .pm = &ov13858_pm_ops, .acpi_match_table = ACPI_PTR(ov13858_acpi_ids), }, .probe = ov13858_probe, diff --git a/drivers/media/i2c/ov13b10.c b/drivers/media/i2c/ov13b10.c index 124eaa4f9e..2793e4675c 100644 --- a/drivers/media/i2c/ov13b10.c +++ b/drivers/media/i2c/ov13b10.c @@ -31,6 +31,7 @@ #define OV13B10_REG_VTS 0x380e #define OV13B10_VTS_30FPS 0x0c7c #define OV13B10_VTS_60FPS 0x063e +#define OV13B10_VTS_120FPS 0x0320 #define OV13B10_VTS_MAX 0x7fff /* HBLANK control - read only */ @@ -468,6 +469,50 @@ static const struct ov13b10_reg mode_2080x1170_regs[] = { {0x5001, 0x0d}, }; +static const struct ov13b10_reg mode_1364x768_120fps_regs[] = { + {0x0305, 0xaf}, + {0x3011, 0x7c}, + {0x3501, 0x03}, + {0x3502, 0x00}, + {0x3662, 0x88}, + {0x3714, 0x28}, + {0x3739, 0x10}, + {0x37c2, 0x14}, + {0x37d9, 0x06}, + {0x37e2, 0x0c}, + {0x37e4, 0x00}, + {0x3800, 0x02}, + {0x3801, 0xe4}, + {0x3802, 0x03}, + {0x3803, 0x48}, + {0x3804, 0x0d}, + {0x3805, 0xab}, + {0x3806, 0x09}, + {0x3807, 0x60}, + {0x3808, 0x05}, + {0x3809, 0x54}, + {0x380a, 0x03}, + {0x380b, 0x00}, + {0x380c, 0x04}, + {0x380d, 0x8e}, + {0x380e, 0x03}, + {0x380f, 0x20}, + {0x3811, 0x07}, + {0x3813, 0x07}, + {0x3814, 0x03}, + {0x3816, 0x03}, + {0x3820, 0x8b}, + {0x3c8c, 0x18}, + {0x4008, 0x00}, + {0x4009, 0x05}, + {0x4050, 0x00}, + {0x4051, 0x05}, + {0x4501, 0x08}, + {0x4505, 0x04}, + {0x5000, 0xfd}, + {0x5001, 0x0d}, +}; + static const char * const ov13b10_test_pattern_menu[] = { "Disabled", "Vertical Color Bar Type 1", @@ -568,7 +613,18 @@ static const struct ov13b10_mode supported_modes[] = { .regs = mode_2080x1170_regs, }, .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, - } + }, + { + .width = 1364, + .height = 768, + .vts_def = OV13B10_VTS_120FPS, + .vts_min = OV13B10_VTS_120FPS, + .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_1364x768_120fps_regs), + .regs = mode_1364x768_120fps_regs, + }, + }, }; struct ov13b10 { @@ -594,9 +650,6 @@ struct ov13b10 { /* Mutex for serialized access */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - /* True if the device has been identified */ bool identified; }; @@ -1161,10 +1214,6 @@ static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov13b->mutex); - if (ov13b->streaming == enable) { - mutex_unlock(&ov13b->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -1183,7 +1232,6 @@ static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov13b->streaming = enable; mutex_unlock(&ov13b->mutex); return ret; @@ -1198,12 +1246,6 @@ err_unlock: static int ov13b10_suspend(struct device *dev) { - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13b10 *ov13b = to_ov13b10(sd); - - if (ov13b->streaming) - ov13b10_stop_streaming(ov13b); - ov13b10_power_off(dev); return 0; @@ -1211,29 +1253,7 @@ static int ov13b10_suspend(struct device *dev) static int ov13b10_resume(struct device *dev) { - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov13b10 *ov13b = to_ov13b10(sd); - int ret; - - ret = ov13b10_power_on(dev); - if (ret) - goto pm_fail; - - if (ov13b->streaming) { - ret = ov13b10_start_streaming(ov13b); - if (ret) - goto stop_streaming; - } - - return 0; - -stop_streaming: - ov13b10_stop_streaming(ov13b); - ov13b10_power_off(dev); -pm_fail: - ov13b->streaming = false; - - return ret; + return ov13b10_power_on(dev); } static const struct v4l2_subdev_video_ops ov13b10_video_ops = { diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c index bb6c9863a5..28a01c6eff 100644 --- a/drivers/media/i2c/ov2640.c +++ b/drivers/media/i2c/ov2640.c @@ -293,9 +293,7 @@ struct ov2640_win_size { struct ov2640_priv { struct v4l2_subdev subdev; -#if defined(CONFIG_MEDIA_CONTROLLER) struct media_pad pad; -#endif struct v4l2_ctrl_handler hdl; u32 cfmt_code; struct clk *clk; @@ -922,13 +920,9 @@ static int ov2640_get_fmt(struct v4l2_subdev *sd, return -EINVAL; if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mf = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mf; return 0; -#else - return -EINVAL; -#endif } mf->width = priv->win->width; @@ -1005,7 +999,6 @@ out: static int ov2640_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); const struct ov2640_win_size *win = @@ -1019,7 +1012,7 @@ static int ov2640_init_cfg(struct v4l2_subdev *sd, try_fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; try_fmt->quantization = V4L2_QUANTIZATION_DEFAULT; try_fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; -#endif + return 0; } @@ -1205,17 +1198,14 @@ static int ov2640_probe(struct i2c_client *client) return -ENOMEM; if (client->dev.of_node) { - priv->clk = devm_clk_get(&client->dev, "xvclk"); + priv->clk = devm_clk_get_enabled(&client->dev, "xvclk"); if (IS_ERR(priv->clk)) return PTR_ERR(priv->clk); - ret = clk_prepare_enable(priv->clk); - if (ret) - return ret; } ret = ov2640_probe_dt(client, priv); if (ret) - goto err_clk; + return ret; priv->win = ov2640_select_win(SVGA_WIDTH, SVGA_HEIGHT); priv->cfmt_code = MEDIA_BUS_FMT_UYVY8_2X8; @@ -1239,13 +1229,11 @@ static int ov2640_probe(struct i2c_client *client) ret = priv->hdl.error; goto err_hdl; } -#if defined(CONFIG_MEDIA_CONTROLLER) priv->pad.flags = MEDIA_PAD_FL_SOURCE; priv->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&priv->subdev.entity, 1, &priv->pad); if (ret < 0) goto err_hdl; -#endif ret = ov2640_video_probe(client); if (ret < 0) @@ -1264,8 +1252,6 @@ err_videoprobe: err_hdl: v4l2_ctrl_handler_free(&priv->hdl); mutex_destroy(&priv->lock); -err_clk: - clk_disable_unprepare(priv->clk); return ret; } @@ -1278,7 +1264,6 @@ static void ov2640_remove(struct i2c_client *client) mutex_destroy(&priv->lock); media_entity_cleanup(&priv->subdev.entity); v4l2_device_unregister_subdev(&priv->subdev); - clk_disable_unprepare(priv->clk); } static const struct i2c_device_id ov2640_id[] = { diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c index 5429bd2eb0..2c3dbe164e 100644 --- a/drivers/media/i2c/ov2659.c +++ b/drivers/media/i2c/ov2659.c @@ -1031,7 +1031,6 @@ static int ov2659_get_fmt(struct v4l2_subdev *sd, dev_dbg(&client->dev, "ov2659_get_fmt\n"); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mf; mf = v4l2_subdev_get_try_format(sd, sd_state, 0); @@ -1039,9 +1038,6 @@ static int ov2659_get_fmt(struct v4l2_subdev *sd, fmt->format = *mf; mutex_unlock(&ov2659->lock); return 0; -#else - return -EINVAL; -#endif } mutex_lock(&ov2659->lock); @@ -1113,10 +1109,8 @@ static int ov2659_set_fmt(struct v4l2_subdev *sd, mutex_lock(&ov2659->lock); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); *mf = fmt->format; -#endif } else { s64 val; @@ -1306,7 +1300,6 @@ static int ov2659_power_on(struct device *dev) * V4L2 subdev internal operations */ -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct i2c_client *client = v4l2_get_subdevdata(sd); @@ -1319,7 +1312,6 @@ static int ov2659_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } -#endif static const struct v4l2_subdev_core_ops ov2659_subdev_core_ops = { .log_status = v4l2_ctrl_subdev_log_status, @@ -1338,7 +1330,6 @@ static const struct v4l2_subdev_pad_ops ov2659_subdev_pad_ops = { .set_fmt = ov2659_set_fmt, }; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_ops ov2659_subdev_ops = { .core = &ov2659_subdev_core_ops, .video = &ov2659_subdev_video_ops, @@ -1348,7 +1339,6 @@ static const struct v4l2_subdev_ops ov2659_subdev_ops = { static const struct v4l2_subdev_internal_ops ov2659_subdev_internal_ops = { .open = ov2659_open, }; -#endif static int ov2659_detect(struct v4l2_subdev *sd) { @@ -1489,15 +1479,12 @@ static int ov2659_probe(struct i2c_client *client) sd = &ov2659->sd; client->flags |= I2C_CLIENT_SCCB; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API - v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops); + v4l2_i2c_subdev_init(sd, client, &ov2659_subdev_ops); sd->internal_ops = &ov2659_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; -#endif -#if defined(CONFIG_MEDIA_CONTROLLER) ov2659->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &ov2659->pad); @@ -1505,7 +1492,6 @@ static int ov2659_probe(struct i2c_client *client) v4l2_ctrl_handler_free(&ov2659->ctrls); return ret; } -#endif mutex_init(&ov2659->lock); diff --git a/drivers/media/i2c/ov2685.c b/drivers/media/i2c/ov2685.c index 303793e1f9..396583826a 100644 --- a/drivers/media/i2c/ov2685.c +++ b/drivers/media/i2c/ov2685.c @@ -91,7 +91,6 @@ struct ov2685 { struct gpio_desc *reset_gpio; struct regulator_bulk_data supplies[OV2685_NUM_SUPPLIES]; - bool streaming; struct mutex mutex; struct v4l2_subdev subdev; struct media_pad pad; @@ -513,10 +512,6 @@ static int ov2685_s_stream(struct v4l2_subdev *sd, int on) mutex_lock(&ov2685->mutex); - on = !!on; - if (on == ov2685->streaming) - goto unlock_and_return; - if (on) { ret = pm_runtime_resume_and_get(&ov2685->client->dev); if (ret < 0) @@ -539,15 +534,12 @@ static int ov2685_s_stream(struct v4l2_subdev *sd, int on) pm_runtime_put(&ov2685->client->dev); } - ov2685->streaming = on; - unlock_and_return: mutex_unlock(&ov2685->mutex); return ret; } -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov2685_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov2685 *ov2685 = to_ov2685(sd); @@ -563,7 +555,6 @@ static int ov2685_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } -#endif static int __maybe_unused ov2685_runtime_resume(struct device *dev) { @@ -660,11 +651,9 @@ static const struct v4l2_subdev_ops ov2685_subdev_ops = { .pad = &ov2685_pad_ops, }; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_internal_ops ov2685_internal_ops = { .open = ov2685_open, }; -#endif static const struct v4l2_ctrl_ops ov2685_ctrl_ops = { .s_ctrl = ov2685_set_ctrl, @@ -833,17 +822,13 @@ static int ov2685_probe(struct i2c_client *client) if (ret) goto err_power_off; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API ov2685->subdev.internal_ops = &ov2685_internal_ops; ov2685->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -#endif -#if defined(CONFIG_MEDIA_CONTROLLER) ov2685->pad.flags = MEDIA_PAD_FL_SOURCE; ov2685->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&ov2685->subdev.entity, 1, &ov2685->pad); if (ret < 0) goto err_power_off; -#endif ret = v4l2_async_register_subdev(&ov2685->subdev); if (ret) { @@ -858,9 +843,7 @@ static int ov2685_probe(struct i2c_client *client) return 0; err_clean_entity: -#if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&ov2685->subdev.entity); -#endif err_power_off: __ov2685_power_off(ov2685); err_free_handler: @@ -877,9 +860,7 @@ static void ov2685_remove(struct i2c_client *client) struct ov2685 *ov2685 = to_ov2685(sd); v4l2_async_unregister_subdev(sd); -#if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&sd->entity); -#endif v4l2_ctrl_handler_free(&ov2685->ctrl_handler); mutex_destroy(&ov2685->mutex); diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c index 41d4f85470..6be22586c3 100644 --- a/drivers/media/i2c/ov2740.c +++ b/drivers/media/i2c/ov2740.c @@ -310,7 +310,7 @@ static const struct ov2740_mode supported_modes[] = { { .width = 1932, .height = 1092, - .hts = 1080, + .hts = 2160, .vts_def = OV2740_VTS_DEF, .vts_min = OV2740_VTS_MIN, .reg_list = { @@ -336,12 +336,6 @@ struct ov2740 { /* Current mode */ const struct ov2740_mode *cur_mode; - /* To serialize asynchronus callbacks */ - struct mutex mutex; - - /* Streaming on/off */ - bool streaming; - /* NVM data inforamtion */ struct nvm_data *nvm; @@ -363,15 +357,6 @@ static u64 to_pixel_rate(u32 f_index) return pixel_rate; } -static u64 to_pixels_per_line(u32 hts, u32 f_index) -{ - u64 ppl = hts * to_pixel_rate(f_index); - - do_div(ppl, OV2740_SCLK); - - return ppl; -} - static int ov2740_read_reg(struct ov2740 *ov2740, u16 reg, u16 len, u32 *val) { struct i2c_client *client = v4l2_get_subdevdata(&ov2740->sd); @@ -582,7 +567,6 @@ static int ov2740_init_controls(struct ov2740 *ov2740) if (ret) return ret; - ctrl_hdlr->lock = &ov2740->mutex; cur_mode = ov2740->cur_mode; size = ARRAY_SIZE(link_freq_menu_items); @@ -605,8 +589,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) V4L2_CID_VBLANK, vblank_min, vblank_max, 1, vblank_default); - h_blank = to_pixels_per_line(cur_mode->hts, cur_mode->link_freq_index); - h_blank -= cur_mode->width; + h_blank = cur_mode->hts - cur_mode->width; ov2740->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, V4L2_CID_HBLANK, h_blank, h_blank, 1, h_blank); @@ -792,18 +775,15 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable) { struct ov2740 *ov2740 = to_ov2740(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); + struct v4l2_subdev_state *sd_state; int ret = 0; - if (ov2740->streaming == enable) - return 0; + sd_state = v4l2_subdev_lock_and_get_active_state(&ov2740->sd); - mutex_lock(&ov2740->mutex); if (enable) { ret = pm_runtime_resume_and_get(&client->dev); - if (ret < 0) { - mutex_unlock(&ov2740->mutex); - return ret; - } + if (ret < 0) + goto out_unlock; ret = ov2740_start_streaming(ov2740); if (ret) { @@ -816,47 +796,12 @@ static int ov2740_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov2740->streaming = enable; - mutex_unlock(&ov2740->mutex); +out_unlock: + v4l2_subdev_unlock_state(sd_state); return ret; } -static int ov2740_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov2740 *ov2740 = to_ov2740(sd); - - mutex_lock(&ov2740->mutex); - if (ov2740->streaming) - ov2740_stop_streaming(ov2740); - - mutex_unlock(&ov2740->mutex); - - return 0; -} - -static int ov2740_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov2740 *ov2740 = to_ov2740(sd); - int ret = 0; - - mutex_lock(&ov2740->mutex); - if (!ov2740->streaming) - goto exit; - - ret = ov2740_start_streaming(ov2740); - if (ret) { - ov2740->streaming = false; - ov2740_stop_streaming(ov2740); - } - -exit: - mutex_unlock(&ov2740->mutex); - return ret; -} - static int ov2740_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -870,48 +815,25 @@ static int ov2740_set_format(struct v4l2_subdev *sd, height, fmt->format.width, fmt->format.height); - mutex_lock(&ov2740->mutex); ov2740_update_pad_format(mode, &fmt->format); - if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { - *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; - } else { - ov2740->cur_mode = mode; - __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index); - __v4l2_ctrl_s_ctrl_int64(ov2740->pixel_rate, - to_pixel_rate(mode->link_freq_index)); - - /* Update limits and set FPS to default */ - vblank_def = mode->vts_def - mode->height; - __v4l2_ctrl_modify_range(ov2740->vblank, - mode->vts_min - mode->height, - OV2740_VTS_MAX - mode->height, 1, - vblank_def); - __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); - h_blank = to_pixels_per_line(mode->hts, mode->link_freq_index) - - mode->width; - __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, - h_blank); - } - mutex_unlock(&ov2740->mutex); + *v4l2_subdev_get_pad_format(sd, sd_state, fmt->pad) = fmt->format; - return 0; -} - -static int ov2740_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *fmt) -{ - struct ov2740 *ov2740 = to_ov2740(sd); - - mutex_lock(&ov2740->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) - fmt->format = *v4l2_subdev_get_try_format(&ov2740->sd, - sd_state, - fmt->pad); - else - ov2740_update_pad_format(ov2740->cur_mode, &fmt->format); + return 0; - mutex_unlock(&ov2740->mutex); + ov2740->cur_mode = mode; + __v4l2_ctrl_s_ctrl(ov2740->link_freq, mode->link_freq_index); + __v4l2_ctrl_s_ctrl_int64(ov2740->pixel_rate, + to_pixel_rate(mode->link_freq_index)); + + /* Update limits and set FPS to default */ + vblank_def = mode->vts_def - mode->height; + __v4l2_ctrl_modify_range(ov2740->vblank, + mode->vts_min - mode->height, + OV2740_VTS_MAX - mode->height, 1, vblank_def); + __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); + h_blank = mode->hts - mode->width; + __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, h_blank); return 0; } @@ -946,14 +868,11 @@ static int ov2740_enum_frame_size(struct v4l2_subdev *sd, return 0; } -static int ov2740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) +static int ov2740_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_state *sd_state) { - struct ov2740 *ov2740 = to_ov2740(sd); - - mutex_lock(&ov2740->mutex); ov2740_update_pad_format(&supported_modes[0], - v4l2_subdev_get_try_format(sd, fh->state, 0)); - mutex_unlock(&ov2740->mutex); + v4l2_subdev_get_pad_format(sd, sd_state, 0)); return 0; } @@ -963,10 +882,11 @@ static const struct v4l2_subdev_video_ops ov2740_video_ops = { }; static const struct v4l2_subdev_pad_ops ov2740_pad_ops = { + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = ov2740_set_format, - .get_fmt = ov2740_get_format, .enum_mbus_code = ov2740_enum_mbus_code, .enum_frame_size = ov2740_enum_frame_size, + .init_cfg = ov2740_init_cfg, }; static const struct v4l2_subdev_ops ov2740_subdev_ops = { @@ -978,10 +898,6 @@ static const struct media_entity_operations ov2740_subdev_entity_ops = { .link_validate = v4l2_subdev_link_validate, }; -static const struct v4l2_subdev_internal_ops ov2740_internal_ops = { - .open = ov2740_open, -}; - static int ov2740_check_hwcfg(struct device *dev) { struct fwnode_handle *ep; @@ -1004,7 +920,7 @@ static int ov2740_check_hwcfg(struct device *dev) ep = fwnode_graph_get_next_endpoint(fwnode, NULL); if (!ep) - return -ENXIO; + return -EPROBE_DEFER; ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); fwnode_handle_put(ep); @@ -1047,13 +963,12 @@ check_hwcfg_error: static void ov2740_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov2740 *ov2740 = to_ov2740(sd); v4l2_async_unregister_subdev(sd); media_entity_cleanup(&sd->entity); + v4l2_subdev_cleanup(sd); v4l2_ctrl_handler_free(sd->ctrl_handler); pm_runtime_disable(&client->dev); - mutex_destroy(&ov2740->mutex); } static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, @@ -1062,9 +977,11 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, struct nvm_data *nvm = priv; struct device *dev = regmap_get_device(nvm->regmap); struct ov2740 *ov2740 = to_ov2740(dev_get_drvdata(dev)); + struct v4l2_subdev_state *sd_state; int ret = 0; - mutex_lock(&ov2740->mutex); + /* Serialise sensor access */ + sd_state = v4l2_subdev_lock_and_get_active_state(&ov2740->sd); if (nvm->nvm_buffer) { memcpy(val, nvm->nvm_buffer + off, count); @@ -1082,7 +999,7 @@ static int ov2740_nvmem_read(void *priv, unsigned int off, void *val, pm_runtime_put(dev); exit: - mutex_unlock(&ov2740->mutex); + v4l2_subdev_unlock_state(sd_state); return ret; } @@ -1153,7 +1070,6 @@ static int ov2740_probe(struct i2c_client *client) return dev_err_probe(dev, ret, "failed to find sensor\n"); } - mutex_init(&ov2740->mutex); ov2740->cur_mode = &supported_modes[0]; ret = ov2740_init_controls(ov2740); if (ret) { @@ -1161,7 +1077,7 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } - ov2740->sd.internal_ops = &ov2740_internal_ops; + ov2740->sd.state_lock = ov2740->ctrl_handler.lock; ov2740->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ov2740->sd.entity.ops = &ov2740_subdev_entity_ops; ov2740->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -1172,36 +1088,42 @@ static int ov2740_probe(struct i2c_client *client) goto probe_error_v4l2_ctrl_handler_free; } + ret = v4l2_subdev_init_finalize(&ov2740->sd); + if (ret) + goto probe_error_media_entity_cleanup; + + /* Set the device's state to active if it's in D0 state. */ + if (full_power) + pm_runtime_set_active(&client->dev); + pm_runtime_enable(&client->dev); + pm_runtime_idle(&client->dev); + ret = v4l2_async_register_subdev_sensor(&ov2740->sd); if (ret < 0) { dev_err_probe(dev, ret, "failed to register V4L2 subdev\n"); - goto probe_error_media_entity_cleanup; + goto probe_error_v4l2_subdev_cleanup; } ret = ov2740_register_nvmem(client, ov2740); if (ret) dev_warn(&client->dev, "register nvmem failed, ret %d\n", ret); - /* Set the device's state to active if it's in D0 state. */ - if (full_power) - pm_runtime_set_active(&client->dev); - pm_runtime_enable(&client->dev); - pm_runtime_idle(&client->dev); - return 0; +probe_error_v4l2_subdev_cleanup: + v4l2_subdev_cleanup(&ov2740->sd); + probe_error_media_entity_cleanup: media_entity_cleanup(&ov2740->sd.entity); + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); probe_error_v4l2_ctrl_handler_free: v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler); - mutex_destroy(&ov2740->mutex); return ret; } -static DEFINE_SIMPLE_DEV_PM_OPS(ov2740_pm_ops, ov2740_suspend, ov2740_resume); - static const struct acpi_device_id ov2740_acpi_ids[] = { {"INT3474"}, {} @@ -1212,7 +1134,6 @@ MODULE_DEVICE_TABLE(acpi, ov2740_acpi_ids); static struct i2c_driver ov2740_i2c_driver = { .driver = { .name = "ov2740", - .pm = pm_sleep_ptr(&ov2740_pm_ops), .acpi_match_table = ov2740_acpi_ids, }, .probe = ov2740_probe, diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c index fda217d2cb..3bd972a822 100644 --- a/drivers/media/i2c/ov4689.c +++ b/drivers/media/i2c/ov4689.c @@ -99,8 +99,7 @@ struct ov4689 { u32 clock_rate; - struct mutex mutex; /* lock to protect streaming, ctrls and cur_mode */ - bool streaming; + struct mutex mutex; /* lock to protect ctrls and cur_mode */ struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl *exposure; @@ -468,10 +467,6 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) mutex_lock(&ov4689->mutex); - on = !!on; - if (on == ov4689->streaming) - goto unlock_and_return; - if (on) { ret = pm_runtime_resume_and_get(&client->dev); if (ret < 0) @@ -504,8 +499,6 @@ static int ov4689_s_stream(struct v4l2_subdev *sd, int on) pm_runtime_put(&client->dev); } - ov4689->streaming = on; - unlock_and_return: mutex_unlock(&ov4689->mutex); diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c index 8de398423b..dcfe3129c6 100644 --- a/drivers/media/i2c/ov5647.c +++ b/drivers/media/i2c/ov5647.c @@ -109,7 +109,6 @@ struct ov5647 { struct v4l2_ctrl *hblank; struct v4l2_ctrl *vblank; struct v4l2_ctrl *exposure; - bool streaming; }; static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) @@ -898,10 +897,6 @@ static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) int ret; mutex_lock(&sensor->lock); - if (sensor->streaming == enable) { - mutex_unlock(&sensor->lock); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -922,7 +917,6 @@ static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - sensor->streaming = enable; mutex_unlock(&sensor->lock); return 0; diff --git a/drivers/media/i2c/ov5670.c b/drivers/media/i2c/ov5670.c index 29e773a997..e80db3ecd4 100644 --- a/drivers/media/i2c/ov5670.c +++ b/drivers/media/i2c/ov5670.c @@ -1882,8 +1882,6 @@ struct ov5670 { /* To serialize asynchronus callbacks */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; /* True if the device has been identified */ bool identified; }; @@ -2471,8 +2469,6 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov5670->mutex); - if (ov5670->streaming == enable) - goto unlock_and_return; if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -2486,7 +2482,6 @@ static int ov5670_set_stream(struct v4l2_subdev *sd, int enable) ret = ov5670_stop_streaming(ov5670); pm_runtime_put(&client->dev); } - ov5670->streaming = enable; goto unlock_and_return; error: @@ -2541,34 +2536,6 @@ static int __maybe_unused ov5670_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused ov5670_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov5670 *ov5670 = to_ov5670(sd); - - if (ov5670->streaming) - ov5670_stop_streaming(ov5670); - - return 0; -} - -static int __maybe_unused ov5670_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov5670 *ov5670 = to_ov5670(sd); - int ret; - - if (ov5670->streaming) { - ret = ov5670_start_streaming(ov5670); - if (ret) { - ov5670_stop_streaming(ov5670); - return ret; - } - } - - return 0; -} - static const struct v4l2_subdev_core_ops ov5670_core_ops = { .log_status = v4l2_ctrl_subdev_log_status, .subscribe_event = v4l2_ctrl_subdev_subscribe_event, @@ -2771,8 +2738,6 @@ static int ov5670_probe(struct i2c_client *client) goto error_handler_free; } - ov5670->streaming = false; - /* Set the device's state to active if it's in D0 state. */ if (full_power) pm_runtime_set_active(&client->dev); @@ -2827,7 +2792,6 @@ static void ov5670_remove(struct i2c_client *client) } static const struct dev_pm_ops ov5670_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov5670_suspend, ov5670_resume) SET_RUNTIME_PM_OPS(ov5670_runtime_suspend, ov5670_runtime_resume, NULL) }; diff --git a/drivers/media/i2c/ov5675.c b/drivers/media/i2c/ov5675.c index d5a2a5f823..e63d9d402d 100644 --- a/drivers/media/i2c/ov5675.c +++ b/drivers/media/i2c/ov5675.c @@ -513,9 +513,6 @@ struct ov5675 { /* To serialize asynchronus callbacks */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - /* True if the device has been identified */ bool identified; }; @@ -949,9 +946,6 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (ov5675->streaming == enable) - return 0; - mutex_lock(&ov5675->mutex); if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -971,7 +965,6 @@ static int ov5675_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov5675->streaming = enable; mutex_unlock(&ov5675->mutex); return ret; @@ -1027,42 +1020,6 @@ static int ov5675_power_on(struct device *dev) return 0; } -static int __maybe_unused ov5675_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov5675 *ov5675 = to_ov5675(sd); - - mutex_lock(&ov5675->mutex); - if (ov5675->streaming) - ov5675_stop_streaming(ov5675); - - mutex_unlock(&ov5675->mutex); - - return 0; -} - -static int __maybe_unused ov5675_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov5675 *ov5675 = to_ov5675(sd); - int ret; - - mutex_lock(&ov5675->mutex); - if (ov5675->streaming) { - ret = ov5675_start_streaming(ov5675); - if (ret) { - ov5675->streaming = false; - ov5675_stop_streaming(ov5675); - mutex_unlock(&ov5675->mutex); - return ret; - } - } - - mutex_unlock(&ov5675->mutex); - - return 0; -} - static int ov5675_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -1409,7 +1366,6 @@ probe_power_off: } static const struct dev_pm_ops ov5675_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov5675_suspend, ov5675_resume) SET_RUNTIME_PM_OPS(ov5675_power_off, ov5675_power_on, NULL) }; diff --git a/drivers/media/i2c/ov5693.c b/drivers/media/i2c/ov5693.c index 488ee6d9d3..819425e213 100644 --- a/drivers/media/i2c/ov5693.c +++ b/drivers/media/i2c/ov5693.c @@ -154,7 +154,6 @@ struct ov5693_device { unsigned int inc_y_odd; unsigned int vts; } mode; - bool streaming; struct v4l2_subdev sd; struct media_pad pad; @@ -975,9 +974,9 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable) int ret; if (enable) { - ret = pm_runtime_get_sync(ov5693->dev); - if (ret < 0) - goto err_power_down; + ret = pm_runtime_resume_and_get(ov5693->dev); + if (ret) + return ret; mutex_lock(&ov5693->lock); ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler); @@ -996,8 +995,6 @@ static int ov5693_s_stream(struct v4l2_subdev *sd, int enable) if (ret) goto err_power_down; - ov5693->streaming = !!enable; - if (!enable) pm_runtime_put(ov5693->dev); diff --git a/drivers/media/i2c/ov5695.c b/drivers/media/i2c/ov5695.c index 3023b72541..c8f57ce157 100644 --- a/drivers/media/i2c/ov5695.c +++ b/drivers/media/i2c/ov5695.c @@ -108,7 +108,6 @@ struct ov5695 { struct v4l2_ctrl *vblank; struct v4l2_ctrl *test_pattern; struct mutex mutex; - bool streaming; const struct ov5695_mode *cur_mode; }; @@ -821,9 +820,7 @@ static int ov5695_set_fmt(struct v4l2_subdev *sd, fmt->format.height = mode->height; fmt->format.field = V4L2_FIELD_NONE; if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; -#endif } else { ov5695->cur_mode = mode; h_blank = mode->hts_def - mode->width; @@ -849,13 +846,8 @@ static int ov5695_get_fmt(struct v4l2_subdev *sd, mutex_lock(&ov5695->mutex); if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API fmt->format = *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); -#else - mutex_unlock(&ov5695->mutex); - return -EINVAL; -#endif } else { fmt->format.width = mode->width; fmt->format.height = mode->height; @@ -942,9 +934,6 @@ static int ov5695_s_stream(struct v4l2_subdev *sd, int on) int ret = 0; mutex_lock(&ov5695->mutex); - on = !!on; - if (on == ov5695->streaming) - goto unlock_and_return; if (on) { ret = pm_runtime_resume_and_get(&client->dev); @@ -962,8 +951,6 @@ static int ov5695_s_stream(struct v4l2_subdev *sd, int on) pm_runtime_put(&client->dev); } - ov5695->streaming = on; - unlock_and_return: mutex_unlock(&ov5695->mutex); @@ -1048,7 +1035,6 @@ static int __maybe_unused ov5695_runtime_suspend(struct device *dev) return 0; } -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov5695_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov5695 *ov5695 = to_ov5695(sd); @@ -1068,18 +1054,15 @@ static int ov5695_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } -#endif static const struct dev_pm_ops ov5695_pm_ops = { SET_RUNTIME_PM_OPS(ov5695_runtime_suspend, ov5695_runtime_resume, NULL) }; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_internal_ops ov5695_internal_ops = { .open = ov5695_open, }; -#endif static const struct v4l2_subdev_video_ops ov5695_video_ops = { .s_stream = ov5695_s_stream, @@ -1322,17 +1305,13 @@ static int ov5695_probe(struct i2c_client *client) if (ret) goto err_power_off; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sd->internal_ops = &ov5695_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; -#endif -#if defined(CONFIG_MEDIA_CONTROLLER) ov5695->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &ov5695->pad); if (ret < 0) goto err_power_off; -#endif ret = v4l2_async_register_subdev_sensor(sd); if (ret) { @@ -1347,9 +1326,7 @@ static int ov5695_probe(struct i2c_client *client) return 0; err_clean_entity: -#if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&sd->entity); -#endif err_power_off: __ov5695_power_off(ov5695); err_free_handler: @@ -1366,9 +1343,7 @@ static void ov5695_remove(struct i2c_client *client) struct ov5695 *ov5695 = to_ov5695(sd); v4l2_async_unregister_subdev(sd); -#if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&sd->entity); -#endif v4l2_ctrl_handler_free(&ov5695->ctrl_handler); mutex_destroy(&ov5695->mutex); diff --git a/drivers/media/i2c/ov7251.c b/drivers/media/i2c/ov7251.c index 675fb37a6f..6582cc0e23 100644 --- a/drivers/media/i2c/ov7251.c +++ b/drivers/media/i2c/ov7251.c @@ -1340,9 +1340,11 @@ static int ov7251_s_stream(struct v4l2_subdev *subdev, int enable) mutex_lock(&ov7251->lock); if (enable) { - ret = pm_runtime_get_sync(ov7251->dev); - if (ret < 0) - goto err_power_down; + ret = pm_runtime_resume_and_get(ov7251->dev); + if (ret) { + mutex_unlock(&ov7251->lock); + return ret; + } ret = ov7251_pll_configure(ov7251); if (ret) { diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c index 2f55491ef5..172483597c 100644 --- a/drivers/media/i2c/ov7670.c +++ b/drivers/media/i2c/ov7670.c @@ -10,6 +10,7 @@ */ #include <linux/clk.h> #include <linux/init.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/slab.h> #include <linux/i2c.h> @@ -186,11 +187,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define REG_HAECC7 0xaa /* Hist AEC/AGC control 7 */ #define REG_BD60MAX 0xab /* 60hz banding step limit */ -enum ov7670_model { - MODEL_OV7670 = 0, - MODEL_OV7675, -}; - struct ov7670_win_size { int width; int height; @@ -217,9 +213,7 @@ struct ov7670_devtype { struct ov7670_format_struct; /* coming later */ struct ov7670_info { struct v4l2_subdev sd; -#if defined(CONFIG_MEDIA_CONTROLLER) struct media_pad pad; -#endif struct v4l2_ctrl_handler hdl; struct { /* gain cluster */ @@ -1108,9 +1102,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ov7670_info *info = to_state(sd); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mbus_fmt; -#endif int ret; if (format->pad) @@ -1120,11 +1112,9 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd, ret = ov7670_try_fmt_internal(sd, &format->format, NULL, NULL); if (ret) return ret; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); *mbus_fmt = format->format; -#endif return 0; } @@ -1148,18 +1138,12 @@ static int ov7670_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ov7670_info *info = to_state(sd); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mbus_fmt; -#endif if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mbus_fmt; return 0; -#else - return -EINVAL; -#endif } else { format->format = info->format; } @@ -1720,7 +1704,6 @@ static void ov7670_get_default_format(struct v4l2_subdev *sd, format->field = V4L2_FIELD_NONE; } -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov7670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct v4l2_mbus_framefmt *format = @@ -1730,7 +1713,6 @@ static int ov7670_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) return 0; } -#endif /* ----------------------------------------------------------------------- */ @@ -1766,29 +1748,12 @@ static const struct v4l2_subdev_ops ov7670_ops = { .pad = &ov7670_pad_ops, }; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static const struct v4l2_subdev_internal_ops ov7670_subdev_internal_ops = { .open = ov7670_open, }; -#endif /* ----------------------------------------------------------------------- */ -static const struct ov7670_devtype ov7670_devdata[] = { - [MODEL_OV7670] = { - .win_sizes = ov7670_win_sizes, - .n_win_sizes = ARRAY_SIZE(ov7670_win_sizes), - .set_framerate = ov7670_set_framerate_legacy, - .get_framerate = ov7670_get_framerate_legacy, - }, - [MODEL_OV7675] = { - .win_sizes = ov7675_win_sizes, - .n_win_sizes = ARRAY_SIZE(ov7675_win_sizes), - .set_framerate = ov7675_set_framerate, - .get_framerate = ov7675_get_framerate, - }, -}; - static int ov7670_init_gpio(struct i2c_client *client, struct ov7670_info *info) { info->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown", @@ -1849,7 +1814,6 @@ static int ov7670_parse_dt(struct device *dev, static int ov7670_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct v4l2_fract tpf; struct v4l2_subdev *sd; struct ov7670_info *info; @@ -1861,10 +1825,8 @@ static int ov7670_probe(struct i2c_client *client) sd = &info->sd; v4l2_i2c_subdev_init(sd, client, &ov7670_ops); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sd->internal_ops = &ov7670_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; -#endif info->clock_speed = 30; /* default: a guess */ @@ -1923,7 +1885,7 @@ static int ov7670_probe(struct i2c_client *client) v4l_info(client, "chip found @ 0x%02x (%s)\n", client->addr << 1, client->adapter->name); - info->devtype = &ov7670_devdata[id->driver_data]; + info->devtype = i2c_get_match_data(client); info->fmt = &ov7670_formats[0]; info->wsize = &info->devtype->win_sizes[0]; @@ -1977,13 +1939,11 @@ static int ov7670_probe(struct i2c_client *client) V4L2_EXPOSURE_MANUAL, false); v4l2_ctrl_cluster(2, &info->saturation); -#if defined(CONFIG_MEDIA_CONTROLLER) info->pad.flags = MEDIA_PAD_FL_SOURCE; info->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&info->sd.entity, 1, &info->pad); if (ret < 0) goto hdl_free; -#endif v4l2_ctrl_handler_setup(&info->hdl); @@ -2013,25 +1973,37 @@ static void ov7670_remove(struct i2c_client *client) media_entity_cleanup(&info->sd.entity); } +static const struct ov7670_devtype ov7670_devdata = { + .win_sizes = ov7670_win_sizes, + .n_win_sizes = ARRAY_SIZE(ov7670_win_sizes), + .set_framerate = ov7670_set_framerate_legacy, + .get_framerate = ov7670_get_framerate_legacy, +}; + +static const struct ov7670_devtype ov7675_devdata = { + .win_sizes = ov7675_win_sizes, + .n_win_sizes = ARRAY_SIZE(ov7675_win_sizes), + .set_framerate = ov7675_set_framerate, + .get_framerate = ov7675_get_framerate, +}; + static const struct i2c_device_id ov7670_id[] = { - { "ov7670", MODEL_OV7670 }, - { "ov7675", MODEL_OV7675 }, - { } + { "ov7670", (kernel_ulong_t)&ov7670_devdata }, + { "ov7675", (kernel_ulong_t)&ov7675_devdata }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, ov7670_id); -#if IS_ENABLED(CONFIG_OF) static const struct of_device_id ov7670_of_match[] = { - { .compatible = "ovti,ov7670", }, - { /* sentinel */ }, + { .compatible = "ovti,ov7670", &ov7670_devdata }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ov7670_of_match); -#endif static struct i2c_driver ov7670_driver = { .driver = { .name = "ov7670", - .of_match_table = of_match_ptr(ov7670_of_match), + .of_match_table = ov7670_of_match, }, .probe = ov7670_probe, .remove = ov7670_remove, diff --git a/drivers/media/i2c/ov772x.c b/drivers/media/i2c/ov772x.c index 386d69c8e0..7618b58a7a 100644 --- a/drivers/media/i2c/ov772x.c +++ b/drivers/media/i2c/ov772x.c @@ -433,9 +433,7 @@ struct ov772x_priv { struct mutex lock; int power_count; int streaming; -#ifdef CONFIG_MEDIA_CONTROLLER struct media_pad pad; -#endif enum v4l2_mbus_type bus_type; }; @@ -1488,13 +1486,11 @@ static int ov772x_probe(struct i2c_client *client) if (ret < 0) goto error_gpio_put; -#ifdef CONFIG_MEDIA_CONTROLLER priv->pad.flags = MEDIA_PAD_FL_SOURCE; priv->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&priv->subdev.entity, 1, &priv->pad); if (ret < 0) goto error_gpio_put; -#endif priv->cfmt = &ov772x_cfmts[0]; priv->win = &ov772x_win_sizes[0]; diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c index dffdb475e4..356a45e65b 100644 --- a/drivers/media/i2c/ov7740.c +++ b/drivers/media/i2c/ov7740.c @@ -83,9 +83,7 @@ struct ov7740 { struct v4l2_subdev subdev; -#if defined(CONFIG_MEDIA_CONTROLLER) struct media_pad pad; -#endif struct v4l2_mbus_framefmt format; const struct ov7740_pixfmt *fmt; /* Current format */ const struct ov7740_framesize *frmsize; @@ -120,7 +118,6 @@ struct ov7740 { struct v4l2_ctrl *contrast; struct mutex mutex; /* To serialize asynchronus callbacks */ - bool streaming; /* Streaming on/off */ struct gpio_desc *resetb_gpio; struct gpio_desc *pwdn_gpio; @@ -618,10 +615,6 @@ static int ov7740_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov7740->mutex); - if (ov7740->streaming == enable) { - mutex_unlock(&ov7740->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -635,8 +628,6 @@ static int ov7740_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov7740->streaming = enable; - mutex_unlock(&ov7740->mutex); return ret; @@ -807,9 +798,7 @@ static int ov7740_set_fmt(struct v4l2_subdev *sd, struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); const struct ov7740_pixfmt *ovfmt; const struct ov7740_framesize *fsize; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mbus_fmt; -#endif int ret; mutex_lock(&ov7740->mutex); @@ -822,11 +811,10 @@ static int ov7740_set_fmt(struct v4l2_subdev *sd, ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL); if (ret) goto error; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API + mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, format->pad); *mbus_fmt = format->format; -#endif mutex_unlock(&ov7740->mutex); return 0; } @@ -851,26 +839,18 @@ static int ov7740_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_format *format) { struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *mbus_fmt; -#endif - int ret = 0; mutex_lock(&ov7740->mutex); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API mbus_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); format->format = *mbus_fmt; - ret = 0; -#else - ret = -EINVAL; -#endif } else { format->format = ov7740->format; } mutex_unlock(&ov7740->mutex); - return ret; + return 0; } static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = { @@ -899,7 +879,6 @@ static void ov7740_get_default_format(struct v4l2_subdev *sd, format->field = V4L2_FIELD_NONE; } -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev); @@ -916,7 +895,6 @@ static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = { .open = ov7740_open, }; -#endif static int ov7740_probe_dt(struct i2c_client *client, struct ov7740 *ov7740) @@ -1094,18 +1072,14 @@ static int ov7740_probe(struct i2c_client *client) sd = &ov7740->subdev; v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sd->internal_ops = &ov7740_subdev_internal_ops; sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; -#endif -#if defined(CONFIG_MEDIA_CONTROLLER) ov7740->pad.flags = MEDIA_PAD_FL_SOURCE; sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad); if (ret) return ret; -#endif ret = ov7740_set_power(ov7740, 1); if (ret) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index f053c3a767..a0f673a24e 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -1438,9 +1438,6 @@ struct ov8856 { /* To serialize asynchronus callbacks */ struct mutex mutex; - /* Streaming on/off */ - bool streaming; - /* lanes index */ u8 nlanes; @@ -2042,9 +2039,6 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable) struct i2c_client *client = v4l2_get_subdevdata(sd); int ret = 0; - if (ov8856->streaming == enable) - return 0; - mutex_lock(&ov8856->mutex); if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -2064,7 +2058,6 @@ static int ov8856_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov8856->streaming = enable; mutex_unlock(&ov8856->mutex); return ret; @@ -2125,45 +2118,6 @@ static int ov8856_power_off(struct device *dev) return 0; } -static int __maybe_unused ov8856_suspend(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov8856 *ov8856 = to_ov8856(sd); - - mutex_lock(&ov8856->mutex); - if (ov8856->streaming) - ov8856_stop_streaming(ov8856); - - ov8856_power_off(dev); - mutex_unlock(&ov8856->mutex); - - return 0; -} - -static int __maybe_unused ov8856_resume(struct device *dev) -{ - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov8856 *ov8856 = to_ov8856(sd); - int ret; - - mutex_lock(&ov8856->mutex); - - ov8856_power_on(dev); - if (ov8856->streaming) { - ret = ov8856_start_streaming(ov8856); - if (ret) { - ov8856->streaming = false; - ov8856_stop_streaming(ov8856); - mutex_unlock(&ov8856->mutex); - return ret; - } - } - - mutex_unlock(&ov8856->mutex); - - return 0; -} - static int ov8856_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *fmt) @@ -2501,7 +2455,6 @@ probe_power_off: } static const struct dev_pm_ops ov8856_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov8856_suspend, ov8856_resume) SET_RUNTIME_PM_OPS(ov8856_power_off, ov8856_power_on, NULL) }; diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c index 068c7449f5..bf6dfce1b5 100644 --- a/drivers/media/i2c/ov9282.c +++ b/drivers/media/i2c/ov9282.c @@ -165,7 +165,6 @@ struct ov9282_mode { * @cur_mode: Pointer to current selected sensor mode * @code: Mbus code currently selected * @mutex: Mutex for serializing sensor controls - * @streaming: Flag indicating streaming state */ struct ov9282 { struct device *dev; @@ -188,7 +187,6 @@ struct ov9282 { const struct ov9282_mode *cur_mode; u32 code; struct mutex mutex; - bool streaming; }; static const s64 link_freq[] = { @@ -1037,11 +1035,6 @@ static int ov9282_set_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&ov9282->mutex); - if (ov9282->streaming == enable) { - mutex_unlock(&ov9282->mutex); - return 0; - } - if (enable) { ret = pm_runtime_resume_and_get(ov9282->dev); if (ret) @@ -1055,8 +1048,6 @@ static int ov9282_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(ov9282->dev); } - ov9282->streaming = enable; - mutex_unlock(&ov9282->mutex); return 0; diff --git a/drivers/media/i2c/ov9734.c b/drivers/media/i2c/ov9734.c index b36fc0feda..f1377c305b 100644 --- a/drivers/media/i2c/ov9734.c +++ b/drivers/media/i2c/ov9734.c @@ -337,9 +337,6 @@ struct ov9734 { /* To serialize asynchronus callbacks */ struct mutex mutex; - - /* Streaming on/off */ - bool streaming; }; static inline struct ov9734 *to_ov9734(struct v4l2_subdev *subdev) @@ -660,10 +657,6 @@ static int ov9734_set_stream(struct v4l2_subdev *sd, int enable) int ret = 0; mutex_lock(&ov9734->mutex); - if (ov9734->streaming == enable) { - mutex_unlock(&ov9734->mutex); - return 0; - } if (enable) { ret = pm_runtime_resume_and_get(&client->dev); @@ -683,46 +676,8 @@ static int ov9734_set_stream(struct v4l2_subdev *sd, int enable) pm_runtime_put(&client->dev); } - ov9734->streaming = enable; - mutex_unlock(&ov9734->mutex); - - return ret; -} - -static int __maybe_unused ov9734_suspend(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov9734 *ov9734 = to_ov9734(sd); - - mutex_lock(&ov9734->mutex); - if (ov9734->streaming) - ov9734_stop_streaming(ov9734); - mutex_unlock(&ov9734->mutex); - return 0; -} - -static int __maybe_unused ov9734_resume(struct device *dev) -{ - struct i2c_client *client = to_i2c_client(dev); - struct v4l2_subdev *sd = i2c_get_clientdata(client); - struct ov9734 *ov9734 = to_ov9734(sd); - int ret = 0; - - mutex_lock(&ov9734->mutex); - if (!ov9734->streaming) - goto exit; - - ret = ov9734_start_streaming(ov9734); - if (ret) { - ov9734->streaming = false; - ov9734_stop_streaming(ov9734); - } - -exit: - mutex_unlock(&ov9734->mutex); return ret; } @@ -1014,10 +969,6 @@ probe_error_v4l2_ctrl_handler_free: return ret; } -static const struct dev_pm_ops ov9734_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(ov9734_suspend, ov9734_resume) -}; - static const struct acpi_device_id ov9734_acpi_ids[] = { { "OVTI9734", }, {} @@ -1028,7 +979,6 @@ MODULE_DEVICE_TABLE(acpi, ov9734_acpi_ids); static struct i2c_driver ov9734_i2c_driver = { .driver = { .name = "ov9734", - .pm = &ov9734_pm_ops, .acpi_match_table = ov9734_acpi_ids, }, .probe = ov9734_probe, diff --git a/drivers/media/i2c/rdacm20.c b/drivers/media/i2c/rdacm20.c index f4e2e2f397..b4647bda8c 100644 --- a/drivers/media/i2c/rdacm20.c +++ b/drivers/media/i2c/rdacm20.c @@ -625,8 +625,7 @@ error_free_ctrls: v4l2_ctrl_handler_free(&dev->ctrls); error: media_entity_cleanup(&dev->sd.entity); - if (dev->sensor) - i2c_unregister_device(dev->sensor); + i2c_unregister_device(dev->sensor); dev_err(&client->dev, "probe failed\n"); diff --git a/drivers/media/i2c/st-vgxy61.c b/drivers/media/i2c/st-vgxy61.c index 30f82ca344..5dbfb04b31 100644 --- a/drivers/media/i2c/st-vgxy61.c +++ b/drivers/media/i2c/st-vgxy61.c @@ -1170,14 +1170,9 @@ static int vgxy61_stream_enable(struct vgxy61_dev *sensor) if (ret) return ret; - ret = pm_runtime_get_sync(&client->dev); - if (ret < 0) { - pm_runtime_put_autosuspend(&client->dev); + ret = pm_runtime_resume_and_get(&client->dev); + if (ret) return ret; - } - - /* pm_runtime_get_sync() can return 1 as a valid return code */ - ret = 0; vgxy61_write_reg(sensor, VGXY61_REG_FORMAT_CTRL, get_bpp_by_code(sensor->fmt.code), &ret); diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index 566f5eaddd..ce612a47ba 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -784,8 +784,12 @@ static int tc358746_set_fmt(struct v4l2_subdev *sd, sink_fmt = v4l2_subdev_get_pad_format(sd, sd_state, TC358746_SINK); fmt = tc358746_get_format_by_code(format->pad, format->format.code); - if (IS_ERR(fmt)) + if (IS_ERR(fmt)) { fmt = tc358746_get_format_by_code(format->pad, tc358746_def_fmt.code); + // Can't happen, but just in case... + if (WARN_ON(IS_ERR(fmt))) + return -EINVAL; + } format->format.code = fmt->code; format->format.field = V4L2_FIELD_NONE; diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c index aa6d4b67b6..c37f605cb7 100644 --- a/drivers/media/i2c/tvp514x.c +++ b/drivers/media/i2c/tvp514x.c @@ -16,23 +16,24 @@ * Prabhakar Lad <prabhakar.lad@ti.com> */ -#include <linux/i2c.h> -#include <linux/slab.h> #include <linux/delay.h> -#include <linux/videodev2.h> +#include <linux/i2c.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> -#include <linux/v4l2-mediabus.h> #include <linux/of.h> #include <linux/of_graph.h> +#include <linux/slab.h> +#include <linux/v4l2-mediabus.h> +#include <linux/videodev2.h> +#include <media/i2c/tvp514x.h> +#include <media/media-entity.h> #include <media/v4l2-async.h> -#include <media/v4l2-device.h> #include <media/v4l2-common.h> -#include <media/v4l2-mediabus.h> -#include <media/v4l2-fwnode.h> #include <media/v4l2-ctrls.h> -#include <media/i2c/tvp514x.h> -#include <media/media-entity.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-mediabus.h> #include "tvp514x_regs.h" @@ -118,7 +119,7 @@ struct tvp514x_decoder { struct media_pad pad; struct v4l2_mbus_framefmt format; - struct tvp514x_reg *int_seq; + const struct tvp514x_reg *int_seq; }; /* TVP514x default register values */ @@ -1024,7 +1025,6 @@ done: static int tvp514x_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct tvp514x_platform_data *pdata = tvp514x_get_pdata(client); struct tvp514x_decoder *decoder; struct v4l2_subdev *sd; @@ -1049,7 +1049,7 @@ tvp514x_probe(struct i2c_client *client) memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, sizeof(tvp514x_reg_list_default)); - decoder->int_seq = (struct tvp514x_reg *)id->driver_data; + decoder->int_seq = i2c_get_match_data(client); /* Copy board specific information here */ decoder->pdata = pdata; @@ -1183,29 +1183,26 @@ static const struct tvp514x_reg tvp514xm_init_reg_seq[] = { * driver_data - Driver data */ static const struct i2c_device_id tvp514x_id[] = { - {"tvp5146", (unsigned long)tvp5146_init_reg_seq}, - {"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq}, - {"tvp5147", (unsigned long)tvp5147_init_reg_seq}, - {"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq}, - {}, + {"tvp5146", (kernel_ulong_t)tvp5146_init_reg_seq }, + {"tvp5146m2", (kernel_ulong_t)tvp514xm_init_reg_seq }, + {"tvp5147", (kernel_ulong_t)tvp5147_init_reg_seq }, + {"tvp5147m1", (kernel_ulong_t)tvp514xm_init_reg_seq }, + { /* sentinel */ } }; - MODULE_DEVICE_TABLE(i2c, tvp514x_id); -#if IS_ENABLED(CONFIG_OF) static const struct of_device_id tvp514x_of_match[] = { - { .compatible = "ti,tvp5146", }, - { .compatible = "ti,tvp5146m2", }, - { .compatible = "ti,tvp5147", }, - { .compatible = "ti,tvp5147m1", }, - { /* sentinel */ }, + { .compatible = "ti,tvp5146", .data = tvp5146_init_reg_seq }, + { .compatible = "ti,tvp5146m2", .data = tvp514xm_init_reg_seq }, + { .compatible = "ti,tvp5147", .data = tvp5147_init_reg_seq }, + { .compatible = "ti,tvp5147m1", .data = tvp514xm_init_reg_seq }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, tvp514x_of_match); -#endif static struct i2c_driver tvp514x_driver = { .driver = { - .of_match_table = of_match_ptr(tvp514x_of_match), + .of_match_table = tvp514x_of_match, .name = TVP514X_MODULE_NAME, }, .probe = tvp514x_probe, diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c index 537ebd9fa8..178bd06cc2 100644 --- a/drivers/media/i2c/video-i2c.c +++ b/drivers/media/i2c/video-i2c.c @@ -759,7 +759,6 @@ static void video_i2c_release(struct video_device *vdev) static int video_i2c_probe(struct i2c_client *client) { - const struct i2c_device_id *id = i2c_client_get_device_id(client); struct video_i2c_data *data; struct v4l2_device *v4l2_dev; struct vb2_queue *queue; @@ -769,11 +768,8 @@ static int video_i2c_probe(struct i2c_client *client) if (!data) return -ENOMEM; - if (dev_fwnode(&client->dev)) - data->chip = device_get_match_data(&client->dev); - else if (id) - data->chip = &video_i2c_chip[id->driver_data]; - else + data->chip = i2c_get_match_data(client); + if (!data->chip) goto error_free_device; data->regmap = regmap_init_i2c(client, data->chip->regmap_config); @@ -940,8 +936,8 @@ static const struct dev_pm_ops video_i2c_pm_ops = { }; static const struct i2c_device_id video_i2c_id_table[] = { - { "amg88xx", AMG88XX }, - { "mlx90640", MLX90640 }, + { "amg88xx", (kernel_ulong_t)&video_i2c_chip[AMG88XX] }, + { "mlx90640", (kernel_ulong_t)&video_i2c_chip[MLX90640] }, {} }; MODULE_DEVICE_TABLE(i2c, video_i2c_id_table); |