drivers/media/i2c/ov9650.c
1054
ov965x->sd.ctrl_handler = hdl;
drivers/media/i2c/ov9650.c
1108
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1117
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1118
fi->interval = ov965x->fiv->interval;
drivers/media/i2c/ov9650.c
1119
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1124
static int __ov965x_set_frame_interval(struct ov965x *ov965x,
drivers/media/i2c/ov9650.c
1127
struct v4l2_mbus_framefmt *mbus_fmt = &ov965x->format;
drivers/media/i2c/ov9650.c
1151
ov965x->fiv = fiv;
drivers/media/i2c/ov9650.c
1153
v4l2_dbg(1, debug, &ov965x->sd, "Changed frame interval to %u us\n",
drivers/media/i2c/ov9650.c
1163
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1176
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1177
ret = __ov965x_set_frame_interval(ov965x, fi);
drivers/media/i2c/ov9650.c
1178
ov965x->apply_frame_fmt = 1;
drivers/media/i2c/ov9650.c
1179
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1187
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1196
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1197
fmt->format = ov965x->format;
drivers/media/i2c/ov9650.c
1198
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1234
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1248
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1256
if (ov965x->streaming) {
drivers/media/i2c/ov9650.c
1259
ov965x->frame_size = size;
drivers/media/i2c/ov9650.c
1260
ov965x->format = fmt->format;
drivers/media/i2c/ov9650.c
1261
ov965x->tslb_reg = ov965x_formats[index].tslb_reg;
drivers/media/i2c/ov9650.c
1262
ov965x->apply_frame_fmt = 1;
drivers/media/i2c/ov9650.c
1271
__ov965x_set_frame_interval(ov965x, &fiv);
drivers/media/i2c/ov9650.c
1273
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1276
ov965x_update_exposure_ctrl(ov965x);
drivers/media/i2c/ov9650.c
1281
static int ov965x_set_frame_size(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
1286
ret = ov965x_write(ov965x, frame_size_reg_addr[i],
drivers/media/i2c/ov9650.c
1287
ov965x->frame_size->regs[i]);
drivers/media/i2c/ov9650.c
1291
static int __ov965x_set_params(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
1293
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
drivers/media/i2c/ov9650.c
1297
if (ov965x->apply_frame_fmt) {
drivers/media/i2c/ov9650.c
1298
reg = DEF_CLKRC + ov965x->fiv->clkrc_div;
drivers/media/i2c/ov9650.c
1299
ret = ov965x_write(ov965x, REG_CLKRC, reg);
drivers/media/i2c/ov9650.c
1302
ret = ov965x_set_frame_size(ov965x);
drivers/media/i2c/ov9650.c
1305
ret = ov965x_read(ov965x, REG_TSLB, ®);
drivers/media/i2c/ov9650.c
1309
reg |= ov965x->tslb_reg;
drivers/media/i2c/ov9650.c
1310
ret = ov965x_write(ov965x, REG_TSLB, reg);
drivers/media/i2c/ov9650.c
1314
ret = ov965x_set_default_gamma_curve(ov965x);
drivers/media/i2c/ov9650.c
1317
ret = ov965x_set_color_matrix(ov965x);
drivers/media/i2c/ov9650.c
1324
ret = ov965x_read(ov965x, REG_COM11, ®);
drivers/media/i2c/ov9650.c
1327
ret = ov965x_write(ov965x, REG_COM11, reg);
drivers/media/i2c/ov9650.c
1334
return ov965x_set_banding_filter(ov965x, ctrls->light_freq->val);
drivers/media/i2c/ov9650.c
1339
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1340
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
drivers/media/i2c/ov9650.c
1345
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1346
if (ov965x->streaming == !on) {
drivers/media/i2c/ov9650.c
1348
ret = __ov965x_set_params(ov965x);
drivers/media/i2c/ov9650.c
1355
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1358
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1363
ret = ov965x_write(ov965x, REG_COM2,
drivers/media/i2c/ov9650.c
1367
ov965x->streaming += on ? 1 : -1;
drivers/media/i2c/ov9650.c
1369
WARN_ON(ov965x->streaming < 0);
drivers/media/i2c/ov9650.c
1370
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1418
static int ov965x_configure_gpios(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
1420
struct device *dev = regmap_get_device(ov965x->regmap);
drivers/media/i2c/ov9650.c
1422
ov965x->gpios[GPIO_PWDN] = devm_gpiod_get_optional(dev, "powerdown",
drivers/media/i2c/ov9650.c
1424
if (IS_ERR(ov965x->gpios[GPIO_PWDN])) {
drivers/media/i2c/ov9650.c
1426
return PTR_ERR(ov965x->gpios[GPIO_PWDN]);
drivers/media/i2c/ov9650.c
1429
ov965x->gpios[GPIO_RST] = devm_gpiod_get_optional(dev, "reset",
drivers/media/i2c/ov9650.c
1431
if (IS_ERR(ov965x->gpios[GPIO_RST])) {
drivers/media/i2c/ov9650.c
1433
return PTR_ERR(ov965x->gpios[GPIO_RST]);
drivers/media/i2c/ov9650.c
1441
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1445
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1446
ret = __ov965x_set_power(ov965x, 1);
drivers/media/i2c/ov9650.c
1453
ret = ov965x_read(ov965x, REG_PID, &pid);
drivers/media/i2c/ov9650.c
1455
ret = ov965x_read(ov965x, REG_VER, &ver);
drivers/media/i2c/ov9650.c
1457
__ov965x_set_power(ov965x, 0);
drivers/media/i2c/ov9650.c
1460
ov965x->id = OV965X_ID(pid, ver);
drivers/media/i2c/ov9650.c
1461
if (ov965x->id == OV9650_ID || ov965x->id == OV9652_ID) {
drivers/media/i2c/ov9650.c
1462
v4l2_info(sd, "Found OV%04X sensor\n", ov965x->id);
drivers/media/i2c/ov9650.c
1465
ov965x->id);
drivers/media/i2c/ov9650.c
1470
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
1478
struct ov965x *ov965x;
drivers/media/i2c/ov9650.c
1486
ov965x = devm_kzalloc(&client->dev, sizeof(*ov965x), GFP_KERNEL);
drivers/media/i2c/ov9650.c
1487
if (!ov965x)
drivers/media/i2c/ov9650.c
1490
ov965x->regmap = devm_regmap_init_sccb(client, &ov965x_regmap_config);
drivers/media/i2c/ov9650.c
1491
if (IS_ERR(ov965x->regmap)) {
drivers/media/i2c/ov9650.c
1493
return PTR_ERR(ov965x->regmap);
drivers/media/i2c/ov9650.c
1497
ov965x->clk = devm_v4l2_sensor_clk_get(&client->dev, NULL);
drivers/media/i2c/ov9650.c
1498
if (IS_ERR(ov965x->clk))
drivers/media/i2c/ov9650.c
1499
return dev_err_probe(&client->dev, PTR_ERR(ov965x->clk),
drivers/media/i2c/ov9650.c
1501
ov965x->mclk_frequency = clk_get_rate(ov965x->clk);
drivers/media/i2c/ov9650.c
1503
ret = ov965x_configure_gpios(ov965x);
drivers/media/i2c/ov9650.c
1513
mutex_init(&ov965x->lock);
drivers/media/i2c/ov9650.c
1515
sd = &ov965x->sd;
drivers/media/i2c/ov9650.c
1523
ov965x->pad.flags = MEDIA_PAD_FL_SOURCE;
drivers/media/i2c/ov9650.c
1525
ret = media_entity_pads_init(&sd->entity, 1, &ov965x->pad);
drivers/media/i2c/ov9650.c
1529
ret = ov965x_initialize_controls(ov965x);
drivers/media/i2c/ov9650.c
1533
ov965x_get_default_format(&ov965x->format);
drivers/media/i2c/ov9650.c
1534
ov965x->frame_size = &ov965x_framesizes[0];
drivers/media/i2c/ov9650.c
1535
ov965x->fiv = &ov965x_intervals[0];
drivers/media/i2c/ov9650.c
1542
ov965x_update_exposure_ctrl(ov965x);
drivers/media/i2c/ov9650.c
1554
mutex_destroy(&ov965x->lock);
drivers/media/i2c/ov9650.c
1561
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
1566
mutex_destroy(&ov965x->lock);
drivers/media/i2c/ov9650.c
415
return &container_of(ctrl->handler, struct ov965x, ctrls.handler)->sd;
drivers/media/i2c/ov9650.c
418
static inline struct ov965x *to_ov965x(struct v4l2_subdev *sd)
drivers/media/i2c/ov9650.c
420
return container_of(sd, struct ov965x, sd);
drivers/media/i2c/ov9650.c
423
static int ov965x_read(struct ov965x *ov965x, u8 addr, u8 *val)
drivers/media/i2c/ov9650.c
428
ret = regmap_read(ov965x->regmap, addr, &buf);
drivers/media/i2c/ov9650.c
434
v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02x. (%d)\n",
drivers/media/i2c/ov9650.c
440
static int ov965x_write(struct ov965x *ov965x, u8 addr, u8 val)
drivers/media/i2c/ov9650.c
444
ret = regmap_write(ov965x->regmap, addr, val);
drivers/media/i2c/ov9650.c
446
v4l2_dbg(2, debug, &ov965x->sd, "%s: 0x%02x @ 0x%02X (%d)\n",
drivers/media/i2c/ov9650.c
452
static int ov965x_write_array(struct ov965x *ov965x,
drivers/media/i2c/ov9650.c
458
ret = ov965x_write(ov965x, regs[i].addr, regs[i].value);
drivers/media/i2c/ov9650.c
463
static int ov965x_set_default_gamma_curve(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
476
int ret = ov965x_write(ov965x, addr, gamma_curve[i]);
drivers/media/i2c/ov9650.c
486
static int ov965x_set_color_matrix(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
496
int ret = ov965x_write(ov965x, addr, mtx[i]);
drivers/media/i2c/ov9650.c
506
static int __ov965x_set_power(struct ov965x *ov965x, int on)
drivers/media/i2c/ov9650.c
509
int ret = clk_prepare_enable(ov965x->clk);
drivers/media/i2c/ov9650.c
514
gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 0);
drivers/media/i2c/ov9650.c
515
gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 0);
drivers/media/i2c/ov9650.c
518
gpiod_set_value_cansleep(ov965x->gpios[GPIO_RST], 1);
drivers/media/i2c/ov9650.c
519
gpiod_set_value_cansleep(ov965x->gpios[GPIO_PWDN], 1);
drivers/media/i2c/ov9650.c
521
clk_disable_unprepare(ov965x->clk);
drivers/media/i2c/ov9650.c
524
ov965x->streaming = 0;
drivers/media/i2c/ov9650.c
531
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
536
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
537
if (ov965x->power == !on) {
drivers/media/i2c/ov9650.c
538
ret = __ov965x_set_power(ov965x, on);
drivers/media/i2c/ov9650.c
540
ret = ov965x_write_array(ov965x,
drivers/media/i2c/ov9650.c
542
ov965x->apply_frame_fmt = 1;
drivers/media/i2c/ov9650.c
543
ov965x->ctrls.update = 1;
drivers/media/i2c/ov9650.c
547
ov965x->power += on ? 1 : -1;
drivers/media/i2c/ov9650.c
549
WARN_ON(ov965x->power < 0);
drivers/media/i2c/ov9650.c
550
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
558
static void ov965x_update_exposure_ctrl(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
560
struct v4l2_ctrl *ctrl = ov965x->ctrls.exposure;
drivers/media/i2c/ov9650.c
565
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
566
if (WARN_ON(!ctrl || !ov965x->frame_size)) {
drivers/media/i2c/ov9650.c
567
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
570
clkrc = DEF_CLKRC + ov965x->fiv->clkrc_div;
drivers/media/i2c/ov9650.c
572
fint = ov965x->mclk_frequency * ((clkrc >> 7) + 1) /
drivers/media/i2c/ov9650.c
576
max = ov965x->frame_size->max_exp_lines * trow;
drivers/media/i2c/ov9650.c
577
ov965x->exp_row_interval = trow;
drivers/media/i2c/ov9650.c
578
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
580
v4l2_dbg(1, debug, &ov965x->sd, "clkrc: %#x, fi: %lu, tr: %lu, %d\n",
drivers/media/i2c/ov9650.c
589
v4l2_err(&ov965x->sd, "Exposure ctrl range update failed\n");
drivers/media/i2c/ov9650.c
592
static int ov965x_set_banding_filter(struct ov965x *ov965x, int value)
drivers/media/i2c/ov9650.c
598
ret = ov965x_read(ov965x, REG_COM8, ®);
drivers/media/i2c/ov9650.c
604
ret = ov965x_write(ov965x, REG_COM8, reg);
drivers/media/i2c/ov9650.c
608
if (WARN_ON(!ov965x->fiv))
drivers/media/i2c/ov9650.c
615
mbd = (1000UL * ov965x->fiv->interval.denominator *
drivers/media/i2c/ov9650.c
616
ov965x->frame_size->max_exp_lines) /
drivers/media/i2c/ov9650.c
617
ov965x->fiv->interval.numerator;
drivers/media/i2c/ov9650.c
620
return ov965x_write(ov965x, REG_MBD, mbd);
drivers/media/i2c/ov9650.c
623
static int ov965x_set_white_balance(struct ov965x *ov965x, int awb)
drivers/media/i2c/ov9650.c
628
ret = ov965x_read(ov965x, REG_COM8, ®);
drivers/media/i2c/ov9650.c
631
ret = ov965x_write(ov965x, REG_COM8, reg);
drivers/media/i2c/ov9650.c
634
ret = ov965x_write(ov965x, REG_BLUE,
drivers/media/i2c/ov9650.c
635
ov965x->ctrls.blue_balance->val);
drivers/media/i2c/ov9650.c
638
ret = ov965x_write(ov965x, REG_RED,
drivers/media/i2c/ov9650.c
639
ov965x->ctrls.red_balance->val);
drivers/media/i2c/ov9650.c
647
static int ov965x_set_brightness(struct ov965x *ov965x, int val)
drivers/media/i2c/ov9650.c
666
ret = ov965x_write(ov965x, regs[0][i],
drivers/media/i2c/ov9650.c
671
static int ov965x_set_gain(struct ov965x *ov965x, int auto_gain)
drivers/media/i2c/ov9650.c
673
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
drivers/media/i2c/ov9650.c
681
ret = ov965x_read(ov965x, REG_COM8, ®);
drivers/media/i2c/ov9650.c
688
ret = ov965x_write(ov965x, REG_COM8, reg);
drivers/media/i2c/ov9650.c
712
ret = ov965x_write(ov965x, REG_GAIN, rgain & 0xff);
drivers/media/i2c/ov9650.c
715
ret = ov965x_read(ov965x, REG_VREF, ®);
drivers/media/i2c/ov9650.c
720
ret = ov965x_write(ov965x, REG_VREF, reg);
drivers/media/i2c/ov9650.c
730
static int ov965x_set_sharpness(struct ov965x *ov965x, unsigned int value)
drivers/media/i2c/ov9650.c
735
ret = ov965x_read(ov965x, REG_COM14, &com14);
drivers/media/i2c/ov9650.c
738
ret = ov965x_read(ov965x, REG_EDGE, &edge);
drivers/media/i2c/ov9650.c
749
ret = ov965x_write(ov965x, REG_COM14, com14);
drivers/media/i2c/ov9650.c
756
return ov965x_write(ov965x, REG_EDGE, edge);
drivers/media/i2c/ov9650.c
759
static int ov965x_set_exposure(struct ov965x *ov965x, int exp)
drivers/media/i2c/ov9650.c
761
struct ov965x_ctrls *ctrls = &ov965x->ctrls;
drivers/media/i2c/ov9650.c
767
ret = ov965x_read(ov965x, REG_COM8, ®);
drivers/media/i2c/ov9650.c
774
ret = ov965x_write(ov965x, REG_COM8, reg);
drivers/media/i2c/ov9650.c
781
/ ov965x->exp_row_interval;
drivers/media/i2c/ov9650.c
786
ret = ov965x_write(ov965x, REG_COM1, exposure & 0x3);
drivers/media/i2c/ov9650.c
788
ret = ov965x_write(ov965x, REG_AECH,
drivers/media/i2c/ov9650.c
791
ret = ov965x_write(ov965x, REG_AECHM,
drivers/media/i2c/ov9650.c
794
ctrls->exposure->val = ((exposure * ov965x->exp_row_interval)
drivers/media/i2c/ov9650.c
800
v4l2_ctrl_activate(ov965x->ctrls.brightness, !exp);
drivers/media/i2c/ov9650.c
804
static int ov965x_set_flip(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
808
if (ov965x->ctrls.hflip->val)
drivers/media/i2c/ov9650.c
811
if (ov965x->ctrls.vflip->val)
drivers/media/i2c/ov9650.c
814
return ov965x_write(ov965x, REG_MVFP, mvfp);
drivers/media/i2c/ov9650.c
820
static int ov965x_set_saturation(struct ov965x *ov965x, int val)
drivers/media/i2c/ov9650.c
838
ret = ov965x_write(ov965x, addr + i, regs[val][i]);
drivers/media/i2c/ov9650.c
843
static int ov965x_set_test_pattern(struct ov965x *ov965x, int value)
drivers/media/i2c/ov9650.c
848
ret = ov965x_read(ov965x, REG_COM23, ®);
drivers/media/i2c/ov9650.c
852
return ov965x_write(ov965x, REG_COM23, reg);
drivers/media/i2c/ov9650.c
855
static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
drivers/media/i2c/ov9650.c
861
if (!ov965x->power)
drivers/media/i2c/ov9650.c
868
ret = ov965x_read(ov965x, REG_GAIN, ®0);
drivers/media/i2c/ov9650.c
871
ret = ov965x_read(ov965x, REG_VREF, ®1);
drivers/media/i2c/ov9650.c
876
ov965x->ctrls.gain->val = m * (16 + (gain & 0xf));
drivers/media/i2c/ov9650.c
882
ret = ov965x_read(ov965x, REG_COM1, ®0);
drivers/media/i2c/ov9650.c
885
ret = ov965x_read(ov965x, REG_AECH, ®1);
drivers/media/i2c/ov9650.c
888
ret = ov965x_read(ov965x, REG_AECHM, ®2);
drivers/media/i2c/ov9650.c
893
ov965x->ctrls.exposure->val = ((exposure *
drivers/media/i2c/ov9650.c
894
ov965x->exp_row_interval) + 50) / 100;
drivers/media/i2c/ov9650.c
904
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
909
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
910
ret = __g_volatile_ctrl(ov965x, ctrl);
drivers/media/i2c/ov9650.c
911
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
918
struct ov965x *ov965x = to_ov965x(sd);
drivers/media/i2c/ov9650.c
922
ctrl->name, ctrl->val, ov965x->power);
drivers/media/i2c/ov9650.c
924
mutex_lock(&ov965x->lock);
drivers/media/i2c/ov9650.c
929
if (ov965x->power == 0) {
drivers/media/i2c/ov9650.c
930
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
936
ret = ov965x_set_white_balance(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
940
ret = ov965x_set_brightness(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
944
ret = ov965x_set_exposure(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
948
ret = ov965x_set_gain(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
952
ret = ov965x_set_flip(ov965x);
drivers/media/i2c/ov9650.c
956
ret = ov965x_set_banding_filter(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
960
ret = ov965x_set_saturation(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
964
ret = ov965x_set_sharpness(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
968
ret = ov965x_set_test_pattern(ov965x, ctrl->val);
drivers/media/i2c/ov9650.c
972
mutex_unlock(&ov965x->lock);
drivers/media/i2c/ov9650.c
986
static int ov965x_initialize_controls(struct ov965x *ov965x)
drivers/media/i2c/ov9650.c
989
struct ov965x_ctrls *ctrls = &ov965x->ctrls;