hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/media/i2c/os02k10.c
....@@ -47,7 +47,7 @@
4747
4848 #define OS02K10_XVCLK_FREQ 24000000
4949
50
-#define CHIP_ID 0x530243
50
+#define CHIP_ID 0x005302
5151 #define OS02K10_REG_CHIP_ID 0x300a
5252
5353 #define OS02K10_REG_CTRL_MODE 0x0100
....@@ -1806,6 +1806,7 @@
18061806 s64 max;
18071807 int ret = 0;
18081808 u32 val = 0;
1809
+ u32 reg_data;
18091810
18101811 /* Propagate change of current control to all related controls */
18111812 switch (ctrl->id) {
....@@ -1835,23 +1836,53 @@
18351836 }
18361837 break;
18371838 case V4L2_CID_ANALOGUE_GAIN:
1839
+ /*
1840
+ * dgain reg format is 4.10bits, again reg format is 4.4bits
1841
+ * 1x is 64, 6 decimal places
1842
+ */
18381843 if (ctrl->val > 992) {
1839
- dgain = ctrl->val * 1024 / 992;
1844
+ dgain = ctrl->val * 1024 / 992; //15.5X * 64 = 992
18401845 again = 992;
18411846 } else {
1842
- dgain = 1024;
1847
+ dgain = 1024; //move 10 bits left
18431848 again = ctrl->val;
18441849 }
18451850 dev_dbg(&client->dev, "gain %d, ag 0x%x, dg 0x%x\n",
18461851 ctrl->val, again, dgain);
1847
- ret = os02k10_write_reg(os02k10->client,
1852
+
1853
+ ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_H,
1854
+ OS02K10_REG_VALUE_08BIT, &reg_data);
1855
+ reg_data = reg_data & 0xf0;
1856
+ ret |= os02k10_write_reg(os02k10->client,
18481857 OS02K10_AEC_LONG_REL_GAIN_REG_H,
1849
- OS02K10_REG_VALUE_16BIT,
1850
- (again << 2) & 0xff0);
1858
+ OS02K10_REG_VALUE_08BIT,
1859
+ ((again >> 6) & 0x0f) | reg_data);
1860
+ ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_REL_GAIN_REG_L,
1861
+ OS02K10_REG_VALUE_08BIT, &reg_data);
1862
+ reg_data = reg_data & 0x0f;
1863
+ ret |= os02k10_write_reg(os02k10->client,
1864
+ OS02K10_AEC_LONG_REL_GAIN_REG_L,
1865
+ OS02K10_REG_VALUE_08BIT,
1866
+ (((again >> 2) & 0x0f) << 4) | reg_data);
1867
+
1868
+ ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_H,
1869
+ OS02K10_REG_VALUE_08BIT, &reg_data);
1870
+ reg_data = reg_data & 0xf0;
18511871 ret |= os02k10_write_reg(os02k10->client,
18521872 OS02K10_AEC_LONG_DIG_GAIN_REG_H,
1853
- OS02K10_REG_VALUE_24BIT,
1854
- (dgain << 6) & 0xfffc0);
1873
+ OS02K10_REG_VALUE_08BIT,
1874
+ ((dgain >> 10) & 0x0f) | reg_data);
1875
+ ret |= os02k10_write_reg(os02k10->client,
1876
+ OS02K10_AEC_LONG_DIG_GAIN_REG_M,
1877
+ OS02K10_REG_VALUE_08BIT,
1878
+ (dgain >> 2) & 0xff);
1879
+ ret |= os02k10_read_reg(os02k10->client, OS02K10_AEC_LONG_DIG_GAIN_REG_L,
1880
+ OS02K10_REG_VALUE_08BIT, &reg_data);
1881
+ reg_data = reg_data & 0x3f;
1882
+ ret |= os02k10_write_reg(os02k10->client,
1883
+ OS02K10_AEC_LONG_DIG_GAIN_REG_L,
1884
+ OS02K10_REG_VALUE_08BIT,
1885
+ ((dgain & 0x03) << 6) | reg_data);
18551886 break;
18561887 case V4L2_CID_VBLANK:
18571888 dev_dbg(&client->dev, "set blank value 0x%x\n", ctrl->val);
....@@ -2095,11 +2126,11 @@
20952126 return -EINVAL;
20962127 }
20972128
2098
- os02k10->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
2129
+ os02k10->reset_gpio = devm_gpiod_get(dev, "reset", os02k10->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
20992130 if (IS_ERR(os02k10->reset_gpio))
21002131 dev_warn(dev, "Failed to get reset-gpios\n");
21012132
2102
- os02k10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
2133
+ os02k10->pwdn_gpio = devm_gpiod_get(dev, "pwdn", os02k10->is_thunderboot ? GPIOD_ASIS : GPIOD_OUT_LOW);
21032134 if (IS_ERR(os02k10->pwdn_gpio))
21042135 dev_warn(dev, "Failed to get pwdn-gpios\n");
21052136