Lines Matching full:gc0308
3 * Driver for the GalaxyCore GC0308 camera sensor.
428 struct gc0308 { struct
452 static inline struct gc0308 *to_gc0308(struct v4l2_subdev *sd) in to_gc0308() argument
454 return container_of(sd, struct gc0308, sd); in to_gc0308()
772 struct gc0308 *gc0308 = dev_get_drvdata(dev); in gc0308_power_on() local
775 ret = regulator_enable(gc0308->vdd); in gc0308_power_on()
779 ret = clk_prepare_enable(gc0308->clk); in gc0308_power_on()
783 gpiod_set_value_cansleep(gc0308->pwdn_gpio, 0); in gc0308_power_on()
786 gpiod_set_value_cansleep(gc0308->reset_gpio, 1); in gc0308_power_on()
788 gpiod_set_value_cansleep(gc0308->reset_gpio, 0); in gc0308_power_on()
794 regulator_disable(gc0308->vdd); in gc0308_power_on()
800 struct gc0308 *gc0308 = dev_get_drvdata(dev); in gc0308_power_off() local
802 gpiod_set_value_cansleep(gc0308->pwdn_gpio, 1); in gc0308_power_off()
803 clk_disable_unprepare(gc0308->clk); in gc0308_power_off()
804 regulator_disable(gc0308->vdd); in gc0308_power_off()
813 struct gc0308 *gc0308 = to_gc0308(sd); in gc0308_g_register() local
815 return cci_read(gc0308->regmap, CCI_REG8(reg->reg), ®->val, NULL); in gc0308_g_register()
821 struct gc0308 *gc0308 = to_gc0308(sd); in gc0308_s_register() local
823 return cci_write(gc0308->regmap, CCI_REG8(reg->reg), reg->val, NULL); in gc0308_s_register()
827 static int gc0308_set_exposure(struct gc0308 *gc0308, enum gc0308_exp_val exp) in gc0308_set_exposure() argument
835 return cci_multi_reg_write(gc0308->regmap, exposure_reg_seq, in gc0308_set_exposure()
839 static int gc0308_set_awb_mode(struct gc0308 *gc0308, in gc0308_set_awb_mode() argument
850 ret = cci_update_bits(gc0308->regmap, GC0308_AAAA_EN, in gc0308_set_awb_mode()
852 ret = cci_multi_reg_write(gc0308->regmap, awb_reg_seq, in gc0308_set_awb_mode()
858 static int gc0308_set_colormode(struct gc0308 *gc0308, enum v4l2_colorfx mode) in gc0308_set_colormode() argument
874 return cci_multi_reg_write(gc0308->regmap, colormode_reg_seq, in gc0308_set_colormode()
878 static int gc0308_set_power_line_freq(struct gc0308 *gc0308, int frequency) in gc0308_set_power_line_freq() argument
897 return cci_multi_reg_write(gc0308->regmap, pwr_line_60hz, in gc0308_set_power_line_freq()
900 return cci_multi_reg_write(gc0308->regmap, pwr_line_50hz, in gc0308_set_power_line_freq()
907 static int gc0308_update_mirror(struct gc0308 *gc0308) in gc0308_update_mirror() argument
911 if (gc0308->vflip->val) in gc0308_update_mirror()
914 if (gc0308->hflip->val) in gc0308_update_mirror()
917 return cci_update_bits(gc0308->regmap, GC0308_CISCTL_MODE1, in gc0308_update_mirror()
921 static int gc0308_update_blanking(struct gc0308 *gc0308) in gc0308_update_blanking() argument
923 u16 vblank = gc0308->vblank->val; in gc0308_update_blanking()
924 u16 hblank = gc0308->hblank->val; in gc0308_update_blanking()
928 cci_write(gc0308->regmap, GC0308_VB_HB, vbhb, &ret); in gc0308_update_blanking()
929 cci_write(gc0308->regmap, GC0308_HBLANK, hblank & 0xff, &ret); in gc0308_update_blanking()
930 cci_write(gc0308->regmap, GC0308_VBLANK, vblank & 0xff, &ret); in gc0308_update_blanking()
937 struct gc0308 *gc0308 = container_of(ctrl->handler, struct gc0308, hdl); in _gc0308_s_ctrl() local
943 return gc0308_update_blanking(gc0308); in _gc0308_s_ctrl()
946 return gc0308_update_mirror(gc0308); in _gc0308_s_ctrl()
948 return cci_update_bits(gc0308->regmap, GC0308_AAAA_EN, in _gc0308_s_ctrl()
951 return gc0308_set_awb_mode(gc0308, ctrl->val); in _gc0308_s_ctrl()
953 return gc0308_set_power_line_freq(gc0308, ctrl->val); in _gc0308_s_ctrl()
955 return gc0308_set_colormode(gc0308, ctrl->val); in _gc0308_s_ctrl()
957 return cci_update_bits(gc0308->regmap, GC0308_DEBUG_MODE2, in _gc0308_s_ctrl()
960 return gc0308_set_exposure(gc0308, ctrl->val); in _gc0308_s_ctrl()
968 struct gc0308 *gc0308 = container_of(ctrl->handler, struct gc0308, hdl); in gc0308_s_ctrl() local
971 if (!pm_runtime_get_if_in_use(gc0308->dev)) in gc0308_s_ctrl()
976 dev_err(gc0308->dev, "failed to set control: %d\n", ret); in gc0308_s_ctrl()
978 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_s_ctrl()
979 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_s_ctrl()
1054 struct gc0308 *gc0308 = to_gc0308(sd); in gc0308_set_format() local
1072 gc0308->mode.out_format = gc0308_formats[i].regval; in gc0308_set_format()
1073 gc0308->mode.subsample = mode->subsample; in gc0308_set_format()
1074 gc0308->mode.width = mode->width; in gc0308_set_format()
1075 gc0308->mode.height = mode->height; in gc0308_set_format()
1105 static int gc0308_set_resolution(struct gc0308 *gc0308, int *ret) in gc0308_set_resolution() argument
1108 {GC0308_SUBSAMPLE, gc0308->mode.subsample}, in gc0308_set_resolution()
1117 {GC0308_CROP_WIN_HEIGHT, gc0308->mode.height}, in gc0308_set_resolution()
1118 {GC0308_CROP_WIN_WIDTH, gc0308->mode.width}, in gc0308_set_resolution()
1121 return cci_multi_reg_write(gc0308->regmap, resolution_regs, in gc0308_set_resolution()
1125 static int gc0308_start_stream(struct gc0308 *gc0308) in gc0308_start_stream() argument
1129 ret = pm_runtime_resume_and_get(gc0308->dev); in gc0308_start_stream()
1133 cci_multi_reg_write(gc0308->regmap, sensor_default_regs, in gc0308_start_stream()
1135 cci_update_bits(gc0308->regmap, GC0308_OUT_FORMAT, in gc0308_start_stream()
1136 GENMASK(4, 0), gc0308->mode.out_format, &ret); in gc0308_start_stream()
1137 gc0308_set_resolution(gc0308, &ret); in gc0308_start_stream()
1140 dev_err(gc0308->dev, "failed to update registers: %d\n", ret); in gc0308_start_stream()
1144 ret = __v4l2_ctrl_handler_setup(&gc0308->hdl); in gc0308_start_stream()
1146 dev_err(gc0308->dev, "failed to setup controls\n"); in gc0308_start_stream()
1152 if (gc0308->mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW) in gc0308_start_stream()
1154 if (gc0308->mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW) in gc0308_start_stream()
1156 ret = cci_write(gc0308->regmap, GC0308_SYNC_MODE, sync_mode, NULL); in gc0308_start_stream()
1163 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_start_stream()
1164 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_start_stream()
1168 static int gc0308_stop_stream(struct gc0308 *gc0308) in gc0308_stop_stream() argument
1170 pm_runtime_mark_last_busy(gc0308->dev); in gc0308_stop_stream()
1171 pm_runtime_put_autosuspend(gc0308->dev); in gc0308_stop_stream()
1177 struct gc0308 *gc0308 = to_gc0308(sd); in gc0308_s_stream() local
1184 ret = gc0308_start_stream(gc0308); in gc0308_s_stream()
1186 ret = gc0308_stop_stream(gc0308); in gc0308_s_stream()
1206 static int gc0308_bus_config(struct gc0308 *gc0308) in gc0308_bus_config() argument
1208 struct device *dev = gc0308->dev; in gc0308_bus_config()
1224 gc0308->mbus_config = bus_cfg.bus.parallel.flags; in gc0308_bus_config()
1235 static int gc0308_init_controls(struct gc0308 *gc0308) in gc0308_init_controls() argument
1239 v4l2_ctrl_handler_init(&gc0308->hdl, 11); in gc0308_init_controls()
1240 gc0308->hblank = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1244 gc0308->vblank = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1248 gc0308->hflip = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1250 gc0308->vflip = v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1252 v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, V4L2_CID_PIXEL_RATE, in gc0308_init_controls()
1255 v4l2_ctrl_new_std(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1257 v4l2_ctrl_new_std_menu_items(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1261 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1264 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1266 v4l2_ctrl_new_std_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1270 v4l2_ctrl_new_int_menu(&gc0308->hdl, &gc0308_ctrl_ops, in gc0308_init_controls()
1276 gc0308->sd.ctrl_handler = &gc0308->hdl; in gc0308_init_controls()
1277 if (gc0308->hdl.error) { in gc0308_init_controls()
1278 ret = gc0308->hdl.error; in gc0308_init_controls()
1279 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_init_controls()
1283 v4l2_ctrl_cluster(2, &gc0308->hflip); in gc0308_init_controls()
1284 v4l2_ctrl_cluster(2, &gc0308->hblank); in gc0308_init_controls()
1292 struct gc0308 *gc0308; in gc0308_probe() local
1297 gc0308 = devm_kzalloc(dev, sizeof(*gc0308), GFP_KERNEL); in gc0308_probe()
1298 if (!gc0308) in gc0308_probe()
1301 gc0308->dev = dev; in gc0308_probe()
1302 dev_set_drvdata(dev, gc0308); in gc0308_probe()
1304 ret = gc0308_bus_config(gc0308); in gc0308_probe()
1308 gc0308->clk = devm_clk_get_optional(dev, NULL); in gc0308_probe()
1309 if (IS_ERR(gc0308->clk)) in gc0308_probe()
1310 return dev_err_probe(dev, PTR_ERR(gc0308->clk), in gc0308_probe()
1313 gc0308->vdd = devm_regulator_get(dev, "vdd28"); in gc0308_probe()
1314 if (IS_ERR(gc0308->vdd)) in gc0308_probe()
1315 return dev_err_probe(dev, PTR_ERR(gc0308->vdd), in gc0308_probe()
1318 gc0308->pwdn_gpio = devm_gpiod_get(dev, "powerdown", GPIOD_OUT_LOW); in gc0308_probe()
1319 if (IS_ERR(gc0308->pwdn_gpio)) in gc0308_probe()
1320 return dev_err_probe(dev, PTR_ERR(gc0308->pwdn_gpio), in gc0308_probe()
1323 gc0308->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in gc0308_probe()
1324 if (IS_ERR(gc0308->reset_gpio)) in gc0308_probe()
1325 return dev_err_probe(dev, PTR_ERR(gc0308->reset_gpio), in gc0308_probe()
1333 gc0308->regmap = devm_regmap_init_i2c(client, &gc0308_regmap_config); in gc0308_probe()
1334 if (IS_ERR(gc0308->regmap)) in gc0308_probe()
1335 return dev_err_probe(dev, PTR_ERR(gc0308->regmap), in gc0308_probe()
1338 v4l2_i2c_subdev_init(&gc0308->sd, client, &gc0308_subdev_ops); in gc0308_probe()
1339 gc0308->sd.internal_ops = &gc0308_internal_ops; in gc0308_probe()
1340 gc0308->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in gc0308_probe()
1341 gc0308->sd.flags |= V4L2_SUBDEV_FL_HAS_EVENTS; in gc0308_probe()
1343 ret = gc0308_init_controls(gc0308); in gc0308_probe()
1347 gc0308->sd.state_lock = gc0308->hdl.lock; in gc0308_probe()
1348 gc0308->pad.flags = MEDIA_PAD_FL_SOURCE; in gc0308_probe()
1349 gc0308->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in gc0308_probe()
1350 ret = media_entity_pads_init(&gc0308->sd.entity, 1, &gc0308->pad); in gc0308_probe()
1354 ret = v4l2_subdev_init_finalize(&gc0308->sd); in gc0308_probe()
1362 if (gc0308->clk) { in gc0308_probe()
1363 clkrate = clk_get_rate(gc0308->clk); in gc0308_probe()
1368 ret = cci_read(gc0308->regmap, GC0308_CHIP_ID, ®val, NULL); in gc0308_probe()
1391 ret = v4l2_async_register_subdev(&gc0308->sd); in gc0308_probe()
1405 v4l2_subdev_cleanup(&gc0308->sd); in gc0308_probe()
1407 media_entity_cleanup(&gc0308->sd.entity); in gc0308_probe()
1409 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_probe()
1415 struct gc0308 *gc0308 = i2c_get_clientdata(client); in gc0308_remove() local
1418 v4l2_async_unregister_subdev(&gc0308->sd); in gc0308_remove()
1419 v4l2_ctrl_handler_free(&gc0308->hdl); in gc0308_remove()
1420 media_entity_cleanup(&gc0308->sd.entity); in gc0308_remove()
1433 { .compatible = "galaxycore,gc0308" },
1440 .name = "gc0308",
1449 MODULE_DESCRIPTION("GalaxyCore GC0308 Camera Driver");