drivers/media/i2c/imx258.c
1016
static int imx258_start_streaming(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1022
ret = cci_write(imx258->regmap, IMX258_REG_RESET, 0x01, NULL);
drivers/media/i2c/imx258.c
1024
dev_err(imx258->dev, "%s failed to reset sensor\n", __func__);
drivers/media/i2c/imx258.c
1032
link_freq_index = imx258->cur_mode->link_freq_index;
drivers/media/i2c/imx258.c
1033
link_freq_cfg = &imx258->link_freq_configs[link_freq_index];
drivers/media/i2c/imx258.c
1035
reg_list = &link_freq_cfg->link_cfg[imx258->lane_mode_idx].reg_list;
drivers/media/i2c/imx258.c
1036
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
drivers/media/i2c/imx258.c
1038
dev_err(imx258->dev, "%s failed to set plls\n", __func__);
drivers/media/i2c/imx258.c
1042
ret = cci_multi_reg_write(imx258->regmap, mode_common_regs,
drivers/media/i2c/imx258.c
1045
dev_err(imx258->dev, "%s failed to set common regs\n", __func__);
drivers/media/i2c/imx258.c
1049
ret = cci_multi_reg_write(imx258->regmap, imx258->variant_cfg->regs,
drivers/media/i2c/imx258.c
1050
imx258->variant_cfg->num_regs, NULL);
drivers/media/i2c/imx258.c
1052
dev_err(imx258->dev, "%s failed to set variant config\n",
drivers/media/i2c/imx258.c
1057
ret = cci_write(imx258->regmap, IMX258_CLK_BLANK_STOP,
drivers/media/i2c/imx258.c
1058
!!(imx258->csi2_flags & V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK),
drivers/media/i2c/imx258.c
1061
dev_err(imx258->dev, "%s failed to set clock lane mode\n", __func__);
drivers/media/i2c/imx258.c
1066
reg_list = &imx258->cur_mode->reg_list;
drivers/media/i2c/imx258.c
1067
ret = cci_multi_reg_write(imx258->regmap, reg_list->regs, reg_list->num_of_regs, NULL);
drivers/media/i2c/imx258.c
1069
dev_err(imx258->dev, "%s failed to set mode\n", __func__);
drivers/media/i2c/imx258.c
1074
ret = __v4l2_ctrl_handler_setup(imx258->sd.ctrl_handler);
drivers/media/i2c/imx258.c
1079
return cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
drivers/media/i2c/imx258.c
1084
static int imx258_stop_streaming(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1089
ret = cci_write(imx258->regmap, IMX258_REG_MODE_SELECT,
drivers/media/i2c/imx258.c
1092
dev_err(imx258->dev, "%s failed to set stream\n", __func__);
drivers/media/i2c/imx258.c
1104
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
1108
imx258->supplies);
drivers/media/i2c/imx258.c
1115
ret = clk_prepare_enable(imx258->clk);
drivers/media/i2c/imx258.c
1118
regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
drivers/media/i2c/imx258.c
1127
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
1129
clk_disable_unprepare(imx258->clk);
drivers/media/i2c/imx258.c
1130
regulator_bulk_disable(IMX258_NUM_SUPPLIES, imx258->supplies);
drivers/media/i2c/imx258.c
1137
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
1140
mutex_lock(&imx258->mutex);
drivers/media/i2c/imx258.c
1143
ret = pm_runtime_resume_and_get(imx258->dev);
drivers/media/i2c/imx258.c
1151
ret = imx258_start_streaming(imx258);
drivers/media/i2c/imx258.c
1155
imx258_stop_streaming(imx258);
drivers/media/i2c/imx258.c
1156
pm_runtime_put(imx258->dev);
drivers/media/i2c/imx258.c
1159
mutex_unlock(&imx258->mutex);
drivers/media/i2c/imx258.c
1164
pm_runtime_put(imx258->dev);
drivers/media/i2c/imx258.c
1166
mutex_unlock(&imx258->mutex);
drivers/media/i2c/imx258.c
1172
static int imx258_identify_module(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1177
ret = cci_read(imx258->regmap, IMX258_REG_CHIP_ID,
drivers/media/i2c/imx258.c
1180
dev_err(imx258->dev, "failed to read chip id %x\n",
drivers/media/i2c/imx258.c
1186
dev_err(imx258->dev, "chip id mismatch: %x!=%llx\n",
drivers/media/i2c/imx258.c
1216
static int imx258_init_controls(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1227
ctrl_hdlr = &imx258->ctrl_handler;
drivers/media/i2c/imx258.c
1232
mutex_init(&imx258->mutex);
drivers/media/i2c/imx258.c
1233
ctrl_hdlr->lock = &imx258->mutex;
drivers/media/i2c/imx258.c
1234
imx258->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
drivers/media/i2c/imx258.c
1239
imx258->link_freq_menu_items);
drivers/media/i2c/imx258.c
1241
if (imx258->link_freq)
drivers/media/i2c/imx258.c
1242
imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
drivers/media/i2c/imx258.c
1244
imx258->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
drivers/media/i2c/imx258.c
1246
if (imx258->hflip)
drivers/media/i2c/imx258.c
1247
imx258->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
drivers/media/i2c/imx258.c
1249
imx258->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
drivers/media/i2c/imx258.c
1251
if (imx258->vflip)
drivers/media/i2c/imx258.c
1252
imx258->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
drivers/media/i2c/imx258.c
1254
link_freq_cfgs = &imx258->link_freq_configs[0];
drivers/media/i2c/imx258.c
1255
link_cfg = link_freq_cfgs[imx258->lane_mode_idx].link_cfg;
drivers/media/i2c/imx258.c
1256
pixel_rate = link_freq_to_pixel_rate(imx258->link_freq_menu_items[0],
drivers/media/i2c/imx258.c
1260
imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
drivers/media/i2c/imx258.c
1265
vblank_def = imx258->cur_mode->vts_def - imx258->cur_mode->height;
drivers/media/i2c/imx258.c
1266
vblank_min = imx258->cur_mode->vts_min - imx258->cur_mode->height;
drivers/media/i2c/imx258.c
1267
imx258->vblank = v4l2_ctrl_new_std(
drivers/media/i2c/imx258.c
1270
IMX258_VTS_MAX - imx258->cur_mode->height, 1,
drivers/media/i2c/imx258.c
1273
imx258->hblank = v4l2_ctrl_new_std(
drivers/media/i2c/imx258.c
1275
IMX258_PPL_DEFAULT - imx258->cur_mode->width,
drivers/media/i2c/imx258.c
1276
IMX258_PPL_DEFAULT - imx258->cur_mode->width,
drivers/media/i2c/imx258.c
1278
IMX258_PPL_DEFAULT - imx258->cur_mode->width);
drivers/media/i2c/imx258.c
1280
if (imx258->hblank)
drivers/media/i2c/imx258.c
1281
imx258->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
drivers/media/i2c/imx258.c
1283
imx258->exposure = v4l2_ctrl_new_std(
drivers/media/i2c/imx258.c
1308
dev_err(imx258->dev, "%s control init failed (%d)\n",
drivers/media/i2c/imx258.c
1313
ret = v4l2_fwnode_device_parse(imx258->dev, &props);
drivers/media/i2c/imx258.c
1322
imx258->sd.ctrl_handler = ctrl_hdlr;
drivers/media/i2c/imx258.c
1328
mutex_destroy(&imx258->mutex);
drivers/media/i2c/imx258.c
1333
static void imx258_free_controls(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1335
v4l2_ctrl_handler_free(imx258->sd.ctrl_handler);
drivers/media/i2c/imx258.c
1336
mutex_destroy(&imx258->mutex);
drivers/media/i2c/imx258.c
1339
static int imx258_get_regulators(struct imx258 *imx258)
drivers/media/i2c/imx258.c
1344
imx258->supplies[i].supply = imx258_supply_name[i];
drivers/media/i2c/imx258.c
1346
return devm_regulator_bulk_get(imx258->dev,
drivers/media/i2c/imx258.c
1347
IMX258_NUM_SUPPLIES, imx258->supplies);
drivers/media/i2c/imx258.c
1352
struct imx258 *imx258;
drivers/media/i2c/imx258.c
1360
imx258 = devm_kzalloc(&client->dev, sizeof(*imx258), GFP_KERNEL);
drivers/media/i2c/imx258.c
1361
if (!imx258)
drivers/media/i2c/imx258.c
1364
imx258->dev = &client->dev;
drivers/media/i2c/imx258.c
1366
imx258->regmap = devm_cci_regmap_init_i2c(client, 16);
drivers/media/i2c/imx258.c
1367
if (IS_ERR(imx258->regmap)) {
drivers/media/i2c/imx258.c
1368
ret = PTR_ERR(imx258->regmap);
drivers/media/i2c/imx258.c
1369
dev_err(imx258->dev, "failed to initialize CCI: %d\n", ret);
drivers/media/i2c/imx258.c
1373
ret = imx258_get_regulators(imx258);
drivers/media/i2c/imx258.c
1375
return dev_err_probe(imx258->dev, ret,
drivers/media/i2c/imx258.c
1378
imx258->clk = devm_v4l2_sensor_clk_get_legacy(imx258->dev, NULL, false,
drivers/media/i2c/imx258.c
1380
if (IS_ERR(imx258->clk))
drivers/media/i2c/imx258.c
1381
return dev_err_probe(imx258->dev, PTR_ERR(imx258->clk),
drivers/media/i2c/imx258.c
1384
val = clk_get_rate(imx258->clk);
drivers/media/i2c/imx258.c
1388
imx258->link_freq_configs = link_freq_configs_19_2;
drivers/media/i2c/imx258.c
1389
imx258->link_freq_menu_items = link_freq_menu_items_19_2;
drivers/media/i2c/imx258.c
1392
imx258->link_freq_configs = link_freq_configs_24;
drivers/media/i2c/imx258.c
1393
imx258->link_freq_menu_items = link_freq_menu_items_24;
drivers/media/i2c/imx258.c
1396
dev_err(imx258->dev, "input clock frequency of %u not supported\n",
drivers/media/i2c/imx258.c
1401
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx258->dev), NULL);
drivers/media/i2c/imx258.c
1403
dev_err(imx258->dev, "Endpoint node not found\n");
drivers/media/i2c/imx258.c
1410
dev_err(imx258->dev, "Parsing endpoint node failed\n");
drivers/media/i2c/imx258.c
1414
ret = v4l2_link_freq_to_bitmap(imx258->dev,
drivers/media/i2c/imx258.c
1417
imx258->link_freq_menu_items,
drivers/media/i2c/imx258.c
1419
&imx258->link_freq_bitmap);
drivers/media/i2c/imx258.c
1421
dev_err(imx258->dev, "Link frequency not supported\n");
drivers/media/i2c/imx258.c
1428
imx258->lane_mode_idx = IMX258_2_LANE_MODE;
drivers/media/i2c/imx258.c
1431
imx258->lane_mode_idx = IMX258_4_LANE_MODE;
drivers/media/i2c/imx258.c
1434
dev_err(imx258->dev, "Invalid data lanes: %u\n",
drivers/media/i2c/imx258.c
1440
imx258->csi2_flags = ep.bus.mipi_csi2.flags;
drivers/media/i2c/imx258.c
1442
imx258->variant_cfg = device_get_match_data(imx258->dev);
drivers/media/i2c/imx258.c
1443
if (!imx258->variant_cfg)
drivers/media/i2c/imx258.c
1444
imx258->variant_cfg = &imx258_cfg;
drivers/media/i2c/imx258.c
1447
v4l2_i2c_subdev_init(&imx258->sd, client, &imx258_subdev_ops);
drivers/media/i2c/imx258.c
1450
ret = imx258_power_on(imx258->dev);
drivers/media/i2c/imx258.c
1455
ret = imx258_identify_module(imx258);
drivers/media/i2c/imx258.c
1460
imx258->cur_mode = &supported_modes[0];
drivers/media/i2c/imx258.c
1462
ret = imx258_init_controls(imx258);
drivers/media/i2c/imx258.c
1467
imx258->sd.internal_ops = &imx258_internal_ops;
drivers/media/i2c/imx258.c
1468
imx258->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
drivers/media/i2c/imx258.c
1469
imx258->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
drivers/media/i2c/imx258.c
1472
imx258->pad.flags = MEDIA_PAD_FL_SOURCE;
drivers/media/i2c/imx258.c
1474
ret = media_entity_pads_init(&imx258->sd.entity, 1, &imx258->pad);
drivers/media/i2c/imx258.c
1478
ret = v4l2_async_register_subdev_sensor(&imx258->sd);
drivers/media/i2c/imx258.c
1482
pm_runtime_set_active(imx258->dev);
drivers/media/i2c/imx258.c
1483
pm_runtime_enable(imx258->dev);
drivers/media/i2c/imx258.c
1484
pm_runtime_idle(imx258->dev);
drivers/media/i2c/imx258.c
1490
media_entity_cleanup(&imx258->sd.entity);
drivers/media/i2c/imx258.c
1493
imx258_free_controls(imx258);
drivers/media/i2c/imx258.c
1496
imx258_power_off(imx258->dev);
drivers/media/i2c/imx258.c
1507
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
1511
imx258_free_controls(imx258);
drivers/media/i2c/imx258.c
1513
pm_runtime_disable(imx258->dev);
drivers/media/i2c/imx258.c
1514
if (!pm_runtime_status_suspended(imx258->dev))
drivers/media/i2c/imx258.c
1515
imx258_power_off(imx258->dev);
drivers/media/i2c/imx258.c
1516
pm_runtime_set_suspended(imx258->dev);
drivers/media/i2c/imx258.c
686
static inline struct imx258 *to_imx258(struct v4l2_subdev *_sd)
drivers/media/i2c/imx258.c
688
return container_of(_sd, struct imx258, sd);
drivers/media/i2c/imx258.c
692
static u32 imx258_get_format_code(const struct imx258 *imx258)
drivers/media/i2c/imx258.c
696
lockdep_assert_held(&imx258->mutex);
drivers/media/i2c/imx258.c
698
i = (imx258->vflip->val ? 2 : 0) |
drivers/media/i2c/imx258.c
699
(imx258->hflip->val ? 1 : 0);
drivers/media/i2c/imx258.c
707
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
715
try_fmt->code = imx258_get_format_code(imx258);
drivers/media/i2c/imx258.c
728
static int imx258_update_digital_gain(struct imx258 *imx258, u32 val)
drivers/media/i2c/imx258.c
732
cci_write(imx258->regmap, IMX258_REG_GR_DIGITAL_GAIN, val, &ret);
drivers/media/i2c/imx258.c
733
cci_write(imx258->regmap, IMX258_REG_GB_DIGITAL_GAIN, val, &ret);
drivers/media/i2c/imx258.c
734
cci_write(imx258->regmap, IMX258_REG_R_DIGITAL_GAIN, val, &ret);
drivers/media/i2c/imx258.c
735
cci_write(imx258->regmap, IMX258_REG_B_DIGITAL_GAIN, val, &ret);
drivers/media/i2c/imx258.c
740
static void imx258_adjust_exposure_range(struct imx258 *imx258)
drivers/media/i2c/imx258.c
745
exposure_max = imx258->cur_mode->height + imx258->vblank->val -
drivers/media/i2c/imx258.c
747
exposure_def = min(exposure_max, imx258->exposure->val);
drivers/media/i2c/imx258.c
748
__v4l2_ctrl_modify_range(imx258->exposure, imx258->exposure->minimum,
drivers/media/i2c/imx258.c
749
exposure_max, imx258->exposure->step,
drivers/media/i2c/imx258.c
755
struct imx258 *imx258 =
drivers/media/i2c/imx258.c
756
container_of(ctrl->handler, struct imx258, ctrl_handler);
drivers/media/i2c/imx258.c
764
imx258_adjust_exposure_range(imx258);
drivers/media/i2c/imx258.c
770
if (pm_runtime_get_if_in_use(imx258->dev) == 0)
drivers/media/i2c/imx258.c
775
ret = cci_write(imx258->regmap, IMX258_REG_ANALOG_GAIN,
drivers/media/i2c/imx258.c
779
ret = cci_write(imx258->regmap, IMX258_REG_EXPOSURE,
drivers/media/i2c/imx258.c
783
ret = imx258_update_digital_gain(imx258, ctrl->val);
drivers/media/i2c/imx258.c
786
ret = cci_write(imx258->regmap, IMX258_REG_TEST_PATTERN,
drivers/media/i2c/imx258.c
791
ret = cci_write(imx258->regmap, IMX258_REG_HDR,
drivers/media/i2c/imx258.c
794
ret = cci_write(imx258->regmap, IMX258_REG_HDR,
drivers/media/i2c/imx258.c
798
ret = cci_write(imx258->regmap, IMX258_REG_HDR_RATIO,
drivers/media/i2c/imx258.c
803
ret = cci_write(imx258->regmap, IMX258_REG_FRM_LENGTH_LINES,
drivers/media/i2c/imx258.c
804
imx258->cur_mode->height + ctrl->val, NULL);
drivers/media/i2c/imx258.c
808
ret = cci_write(imx258->regmap, REG_MIRROR_FLIP_CONTROL,
drivers/media/i2c/imx258.c
809
(imx258->hflip->val ?
drivers/media/i2c/imx258.c
811
(imx258->vflip->val ?
drivers/media/i2c/imx258.c
816
dev_info(imx258->dev,
drivers/media/i2c/imx258.c
823
pm_runtime_put(imx258->dev);
drivers/media/i2c/imx258.c
836
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
842
code->code = imx258_get_format_code(imx258);
drivers/media/i2c/imx258.c
851
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
855
if (fse->code != imx258_get_format_code(imx258))
drivers/media/i2c/imx258.c
866
static void imx258_update_pad_format(struct imx258 *imx258,
drivers/media/i2c/imx258.c
872
fmt->format.code = imx258_get_format_code(imx258);
drivers/media/i2c/imx258.c
876
static int __imx258_get_pad_format(struct imx258 *imx258,
drivers/media/i2c/imx258.c
884
imx258_update_pad_format(imx258, imx258->cur_mode, fmt);
drivers/media/i2c/imx258.c
893
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
896
mutex_lock(&imx258->mutex);
drivers/media/i2c/imx258.c
897
ret = __imx258_get_pad_format(imx258, sd_state, fmt);
drivers/media/i2c/imx258.c
898
mutex_unlock(&imx258->mutex);
drivers/media/i2c/imx258.c
907
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
918
mutex_lock(&imx258->mutex);
drivers/media/i2c/imx258.c
920
fmt->format.code = imx258_get_format_code(imx258);
drivers/media/i2c/imx258.c
925
imx258_update_pad_format(imx258, mode, fmt);
drivers/media/i2c/imx258.c
930
imx258->cur_mode = mode;
drivers/media/i2c/imx258.c
931
__v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
drivers/media/i2c/imx258.c
933
link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
drivers/media/i2c/imx258.c
935
&imx258->link_freq_configs[mode->link_freq_index];
drivers/media/i2c/imx258.c
937
link_cfg = &link_freq_cfgs->link_cfg[imx258->lane_mode_idx];
drivers/media/i2c/imx258.c
939
__v4l2_ctrl_modify_range(imx258->pixel_rate, pixel_rate,
drivers/media/i2c/imx258.c
942
vblank_def = imx258->cur_mode->vts_def -
drivers/media/i2c/imx258.c
943
imx258->cur_mode->height;
drivers/media/i2c/imx258.c
944
vblank_min = imx258->cur_mode->vts_min -
drivers/media/i2c/imx258.c
945
imx258->cur_mode->height;
drivers/media/i2c/imx258.c
947
imx258->vblank, vblank_min,
drivers/media/i2c/imx258.c
948
IMX258_VTS_MAX - imx258->cur_mode->height, 1,
drivers/media/i2c/imx258.c
950
__v4l2_ctrl_s_ctrl(imx258->vblank, vblank_def);
drivers/media/i2c/imx258.c
952
imx258->link_freq_configs[mode->link_freq_index].pixels_per_line
drivers/media/i2c/imx258.c
953
- imx258->cur_mode->width;
drivers/media/i2c/imx258.c
954
__v4l2_ctrl_modify_range(imx258->hblank, h_blank,
drivers/media/i2c/imx258.c
958
mutex_unlock(&imx258->mutex);
drivers/media/i2c/imx258.c
964
__imx258_get_pad_crop(struct imx258 *imx258,
drivers/media/i2c/imx258.c
972
return &imx258->cur_mode->crop;
drivers/media/i2c/imx258.c
984
struct imx258 *imx258 = to_imx258(sd);
drivers/media/i2c/imx258.c
986
mutex_lock(&imx258->mutex);
drivers/media/i2c/imx258.c
987
sel->r = *__imx258_get_pad_crop(imx258, sd_state, sel->pad,
drivers/media/i2c/imx258.c
989
mutex_unlock(&imx258->mutex);