1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2022 Intel Corporation.
4 #include <linux/unaligned.h>
5 #include <linux/acpi.h>
6 #include <linux/delay.h>
8 #include <linux/module.h>
9 #include <linux/pm_runtime.h>
10 #include <media/v4l2-ctrls.h>
11 #include <media/v4l2-device.h>
12 #include <media/v4l2-fwnode.h>
14 #define HI847_REG_VALUE_08BIT 1
15 #define HI847_REG_VALUE_16BIT 2
16 #define HI847_REG_VALUE_24BIT 3
18 #define HI847_LINK_FREQ_400MHZ 400000000ULL
19 #define HI847_LINK_FREQ_200MHZ 200000000ULL
20 #define HI847_SCLK 72000000ULL
21 #define HI847_MCLK 19200000
22 #define HI847_DATA_LANES 4
23 #define HI847_RGB_DEPTH 10
25 #define HI847_REG_CHIP_ID 0x0716
26 #define HI847_CHIP_ID 0x0847
28 #define HI847_REG_MODE_SELECT 0x0B00
29 #define HI847_MODE_STANDBY 0x0000
30 #define HI847_MODE_STREAMING 0x0100
32 #define HI847_REG_MODE_TG 0x027E
33 #define HI847_REG_MODE_TG_ENABLE 0x0100
34 #define HI847_REG_MODE_TG_DISABLE 0x0000
36 /* vertical-timings from sensor */
37 #define HI847_REG_FLL 0x020E
38 #define HI847_FLL_30FPS 0x0B51
39 #define HI847_FLL_30FPS_MIN 0x0B51
40 #define HI847_FLL_60FPS 0x05A9
41 #define HI847_FLL_60FPS_MIN 0x05A9
42 #define HI847_FLL_MAX 0x7fff
44 /* horizontal-timings from sensor */
45 #define HI847_REG_LLP 0x0206
47 /* Exposure controls from sensor */
48 #define HI847_REG_EXPOSURE 0x020A
49 #define HI847_EXPOSURE_MIN 4
50 #define HI847_EXPOSURE_MAX_MARGIN 4
51 #define HI847_EXPOSURE_STEP 1
53 /* Analog gain controls from sensor */
54 #define HI847_REG_ANALOG_GAIN 0x0212
55 #define HI847_ANAL_GAIN_MIN 0
56 #define HI847_ANAL_GAIN_MAX 240
57 #define HI847_ANAL_GAIN_STEP 1
59 /* Digital gain controls from sensor */
60 #define HI847_REG_MWB_GR_GAIN 0x0214
61 #define HI847_REG_MWB_GB_GAIN 0x0216
62 #define HI847_REG_MWB_R_GAIN 0x0218
63 #define HI847_REG_MWB_B_GAIN 0x021A
64 #define HI847_DGTL_GAIN_MIN 1
65 #define HI847_DGTL_GAIN_MAX 8191
66 #define HI847_DGTL_GAIN_STEP 1
67 #define HI847_DGTL_GAIN_DEFAULT 512
69 /* Test Pattern Control */
70 #define HI847_REG_ISP 0X0B04
71 #define HI847_REG_ISP_TPG_EN 0x0001
72 #define HI847_REG_TEST_PATTERN 0x0C0A
74 /* Flip Mirror Controls from sensor */
75 #define HI847_REG_MIRROR_FLIP 0x0202
77 #define HI847_REG_FORMAT_X 0x0F04
78 #define HI847_REG_FORMAT_Y 0x0F06
81 HI847_LINK_FREQ_400MHZ_INDEX
,
82 HI847_LINK_FREQ_200MHZ_INDEX
,
90 struct hi847_reg_list
{
92 const struct hi847_reg
*regs
;
95 struct hi847_link_freq_config
{
96 const struct hi847_reg_list reg_list
;
100 /* Frame width in pixels */
103 /* Frame height in pixels */
106 /* Horizontal timining size */
109 /* Default vertical timining size */
112 /* Min vertical timining size */
115 /* Link frequency needed for this resolution */
118 /* Sensor register settings for this resolution */
119 const struct hi847_reg_list reg_list
;
122 #define to_hi847(_sd) container_of(_sd, struct hi847, sd)
124 //SENSOR_INITIALIZATION
125 static const struct hi847_reg mipi_data_rate_lane_4
[] = {
1917 static const struct hi847_reg mode_3264x2448_regs
[] = {
2013 static const struct hi847_reg mode_1632x1224_regs
[] = {
2109 static const char * const hi847_test_pattern_menu
[] = {
2113 "Fade To Grey Colour Bars",
2115 "Horizontal Gradient Pattern",
2116 "Vertical Gradient Pattern",
2121 static const s64 link_freq_menu_items
[] = {
2122 HI847_LINK_FREQ_400MHZ
,
2123 HI847_LINK_FREQ_200MHZ
,
2126 static const struct hi847_link_freq_config link_freq_configs
[] = {
2127 [HI847_LINK_FREQ_400MHZ_INDEX
] = {
2129 .num_of_regs
= ARRAY_SIZE(mipi_data_rate_lane_4
),
2130 .regs
= mipi_data_rate_lane_4
,
2133 [HI847_LINK_FREQ_200MHZ_INDEX
] = {
2135 .num_of_regs
= ARRAY_SIZE(mipi_data_rate_lane_4
),
2136 .regs
= mipi_data_rate_lane_4
,
2141 static const struct hi847_mode supported_modes
[] = {
2145 .fll_def
= HI847_FLL_30FPS
,
2146 .fll_min
= HI847_FLL_30FPS_MIN
,
2149 .num_of_regs
= ARRAY_SIZE(mode_3264x2448_regs
),
2150 .regs
= mode_3264x2448_regs
,
2152 .link_freq_index
= HI847_LINK_FREQ_400MHZ_INDEX
,
2157 .fll_def
= HI847_FLL_60FPS
,
2158 .fll_min
= HI847_FLL_60FPS_MIN
,
2161 .num_of_regs
= ARRAY_SIZE(mode_1632x1224_regs
),
2162 .regs
= mode_1632x1224_regs
,
2164 .link_freq_index
= HI847_LINK_FREQ_200MHZ_INDEX
,
2169 struct v4l2_subdev sd
;
2170 struct media_pad pad
;
2171 struct v4l2_ctrl_handler ctrl_handler
;
2174 struct v4l2_ctrl
*link_freq
;
2175 struct v4l2_ctrl
*pixel_rate
;
2176 struct v4l2_ctrl
*vblank
;
2177 struct v4l2_ctrl
*hblank
;
2178 struct v4l2_ctrl
*exposure
;
2179 struct v4l2_ctrl
*vflip
;
2180 struct v4l2_ctrl
*hflip
;
2183 const struct hi847_mode
*cur_mode
;
2185 /* To serialize asynchronus callbacks */
2189 static u64
to_pixel_rate(u32 f_index
)
2191 u64 pixel_rate
= link_freq_menu_items
[f_index
] * 2 * HI847_DATA_LANES
;
2193 do_div(pixel_rate
, HI847_RGB_DEPTH
);
2198 static int hi847_read_reg(struct hi847
*hi847
, u16 reg
, u16 len
, u32
*val
)
2200 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2201 struct i2c_msg msgs
[2];
2203 u8 data_buf
[4] = {0};
2209 put_unaligned_be16(reg
, addr_buf
);
2210 msgs
[0].addr
= client
->addr
;
2212 msgs
[0].len
= sizeof(addr_buf
);
2213 msgs
[0].buf
= addr_buf
;
2214 msgs
[1].addr
= client
->addr
;
2215 msgs
[1].flags
= I2C_M_RD
;
2217 msgs
[1].buf
= &data_buf
[4 - len
];
2219 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
2220 if (ret
!= ARRAY_SIZE(msgs
))
2223 *val
= get_unaligned_be32(data_buf
);
2228 static int hi847_write_reg(struct hi847
*hi847
, u16 reg
, u16 len
, u32 val
)
2230 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2236 put_unaligned_be16(reg
, buf
);
2237 put_unaligned_be32(val
<< 8 * (4 - len
), buf
+ 2);
2238 if (i2c_master_send(client
, buf
, len
+ 2) != len
+ 2)
2244 static int hi847_write_reg_list(struct hi847
*hi847
,
2245 const struct hi847_reg_list
*r_list
)
2247 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2251 for (i
= 0; i
< r_list
->num_of_regs
; i
++) {
2252 ret
= hi847_write_reg(hi847
, r_list
->regs
[i
].address
,
2253 HI847_REG_VALUE_16BIT
,
2254 r_list
->regs
[i
].val
);
2256 dev_err_ratelimited(&client
->dev
,
2257 "failed to write reg 0x%4.4x. error = %d",
2258 r_list
->regs
[i
].address
, ret
);
2266 static int hi847_update_digital_gain(struct hi847
*hi847
, u32 d_gain
)
2270 ret
= hi847_write_reg(hi847
, HI847_REG_MWB_GR_GAIN
,
2271 HI847_REG_VALUE_16BIT
, d_gain
);
2275 ret
= hi847_write_reg(hi847
, HI847_REG_MWB_GB_GAIN
,
2276 HI847_REG_VALUE_16BIT
, d_gain
);
2280 ret
= hi847_write_reg(hi847
, HI847_REG_MWB_R_GAIN
,
2281 HI847_REG_VALUE_16BIT
, d_gain
);
2285 return hi847_write_reg(hi847
, HI847_REG_MWB_B_GAIN
,
2286 HI847_REG_VALUE_16BIT
, d_gain
);
2289 static int hi847_test_pattern(struct hi847
*hi847
, u32 pattern
)
2295 ret
= hi847_read_reg(hi847
, HI847_REG_ISP
,
2296 HI847_REG_VALUE_16BIT
, &val
);
2300 ret
= hi847_write_reg(hi847
, HI847_REG_ISP
,
2301 HI847_REG_VALUE_16BIT
,
2302 val
| HI847_REG_ISP_TPG_EN
);
2307 ret
= hi847_read_reg(hi847
, HI847_REG_TEST_PATTERN
,
2308 HI847_REG_VALUE_16BIT
, &val
);
2312 return hi847_write_reg(hi847
, HI847_REG_TEST_PATTERN
,
2313 HI847_REG_VALUE_16BIT
, val
| pattern
<< 8);
2316 static int hi847_grbg_shift(struct hi847
*hi847
)
2321 /* regs shift for full size */
2322 static const u32 FORMAT_X_SHIFT_1
[2][2] = {
2323 { 0x0008, 0x0007, },
2324 { 0x0008, 0x0007, },
2327 static const u32 FORMAT_Y_SHIFT_1
[2][2] = {
2328 { 0x0002, 0x0002, },
2329 { 0x0001, 0x0001, },
2332 /* regs shift for binning size */
2333 static const u32 FORMAT_X_SHIFT_2
[2][2] = {
2334 { 0x0004, 0x0003, },
2335 { 0x0004, 0x0003, },
2338 static const u32 FORMAT_Y_SHIFT_2
[2][2] = {
2339 { 0x0002, 0x0002, },
2340 { 0x0001, 0x0001, },
2343 hflip
= hi847
->hflip
->val
;
2344 vflip
= hi847
->vflip
->val
;
2346 if (hi847
->cur_mode
->width
== 3264) {
2347 ret
= hi847_write_reg(hi847
, HI847_REG_FORMAT_X
,
2348 HI847_REG_VALUE_16BIT
,
2349 FORMAT_X_SHIFT_1
[vflip
][hflip
]);
2353 return hi847_write_reg(hi847
, HI847_REG_FORMAT_Y
,
2354 HI847_REG_VALUE_16BIT
,
2355 FORMAT_Y_SHIFT_1
[vflip
][hflip
]);
2357 ret
= hi847_write_reg(hi847
, HI847_REG_FORMAT_X
,
2358 HI847_REG_VALUE_16BIT
,
2359 FORMAT_X_SHIFT_2
[vflip
][hflip
]);
2363 return hi847_write_reg(hi847
, HI847_REG_FORMAT_Y
,
2364 HI847_REG_VALUE_16BIT
,
2365 FORMAT_Y_SHIFT_2
[vflip
][hflip
]);
2369 static int hi847_set_ctrl_hflip(struct hi847
*hi847
, u32 ctrl_val
)
2374 ret
= hi847_read_reg(hi847
, HI847_REG_MIRROR_FLIP
,
2375 HI847_REG_VALUE_16BIT
, &val
);
2379 ret
= hi847_grbg_shift(hi847
);
2383 return hi847_write_reg(hi847
, HI847_REG_MIRROR_FLIP
,
2384 HI847_REG_VALUE_16BIT
,
2385 ctrl_val
? val
| BIT(8) : val
& ~BIT(8));
2388 static int hi847_set_ctrl_vflip(struct hi847
*hi847
, u8 ctrl_val
)
2393 ret
= hi847_read_reg(hi847
, HI847_REG_MIRROR_FLIP
,
2394 HI847_REG_VALUE_16BIT
, &val
);
2398 ret
= hi847_grbg_shift(hi847
);
2402 return hi847_write_reg(hi847
, HI847_REG_MIRROR_FLIP
,
2403 HI847_REG_VALUE_16BIT
,
2404 ctrl_val
? val
| BIT(9) : val
& ~BIT(9));
2407 static int hi847_set_ctrl(struct v4l2_ctrl
*ctrl
)
2409 struct hi847
*hi847
= container_of(ctrl
->handler
,
2410 struct hi847
, ctrl_handler
);
2411 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2415 /* Propagate change of current control to all related controls */
2416 if (ctrl
->id
== V4L2_CID_VBLANK
) {
2417 /* Update max exposure while meeting expected vblanking */
2418 exposure_max
= hi847
->cur_mode
->height
+ ctrl
->val
-
2419 HI847_EXPOSURE_MAX_MARGIN
;
2420 __v4l2_ctrl_modify_range(hi847
->exposure
,
2421 hi847
->exposure
->minimum
,
2422 exposure_max
, hi847
->exposure
->step
,
2426 /* V4L2 controls values will be applied only when power is already up */
2427 if (!pm_runtime_get_if_in_use(&client
->dev
))
2431 case V4L2_CID_ANALOGUE_GAIN
:
2432 ret
= hi847_write_reg(hi847
, HI847_REG_ANALOG_GAIN
,
2433 HI847_REG_VALUE_16BIT
, ctrl
->val
);
2436 case V4L2_CID_DIGITAL_GAIN
:
2437 ret
= hi847_update_digital_gain(hi847
, ctrl
->val
);
2440 case V4L2_CID_EXPOSURE
:
2441 ret
= hi847_write_reg(hi847
, HI847_REG_EXPOSURE
,
2442 HI847_REG_VALUE_16BIT
, ctrl
->val
);
2445 case V4L2_CID_VBLANK
:
2446 /* Update FLL that meets expected vertical blanking */
2447 ret
= hi847_write_reg(hi847
, HI847_REG_FLL
,
2448 HI847_REG_VALUE_16BIT
,
2449 hi847
->cur_mode
->height
+ ctrl
->val
);
2452 case V4L2_CID_TEST_PATTERN
:
2453 ret
= hi847_test_pattern(hi847
, ctrl
->val
);
2456 case V4L2_CID_HFLIP
:
2457 hi847_set_ctrl_hflip(hi847
, ctrl
->val
);
2460 case V4L2_CID_VFLIP
:
2461 hi847_set_ctrl_vflip(hi847
, ctrl
->val
);
2469 pm_runtime_put(&client
->dev
);
2474 static const struct v4l2_ctrl_ops hi847_ctrl_ops
= {
2475 .s_ctrl
= hi847_set_ctrl
,
2478 static int hi847_init_controls(struct hi847
*hi847
)
2480 struct v4l2_ctrl_handler
*ctrl_hdlr
;
2481 s64 exposure_max
, h_blank
;
2484 ctrl_hdlr
= &hi847
->ctrl_handler
;
2485 ret
= v4l2_ctrl_handler_init(ctrl_hdlr
, 8);
2489 ctrl_hdlr
->lock
= &hi847
->mutex
;
2490 hi847
->link_freq
= v4l2_ctrl_new_int_menu(ctrl_hdlr
, &hi847_ctrl_ops
,
2492 ARRAY_SIZE(link_freq_menu_items
) - 1,
2493 0, link_freq_menu_items
);
2494 if (hi847
->link_freq
)
2495 hi847
->link_freq
->flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
2497 hi847
->pixel_rate
= v4l2_ctrl_new_std
2498 (ctrl_hdlr
, &hi847_ctrl_ops
,
2499 V4L2_CID_PIXEL_RATE
, 0,
2500 to_pixel_rate(HI847_LINK_FREQ_400MHZ_INDEX
),
2502 to_pixel_rate(HI847_LINK_FREQ_400MHZ_INDEX
));
2503 hi847
->vblank
= v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
,
2505 hi847
->cur_mode
->fll_min
-
2506 hi847
->cur_mode
->height
,
2508 hi847
->cur_mode
->height
, 1,
2509 hi847
->cur_mode
->fll_def
-
2510 hi847
->cur_mode
->height
);
2512 h_blank
= hi847
->cur_mode
->llp
- hi847
->cur_mode
->width
;
2514 hi847
->hblank
= v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
,
2515 V4L2_CID_HBLANK
, h_blank
, h_blank
, 1,
2518 hi847
->hblank
->flags
|= V4L2_CTRL_FLAG_READ_ONLY
;
2520 v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
, V4L2_CID_ANALOGUE_GAIN
,
2521 HI847_ANAL_GAIN_MIN
, HI847_ANAL_GAIN_MAX
,
2522 HI847_ANAL_GAIN_STEP
, HI847_ANAL_GAIN_MIN
);
2523 v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
, V4L2_CID_DIGITAL_GAIN
,
2524 HI847_DGTL_GAIN_MIN
, HI847_DGTL_GAIN_MAX
,
2525 HI847_DGTL_GAIN_STEP
, HI847_DGTL_GAIN_DEFAULT
);
2526 exposure_max
= hi847
->cur_mode
->fll_def
- HI847_EXPOSURE_MAX_MARGIN
;
2527 hi847
->exposure
= v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
,
2529 HI847_EXPOSURE_MIN
, exposure_max
,
2530 HI847_EXPOSURE_STEP
,
2532 v4l2_ctrl_new_std_menu_items(ctrl_hdlr
, &hi847_ctrl_ops
,
2533 V4L2_CID_TEST_PATTERN
,
2534 ARRAY_SIZE(hi847_test_pattern_menu
) - 1,
2535 0, 0, hi847_test_pattern_menu
);
2536 hi847
->hflip
= v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
,
2537 V4L2_CID_HFLIP
, 0, 1, 1, 0);
2538 hi847
->vflip
= v4l2_ctrl_new_std(ctrl_hdlr
, &hi847_ctrl_ops
,
2539 V4L2_CID_VFLIP
, 0, 1, 1, 0);
2541 if (ctrl_hdlr
->error
)
2542 return ctrl_hdlr
->error
;
2544 hi847
->sd
.ctrl_handler
= ctrl_hdlr
;
2549 static void hi847_assign_pad_format(const struct hi847_mode
*mode
,
2550 struct v4l2_mbus_framefmt
*fmt
)
2552 fmt
->width
= mode
->width
;
2553 fmt
->height
= mode
->height
;
2554 fmt
->code
= MEDIA_BUS_FMT_SGRBG10_1X10
;
2555 fmt
->field
= V4L2_FIELD_NONE
;
2558 static int hi847_start_streaming(struct hi847
*hi847
)
2560 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2561 const struct hi847_reg_list
*reg_list
;
2562 int link_freq_index
, ret
;
2564 link_freq_index
= hi847
->cur_mode
->link_freq_index
;
2565 reg_list
= &link_freq_configs
[link_freq_index
].reg_list
;
2566 ret
= hi847_write_reg_list(hi847
, reg_list
);
2568 dev_err(&client
->dev
, "failed to set plls");
2572 reg_list
= &hi847
->cur_mode
->reg_list
;
2573 ret
= hi847_write_reg_list(hi847
, reg_list
);
2575 dev_err(&client
->dev
, "failed to set mode");
2579 ret
= __v4l2_ctrl_handler_setup(hi847
->sd
.ctrl_handler
);
2583 ret
= hi847_write_reg(hi847
, HI847_REG_MODE_TG
,
2584 HI847_REG_VALUE_16BIT
, HI847_REG_MODE_TG_ENABLE
);
2586 ret
= hi847_write_reg(hi847
, HI847_REG_MODE_SELECT
,
2587 HI847_REG_VALUE_16BIT
, HI847_MODE_STREAMING
);
2590 dev_err(&client
->dev
, "failed to set stream");
2597 static void hi847_stop_streaming(struct hi847
*hi847
)
2599 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2601 if (hi847_write_reg(hi847
, HI847_REG_MODE_TG
,
2602 HI847_REG_VALUE_16BIT
, HI847_REG_MODE_TG_DISABLE
))
2603 dev_err(&client
->dev
, "failed to set stream 0x%x",
2606 if (hi847_write_reg(hi847
, HI847_REG_MODE_SELECT
,
2607 HI847_REG_VALUE_16BIT
, HI847_MODE_STANDBY
))
2608 dev_err(&client
->dev
, "failed to set stream 0x%x",
2609 HI847_REG_MODE_SELECT
);
2612 static int hi847_set_stream(struct v4l2_subdev
*sd
, int enable
)
2614 struct hi847
*hi847
= to_hi847(sd
);
2615 struct i2c_client
*client
= v4l2_get_subdevdata(sd
);
2618 mutex_lock(&hi847
->mutex
);
2620 ret
= pm_runtime_resume_and_get(&client
->dev
);
2622 mutex_unlock(&hi847
->mutex
);
2626 ret
= hi847_start_streaming(hi847
);
2629 hi847_stop_streaming(hi847
);
2630 pm_runtime_put(&client
->dev
);
2633 hi847_stop_streaming(hi847
);
2634 pm_runtime_put(&client
->dev
);
2637 mutex_unlock(&hi847
->mutex
);
2642 static int hi847_set_format(struct v4l2_subdev
*sd
,
2643 struct v4l2_subdev_state
*sd_state
,
2644 struct v4l2_subdev_format
*fmt
)
2646 struct hi847
*hi847
= to_hi847(sd
);
2647 const struct hi847_mode
*mode
;
2648 s32 vblank_def
, h_blank
;
2650 mode
= v4l2_find_nearest_size(supported_modes
,
2651 ARRAY_SIZE(supported_modes
), width
,
2652 height
, fmt
->format
.width
,
2653 fmt
->format
.height
);
2655 mutex_lock(&hi847
->mutex
);
2656 hi847_assign_pad_format(mode
, &fmt
->format
);
2657 if (fmt
->which
== V4L2_SUBDEV_FORMAT_TRY
) {
2658 *v4l2_subdev_state_get_format(sd_state
, fmt
->pad
) =
2661 hi847
->cur_mode
= mode
;
2662 __v4l2_ctrl_s_ctrl(hi847
->link_freq
, mode
->link_freq_index
);
2663 __v4l2_ctrl_s_ctrl_int64(hi847
->pixel_rate
,
2664 to_pixel_rate(mode
->link_freq_index
));
2666 /* Update limits and set FPS to default */
2667 vblank_def
= mode
->fll_def
- mode
->height
;
2668 __v4l2_ctrl_modify_range(hi847
->vblank
,
2669 mode
->fll_min
- mode
->height
,
2670 HI847_FLL_MAX
- mode
->height
, 1,
2672 __v4l2_ctrl_s_ctrl(hi847
->vblank
, vblank_def
);
2674 h_blank
= hi847
->cur_mode
->llp
- hi847
->cur_mode
->width
;
2676 __v4l2_ctrl_modify_range(hi847
->hblank
, h_blank
, h_blank
, 1,
2680 mutex_unlock(&hi847
->mutex
);
2685 static int hi847_get_format(struct v4l2_subdev
*sd
,
2686 struct v4l2_subdev_state
*sd_state
,
2687 struct v4l2_subdev_format
*fmt
)
2689 struct hi847
*hi847
= to_hi847(sd
);
2691 mutex_lock(&hi847
->mutex
);
2692 if (fmt
->which
== V4L2_SUBDEV_FORMAT_TRY
)
2693 fmt
->format
= *v4l2_subdev_state_get_format(sd_state
,
2696 hi847_assign_pad_format(hi847
->cur_mode
, &fmt
->format
);
2698 mutex_unlock(&hi847
->mutex
);
2703 static int hi847_enum_mbus_code(struct v4l2_subdev
*sd
,
2704 struct v4l2_subdev_state
*sd_state
,
2705 struct v4l2_subdev_mbus_code_enum
*code
)
2707 if (code
->index
> 0)
2710 code
->code
= MEDIA_BUS_FMT_SGRBG10_1X10
;
2715 static int hi847_enum_frame_size(struct v4l2_subdev
*sd
,
2716 struct v4l2_subdev_state
*sd_state
,
2717 struct v4l2_subdev_frame_size_enum
*fse
)
2719 if (fse
->index
>= ARRAY_SIZE(supported_modes
))
2722 if (fse
->code
!= MEDIA_BUS_FMT_SGRBG10_1X10
)
2725 fse
->min_width
= supported_modes
[fse
->index
].width
;
2726 fse
->max_width
= fse
->min_width
;
2727 fse
->min_height
= supported_modes
[fse
->index
].height
;
2728 fse
->max_height
= fse
->min_height
;
2733 static int hi847_open(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
)
2735 struct hi847
*hi847
= to_hi847(sd
);
2737 mutex_lock(&hi847
->mutex
);
2738 hi847_assign_pad_format(&supported_modes
[0],
2739 v4l2_subdev_state_get_format(fh
->state
, 0));
2740 mutex_unlock(&hi847
->mutex
);
2745 static const struct v4l2_subdev_video_ops hi847_video_ops
= {
2746 .s_stream
= hi847_set_stream
,
2749 static const struct v4l2_subdev_pad_ops hi847_pad_ops
= {
2750 .set_fmt
= hi847_set_format
,
2751 .get_fmt
= hi847_get_format
,
2752 .enum_mbus_code
= hi847_enum_mbus_code
,
2753 .enum_frame_size
= hi847_enum_frame_size
,
2756 static const struct v4l2_subdev_ops hi847_subdev_ops
= {
2757 .video
= &hi847_video_ops
,
2758 .pad
= &hi847_pad_ops
,
2761 static const struct media_entity_operations hi847_subdev_entity_ops
= {
2762 .link_validate
= v4l2_subdev_link_validate
,
2765 static const struct v4l2_subdev_internal_ops hi847_internal_ops
= {
2769 static int hi847_identify_module(struct hi847
*hi847
)
2771 struct i2c_client
*client
= v4l2_get_subdevdata(&hi847
->sd
);
2775 ret
= hi847_read_reg(hi847
, HI847_REG_CHIP_ID
,
2776 HI847_REG_VALUE_16BIT
, &val
);
2780 if (val
!= HI847_CHIP_ID
) {
2781 dev_err(&client
->dev
, "chip id mismatch: %x!=%x",
2782 HI847_CHIP_ID
, val
);
2789 static int hi847_check_hwcfg(struct device
*dev
)
2791 struct fwnode_handle
*ep
;
2792 struct fwnode_handle
*fwnode
= dev_fwnode(dev
);
2793 struct v4l2_fwnode_endpoint bus_cfg
= {
2794 .bus_type
= V4L2_MBUS_CSI2_DPHY
2803 ret
= fwnode_property_read_u32(fwnode
, "clock-frequency", &mclk
);
2805 dev_err(dev
, "can't get clock frequency");
2809 if (mclk
!= HI847_MCLK
) {
2810 dev_err(dev
, "external clock %d is not supported", mclk
);
2814 ep
= fwnode_graph_get_next_endpoint(fwnode
, NULL
);
2818 ret
= v4l2_fwnode_endpoint_alloc_parse(ep
, &bus_cfg
);
2819 fwnode_handle_put(ep
);
2823 if (bus_cfg
.bus
.mipi_csi2
.num_data_lanes
!= HI847_DATA_LANES
) {
2824 dev_err(dev
, "number of CSI2 data lanes %d is not supported",
2825 bus_cfg
.bus
.mipi_csi2
.num_data_lanes
);
2827 goto check_hwcfg_error
;
2830 if (!bus_cfg
.nr_of_link_frequencies
) {
2831 dev_err(dev
, "no link frequencies defined");
2833 goto check_hwcfg_error
;
2836 for (i
= 0; i
< ARRAY_SIZE(link_freq_menu_items
); i
++) {
2837 for (j
= 0; j
< bus_cfg
.nr_of_link_frequencies
; j
++) {
2838 if (link_freq_menu_items
[i
] ==
2839 bus_cfg
.link_frequencies
[j
])
2843 if (j
== bus_cfg
.nr_of_link_frequencies
) {
2844 dev_err(dev
, "no link frequency %lld supported",
2845 link_freq_menu_items
[i
]);
2847 goto check_hwcfg_error
;
2852 v4l2_fwnode_endpoint_free(&bus_cfg
);
2857 static void hi847_remove(struct i2c_client
*client
)
2859 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
2860 struct hi847
*hi847
= to_hi847(sd
);
2862 v4l2_async_unregister_subdev(sd
);
2863 media_entity_cleanup(&sd
->entity
);
2864 v4l2_ctrl_handler_free(sd
->ctrl_handler
);
2865 pm_runtime_disable(&client
->dev
);
2866 mutex_destroy(&hi847
->mutex
);
2869 static int hi847_probe(struct i2c_client
*client
)
2871 struct hi847
*hi847
;
2874 hi847
= devm_kzalloc(&client
->dev
, sizeof(*hi847
), GFP_KERNEL
);
2878 ret
= hi847_check_hwcfg(&client
->dev
);
2880 dev_err(&client
->dev
, "failed to get HW configuration: %d",
2885 v4l2_i2c_subdev_init(&hi847
->sd
, client
, &hi847_subdev_ops
);
2886 ret
= hi847_identify_module(hi847
);
2888 dev_err(&client
->dev
, "failed to find sensor: %d", ret
);
2892 mutex_init(&hi847
->mutex
);
2893 hi847
->cur_mode
= &supported_modes
[0];
2894 ret
= hi847_init_controls(hi847
);
2896 dev_err(&client
->dev
, "failed to init controls: %d", ret
);
2897 goto probe_error_v4l2_ctrl_handler_free
;
2900 hi847
->sd
.internal_ops
= &hi847_internal_ops
;
2901 hi847
->sd
.flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
2902 hi847
->sd
.entity
.ops
= &hi847_subdev_entity_ops
;
2903 hi847
->sd
.entity
.function
= MEDIA_ENT_F_CAM_SENSOR
;
2904 hi847
->pad
.flags
= MEDIA_PAD_FL_SOURCE
;
2905 ret
= media_entity_pads_init(&hi847
->sd
.entity
, 1, &hi847
->pad
);
2907 dev_err(&client
->dev
, "failed to init entity pads: %d", ret
);
2908 goto probe_error_v4l2_ctrl_handler_free
;
2911 ret
= v4l2_async_register_subdev_sensor(&hi847
->sd
);
2913 dev_err(&client
->dev
, "failed to register V4L2 subdev: %d",
2915 goto probe_error_media_entity_cleanup
;
2918 pm_runtime_set_active(&client
->dev
);
2919 pm_runtime_enable(&client
->dev
);
2920 pm_runtime_idle(&client
->dev
);
2924 probe_error_media_entity_cleanup
:
2925 media_entity_cleanup(&hi847
->sd
.entity
);
2927 probe_error_v4l2_ctrl_handler_free
:
2928 v4l2_ctrl_handler_free(hi847
->sd
.ctrl_handler
);
2929 mutex_destroy(&hi847
->mutex
);
2935 static const struct acpi_device_id hi847_acpi_ids
[] = {
2940 MODULE_DEVICE_TABLE(acpi
, hi847_acpi_ids
);
2943 static struct i2c_driver hi847_i2c_driver
= {
2946 .acpi_match_table
= ACPI_PTR(hi847_acpi_ids
),
2948 .probe
= hi847_probe
,
2949 .remove
= hi847_remove
,
2952 module_i2c_driver(hi847_i2c_driver
);
2954 MODULE_AUTHOR("Shawn Tu");
2955 MODULE_DESCRIPTION("Hynix HI847 sensor driver");
2956 MODULE_LICENSE("GPL v2");