2021-05-27 17:21:41 +03:00
// SPDX-License-Identifier: GPL-2.0-only
/*
* Sony imx335 Camera Sensor Driver
*
* Copyright ( C ) 2021 Intel Corporation
*/
# include <asm/unaligned.h>
# include <linux/clk.h>
# include <linux/delay.h>
# include <linux/i2c.h>
# include <linux/module.h>
# include <linux/pm_runtime.h>
# include <media/v4l2-ctrls.h>
# include <media/v4l2-fwnode.h>
# include <media/v4l2-subdev.h>
/* Streaming Mode */
# define IMX335_REG_MODE_SELECT 0x3000
# define IMX335_MODE_STANDBY 0x01
# define IMX335_MODE_STREAMING 0x00
/* Lines per frame */
# define IMX335_REG_LPFR 0x3030
/* Chip ID */
# define IMX335_REG_ID 0x3912
# define IMX335_ID 0x00
/* Exposure control */
# define IMX335_REG_SHUTTER 0x3058
# define IMX335_EXPOSURE_MIN 1
# define IMX335_EXPOSURE_OFFSET 9
# define IMX335_EXPOSURE_STEP 1
# define IMX335_EXPOSURE_DEFAULT 0x0648
/* Analog gain control */
# define IMX335_REG_AGAIN 0x30e8
# define IMX335_AGAIN_MIN 0
# define IMX335_AGAIN_MAX 240
# define IMX335_AGAIN_STEP 1
# define IMX335_AGAIN_DEFAULT 0
/* Group hold register */
# define IMX335_REG_HOLD 0x3001
/* Input clock rate */
# define IMX335_INCLK_RATE 24000000
/* CSI2 HW configuration */
# define IMX335_LINK_FREQ 594000000
# define IMX335_NUM_DATA_LANES 4
# define IMX335_REG_MIN 0x00
# define IMX335_REG_MAX 0xfffff
2023-12-11 15:59:47 +03:00
/* IMX335 native and active pixel array size. */
# define IMX335_NATIVE_WIDTH 2616U
# define IMX335_NATIVE_HEIGHT 1964U
# define IMX335_PIXEL_ARRAY_LEFT 12U
# define IMX335_PIXEL_ARRAY_TOP 12U
# define IMX335_PIXEL_ARRAY_WIDTH 2592U
# define IMX335_PIXEL_ARRAY_HEIGHT 1944U
2021-05-27 17:21:41 +03:00
/**
* struct imx335_reg - imx335 sensor register
* @ address : Register address
* @ val : Register value
*/
struct imx335_reg {
u16 address ;
u8 val ;
} ;
/**
* struct imx335_reg_list - imx335 sensor register list
* @ num_of_regs : Number of registers in the list
* @ regs : Pointer to register list
*/
struct imx335_reg_list {
u32 num_of_regs ;
const struct imx335_reg * regs ;
} ;
2023-12-11 15:59:46 +03:00
static const char * const imx335_supply_name [ ] = {
" avdd " , /* Analog (2.9V) supply */
" ovdd " , /* Digital I/O (1.8V) supply */
" dvdd " , /* Digital Core (1.2V) supply */
} ;
2021-05-27 17:21:41 +03:00
/**
* struct imx335_mode - imx335 sensor mode structure
* @ width : Frame width
* @ height : Frame height
* @ code : Format code
* @ hblank : Horizontal blanking in lines
* @ vblank : Vertical blanking in lines
* @ vblank_min : Minimum vertical blanking in lines
* @ vblank_max : Maximum vertical blanking in lines
* @ pclk : Sensor pixel clock
* @ link_freq_idx : Link frequency index
* @ reg_list : Register list for sensor mode
*/
struct imx335_mode {
u32 width ;
u32 height ;
u32 code ;
u32 hblank ;
u32 vblank ;
u32 vblank_min ;
u32 vblank_max ;
u64 pclk ;
u32 link_freq_idx ;
struct imx335_reg_list reg_list ;
} ;
/**
* struct imx335 - imx335 sensor device structure
* @ dev : Pointer to generic device
* @ client : Pointer to i2c client
* @ sd : V4L2 sub - device
* @ pad : Media pad . Only one pad supported
* @ reset_gpio : Sensor reset gpio
2023-12-11 15:59:46 +03:00
* @ supplies : Regulator supplies to handle power control
2021-05-27 17:21:41 +03:00
* @ inclk : Sensor input clock
* @ ctrl_handler : V4L2 control handler
* @ link_freq_ctrl : Pointer to link frequency control
* @ pclk_ctrl : Pointer to pixel clock control
* @ hblank_ctrl : Pointer to horizontal blanking control
* @ vblank_ctrl : Pointer to vertical blanking control
* @ exp_ctrl : Pointer to exposure control
* @ again_ctrl : Pointer to analog gain control
* @ vblank : Vertical blanking in lines
* @ cur_mode : Pointer to current selected sensor mode
* @ mutex : Mutex for serializing sensor controls
2023-12-11 15:59:49 +03:00
* @ cur_mbus_code : Currently selected media bus format code
2021-05-27 17:21:41 +03:00
*/
struct imx335 {
struct device * dev ;
struct i2c_client * client ;
struct v4l2_subdev sd ;
struct media_pad pad ;
struct gpio_desc * reset_gpio ;
2023-12-11 15:59:46 +03:00
struct regulator_bulk_data supplies [ ARRAY_SIZE ( imx335_supply_name ) ] ;
2021-05-27 17:21:41 +03:00
struct clk * inclk ;
struct v4l2_ctrl_handler ctrl_handler ;
struct v4l2_ctrl * link_freq_ctrl ;
struct v4l2_ctrl * pclk_ctrl ;
struct v4l2_ctrl * hblank_ctrl ;
struct v4l2_ctrl * vblank_ctrl ;
struct {
struct v4l2_ctrl * exp_ctrl ;
struct v4l2_ctrl * again_ctrl ;
} ;
u32 vblank ;
const struct imx335_mode * cur_mode ;
struct mutex mutex ;
2023-12-11 15:59:49 +03:00
u32 cur_mbus_code ;
2021-05-27 17:21:41 +03:00
} ;
static const s64 link_freq [ ] = {
IMX335_LINK_FREQ ,
} ;
/* Sensor mode registers */
static const struct imx335_reg mode_2592x1940_regs [ ] = {
{ 0x3000 , 0x01 } ,
{ 0x3002 , 0x00 } ,
{ 0x300c , 0x3b } ,
{ 0x300d , 0x2a } ,
{ 0x3018 , 0x04 } ,
{ 0x302c , 0x3c } ,
{ 0x302e , 0x20 } ,
{ 0x3056 , 0x94 } ,
{ 0x3074 , 0xc8 } ,
{ 0x3076 , 0x28 } ,
{ 0x304c , 0x00 } ,
{ 0x314c , 0xc6 } ,
{ 0x315a , 0x02 } ,
{ 0x3168 , 0xa0 } ,
{ 0x316a , 0x7e } ,
{ 0x31a1 , 0x00 } ,
{ 0x3288 , 0x21 } ,
{ 0x328a , 0x02 } ,
{ 0x3414 , 0x05 } ,
{ 0x3416 , 0x18 } ,
{ 0x3648 , 0x01 } ,
{ 0x364a , 0x04 } ,
{ 0x364c , 0x04 } ,
{ 0x3678 , 0x01 } ,
{ 0x367c , 0x31 } ,
{ 0x367e , 0x31 } ,
{ 0x3706 , 0x10 } ,
{ 0x3708 , 0x03 } ,
{ 0x3714 , 0x02 } ,
{ 0x3715 , 0x02 } ,
{ 0x3716 , 0x01 } ,
{ 0x3717 , 0x03 } ,
{ 0x371c , 0x3d } ,
{ 0x371d , 0x3f } ,
{ 0x372c , 0x00 } ,
{ 0x372d , 0x00 } ,
{ 0x372e , 0x46 } ,
{ 0x372f , 0x00 } ,
{ 0x3730 , 0x89 } ,
{ 0x3731 , 0x00 } ,
{ 0x3732 , 0x08 } ,
{ 0x3733 , 0x01 } ,
{ 0x3734 , 0xfe } ,
{ 0x3735 , 0x05 } ,
{ 0x3740 , 0x02 } ,
{ 0x375d , 0x00 } ,
{ 0x375e , 0x00 } ,
{ 0x375f , 0x11 } ,
{ 0x3760 , 0x01 } ,
{ 0x3768 , 0x1b } ,
{ 0x3769 , 0x1b } ,
{ 0x376a , 0x1b } ,
{ 0x376b , 0x1b } ,
{ 0x376c , 0x1a } ,
{ 0x376d , 0x17 } ,
{ 0x376e , 0x0f } ,
{ 0x3776 , 0x00 } ,
{ 0x3777 , 0x00 } ,
{ 0x3778 , 0x46 } ,
{ 0x3779 , 0x00 } ,
{ 0x377a , 0x89 } ,
{ 0x377b , 0x00 } ,
{ 0x377c , 0x08 } ,
{ 0x377d , 0x01 } ,
{ 0x377e , 0x23 } ,
{ 0x377f , 0x02 } ,
{ 0x3780 , 0xd9 } ,
{ 0x3781 , 0x03 } ,
{ 0x3782 , 0xf5 } ,
{ 0x3783 , 0x06 } ,
{ 0x3784 , 0xa5 } ,
{ 0x3788 , 0x0f } ,
{ 0x378a , 0xd9 } ,
{ 0x378b , 0x03 } ,
{ 0x378c , 0xeb } ,
{ 0x378d , 0x05 } ,
{ 0x378e , 0x87 } ,
{ 0x378f , 0x06 } ,
{ 0x3790 , 0xf5 } ,
{ 0x3792 , 0x43 } ,
{ 0x3794 , 0x7a } ,
{ 0x3796 , 0xa1 } ,
{ 0x37b0 , 0x36 } ,
{ 0x3a00 , 0x01 } ,
} ;
2023-12-11 15:59:49 +03:00
static const struct imx335_reg raw10_framefmt_regs [ ] = {
{ 0x3050 , 0x00 } ,
{ 0x319d , 0x00 } ,
{ 0x341c , 0xff } ,
{ 0x341d , 0x01 } ,
} ;
static const struct imx335_reg raw12_framefmt_regs [ ] = {
{ 0x3050 , 0x01 } ,
{ 0x319d , 0x01 } ,
{ 0x341c , 0x47 } ,
{ 0x341d , 0x00 } ,
} ;
static const u32 imx335_mbus_codes [ ] = {
MEDIA_BUS_FMT_SRGGB12_1X12 ,
MEDIA_BUS_FMT_SRGGB10_1X10 ,
} ;
2021-05-27 17:21:41 +03:00
/* Supported sensor mode configurations */
static const struct imx335_mode supported_mode = {
. width = 2592 ,
. height = 1940 ,
. hblank = 342 ,
. vblank = 2560 ,
. vblank_min = 2560 ,
. vblank_max = 133060 ,
. pclk = 396000000 ,
. link_freq_idx = 0 ,
. reg_list = {
. num_of_regs = ARRAY_SIZE ( mode_2592x1940_regs ) ,
. regs = mode_2592x1940_regs ,
} ,
} ;
/**
* to_imx335 ( ) - imx335 V4L2 sub - device to imx335 device .
* @ subdev : pointer to imx335 V4L2 sub - device
*
* Return : pointer to imx335 device
*/
static inline struct imx335 * to_imx335 ( struct v4l2_subdev * subdev )
{
return container_of ( subdev , struct imx335 , sd ) ;
}
/**
* imx335_read_reg ( ) - Read registers .
* @ imx335 : pointer to imx335 device
* @ reg : register address
* @ len : length of bytes to read . Max supported bytes is 4
* @ val : pointer to register value to be filled .
*
* Big endian register addresses with little endian values .
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_read_reg ( struct imx335 * imx335 , u16 reg , u32 len , u32 * val )
{
struct i2c_client * client = v4l2_get_subdevdata ( & imx335 - > sd ) ;
struct i2c_msg msgs [ 2 ] = { 0 } ;
u8 addr_buf [ 2 ] = { 0 } ;
u8 data_buf [ 4 ] = { 0 } ;
int ret ;
if ( WARN_ON ( len > 4 ) )
return - EINVAL ;
put_unaligned_be16 ( reg , addr_buf ) ;
/* Write register address */
msgs [ 0 ] . addr = client - > addr ;
msgs [ 0 ] . flags = 0 ;
msgs [ 0 ] . len = ARRAY_SIZE ( addr_buf ) ;
msgs [ 0 ] . buf = addr_buf ;
/* Read data from register */
msgs [ 1 ] . addr = client - > addr ;
msgs [ 1 ] . flags = I2C_M_RD ;
msgs [ 1 ] . len = len ;
msgs [ 1 ] . buf = data_buf ;
ret = i2c_transfer ( client - > adapter , msgs , ARRAY_SIZE ( msgs ) ) ;
if ( ret ! = ARRAY_SIZE ( msgs ) )
return - EIO ;
* val = get_unaligned_le32 ( data_buf ) ;
return 0 ;
}
/**
* imx335_write_reg ( ) - Write register
* @ imx335 : pointer to imx335 device
* @ reg : register address
* @ len : length of bytes . Max supported bytes is 4
* @ val : register value
*
* Big endian register addresses with little endian values .
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_write_reg ( struct imx335 * imx335 , u16 reg , u32 len , u32 val )
{
struct i2c_client * client = v4l2_get_subdevdata ( & imx335 - > sd ) ;
u8 buf [ 6 ] = { 0 } ;
if ( WARN_ON ( len > 4 ) )
return - EINVAL ;
put_unaligned_be16 ( reg , buf ) ;
put_unaligned_le32 ( val , buf + 2 ) ;
if ( i2c_master_send ( client , buf , len + 2 ) ! = len + 2 )
return - EIO ;
return 0 ;
}
/**
* imx335_write_regs ( ) - Write a list of registers
* @ imx335 : pointer to imx335 device
* @ regs : list of registers to be written
* @ len : length of registers array
*
* Return : 0 if successful . error code otherwise .
*/
static int imx335_write_regs ( struct imx335 * imx335 ,
const struct imx335_reg * regs , u32 len )
{
unsigned int i ;
int ret ;
for ( i = 0 ; i < len ; i + + ) {
ret = imx335_write_reg ( imx335 , regs [ i ] . address , 1 , regs [ i ] . val ) ;
if ( ret )
return ret ;
}
return 0 ;
}
/**
* imx335_update_controls ( ) - Update control ranges based on streaming mode
* @ imx335 : pointer to imx335 device
* @ mode : pointer to imx335_mode sensor mode
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_update_controls ( struct imx335 * imx335 ,
const struct imx335_mode * mode )
{
int ret ;
ret = __v4l2_ctrl_s_ctrl ( imx335 - > link_freq_ctrl , mode - > link_freq_idx ) ;
if ( ret )
return ret ;
ret = __v4l2_ctrl_s_ctrl ( imx335 - > hblank_ctrl , mode - > hblank ) ;
if ( ret )
return ret ;
return __v4l2_ctrl_modify_range ( imx335 - > vblank_ctrl , mode - > vblank_min ,
mode - > vblank_max , 1 , mode - > vblank ) ;
}
/**
* imx335_update_exp_gain ( ) - Set updated exposure and gain
* @ imx335 : pointer to imx335 device
* @ exposure : updated exposure value
* @ gain : updated analog gain value
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_update_exp_gain ( struct imx335 * imx335 , u32 exposure , u32 gain )
{
u32 lpfr , shutter ;
int ret ;
lpfr = imx335 - > vblank + imx335 - > cur_mode - > height ;
shutter = lpfr - exposure ;
2023-12-11 15:59:44 +03:00
dev_dbg ( imx335 - > dev , " Set exp %u, analog gain %u, shutter %u, lpfr %u \n " ,
2021-05-27 17:21:41 +03:00
exposure , gain , shutter , lpfr ) ;
ret = imx335_write_reg ( imx335 , IMX335_REG_HOLD , 1 , 1 ) ;
if ( ret )
return ret ;
ret = imx335_write_reg ( imx335 , IMX335_REG_LPFR , 3 , lpfr ) ;
if ( ret )
goto error_release_group_hold ;
ret = imx335_write_reg ( imx335 , IMX335_REG_SHUTTER , 3 , shutter ) ;
if ( ret )
goto error_release_group_hold ;
ret = imx335_write_reg ( imx335 , IMX335_REG_AGAIN , 2 , gain ) ;
error_release_group_hold :
imx335_write_reg ( imx335 , IMX335_REG_HOLD , 1 , 0 ) ;
return ret ;
}
/**
* imx335_set_ctrl ( ) - Set subdevice control
* @ ctrl : pointer to v4l2_ctrl structure
*
* Supported controls :
* - V4L2_CID_VBLANK
* - cluster controls :
* - V4L2_CID_ANALOGUE_GAIN
* - V4L2_CID_EXPOSURE
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_set_ctrl ( struct v4l2_ctrl * ctrl )
{
struct imx335 * imx335 =
container_of ( ctrl - > handler , struct imx335 , ctrl_handler ) ;
u32 analog_gain ;
u32 exposure ;
int ret ;
switch ( ctrl - > id ) {
case V4L2_CID_VBLANK :
imx335 - > vblank = imx335 - > vblank_ctrl - > val ;
2023-12-11 15:59:44 +03:00
dev_dbg ( imx335 - > dev , " Received vblank %u, new lpfr %u \n " ,
2021-05-27 17:21:41 +03:00
imx335 - > vblank ,
imx335 - > vblank + imx335 - > cur_mode - > height ) ;
ret = __v4l2_ctrl_modify_range ( imx335 - > exp_ctrl ,
IMX335_EXPOSURE_MIN ,
imx335 - > vblank +
imx335 - > cur_mode - > height -
IMX335_EXPOSURE_OFFSET ,
1 , IMX335_EXPOSURE_DEFAULT ) ;
break ;
case V4L2_CID_EXPOSURE :
/* Set controls only if sensor is in power on state */
if ( ! pm_runtime_get_if_in_use ( imx335 - > dev ) )
return 0 ;
exposure = ctrl - > val ;
analog_gain = imx335 - > again_ctrl - > val ;
2023-12-11 15:59:44 +03:00
dev_dbg ( imx335 - > dev , " Received exp %u, analog gain %u \n " ,
2021-05-27 17:21:41 +03:00
exposure , analog_gain ) ;
ret = imx335_update_exp_gain ( imx335 , exposure , analog_gain ) ;
pm_runtime_put ( imx335 - > dev ) ;
break ;
default :
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " Invalid control %d \n " , ctrl - > id ) ;
2021-05-27 17:21:41 +03:00
ret = - EINVAL ;
}
return ret ;
}
/* V4l2 subdevice control ops*/
static const struct v4l2_ctrl_ops imx335_ctrl_ops = {
. s_ctrl = imx335_set_ctrl ,
} ;
2023-12-11 15:59:49 +03:00
static int imx335_get_format_code ( struct imx335 * imx335 , u32 code )
{
unsigned int i ;
for ( i = 0 ; i < ARRAY_SIZE ( imx335_mbus_codes ) ; i + + ) {
if ( imx335_mbus_codes [ i ] = = code )
return imx335_mbus_codes [ i ] ;
}
return imx335_mbus_codes [ 0 ] ;
}
2021-05-27 17:21:41 +03:00
/**
* imx335_enum_mbus_code ( ) - Enumerate V4L2 sub - device mbus codes
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
* @ code : V4L2 sub - device code enumeration need to be filled
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_enum_mbus_code ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_mbus_code_enum * code )
{
2023-12-11 15:59:49 +03:00
if ( code - > index > = ARRAY_SIZE ( imx335_mbus_codes ) )
2021-05-27 17:21:41 +03:00
return - EINVAL ;
2023-12-11 15:59:49 +03:00
code - > code = imx335_mbus_codes [ code - > index ] ;
2021-05-27 17:21:41 +03:00
return 0 ;
}
/**
* imx335_enum_frame_size ( ) - Enumerate V4L2 sub - device frame sizes
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
* @ fsize : V4L2 sub - device size enumeration need to be filled
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_enum_frame_size ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_frame_size_enum * fsize )
{
2023-12-11 15:59:49 +03:00
struct imx335 * imx335 = to_imx335 ( sd ) ;
u32 code ;
if ( fsize - > index > ARRAY_SIZE ( imx335_mbus_codes ) )
2021-05-27 17:21:41 +03:00
return - EINVAL ;
2023-12-11 15:59:49 +03:00
code = imx335_get_format_code ( imx335 , fsize - > code ) ;
if ( fsize - > code ! = code )
2021-05-27 17:21:41 +03:00
return - EINVAL ;
fsize - > min_width = supported_mode . width ;
fsize - > max_width = fsize - > min_width ;
fsize - > min_height = supported_mode . height ;
fsize - > max_height = fsize - > min_height ;
return 0 ;
}
/**
* imx335_fill_pad_format ( ) - Fill subdevice pad format
* from selected sensor mode
* @ imx335 : pointer to imx335 device
* @ mode : pointer to imx335_mode sensor mode
* @ fmt : V4L2 sub - device format need to be filled
*/
static void imx335_fill_pad_format ( struct imx335 * imx335 ,
const struct imx335_mode * mode ,
struct v4l2_subdev_format * fmt )
{
fmt - > format . width = mode - > width ;
fmt - > format . height = mode - > height ;
2023-12-11 15:59:49 +03:00
fmt - > format . code = imx335 - > cur_mbus_code ;
2021-05-27 17:21:41 +03:00
fmt - > format . field = V4L2_FIELD_NONE ;
fmt - > format . colorspace = V4L2_COLORSPACE_RAW ;
fmt - > format . ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT ;
fmt - > format . quantization = V4L2_QUANTIZATION_DEFAULT ;
fmt - > format . xfer_func = V4L2_XFER_FUNC_NONE ;
}
/**
* imx335_get_pad_format ( ) - Get subdevice pad format
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
* @ fmt : V4L2 sub - device format need to be set
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_get_pad_format ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_format * fmt )
{
struct imx335 * imx335 = to_imx335 ( sd ) ;
mutex_lock ( & imx335 - > mutex ) ;
if ( fmt - > which = = V4L2_SUBDEV_FORMAT_TRY ) {
struct v4l2_mbus_framefmt * framefmt ;
media: v4l: subdev: Switch to stream-aware state functions
Switch all drivers accessing sub-device state to use the stream-aware
functions. We will soon remove the old ones.
This patch has been generated using the following Coccinelle script:
---------8<------------
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_format(E1, E2, E3)
+ v4l2_subdev_state_get_format(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_crop(E1, E2, E3)
+ v4l2_subdev_state_get_crop(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_compose(E1, E2, E3)
+ v4l2_subdev_state_get_compose(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_format(E1, E2, E3)
+ v4l2_subdev_state_get_format(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_crop(E1, E2, E3)
+ v4l2_subdev_state_get_crop(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_compose(E1, E2, E3)
+ v4l2_subdev_state_get_compose(E2, E3)
---------8<------------
Additionally drivers/media/i2c/s5k5baf.c and
drivers/media/platform/samsung/s3c-camif/camif-capture.c have been
manually changed as Coccinelle didn't. Further local variables have been
removed as they became unused as a result of the other changes.
Also Coccinelle introduced indentation by space in files
drivers/media/i2c/st-mipid02.c and
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also
corrected.
The diff from Coccinelle-generated changes are:
> diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c
> index e549692ff478..420984382173 100644
> --- b/drivers/media/i2c/imx319.c
> +++ a/drivers/media/i2c/imx319.c
> @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &imx319->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c
> index 96bdde685d65..e1b1d2fc79dd 100644
> --- b/drivers/media/i2c/imx355.c
> +++ a/drivers/media/i2c/imx355.c
> @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &imx355->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c
> index ca799bbcfdb7..abbb0b774d43 100644
> --- b/drivers/media/i2c/ov08x40.c
> +++ a/drivers/media/i2c/ov08x40.c
> @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov08x->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c
> index 7816d9787c61..09387e335d80 100644
> --- b/drivers/media/i2c/ov13858.c
> +++ a/drivers/media/i2c/ov13858.c
> @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov13858->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c
> index 268cd4b03f9c..c06411d5ee2b 100644
> --- b/drivers/media/i2c/ov13b10.c
> +++ a/drivers/media/i2c/ov13b10.c
> @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov13b->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> index 47605e36bc60..8f9b5713daf7 100644
> --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state,
> struct v4l2_subdev_format *fmt,
> const struct s5c73m3_frame_size **fs)
> {
> - struct v4l2_subdev *sd = &state->sensor_sd;
> u32 code;
>
> switch (fmt->pad) {
> diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
> index 67da2045f543..03ccfb0e1e11 100644
> --- a/drivers/media/i2c/s5k5baf.c
> +++ b/drivers/media/i2c/s5k5baf.c
> @@ -1472,14 +1472,11 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
>
> if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
> rects = (struct v4l2_rect * []) {
> - &s5k5baf_cis_rect,
> - v4l2_subdev_get_try_crop(sd, sd_state,
> - PAD_CIS),
> - v4l2_subdev_get_try_compose(sd, sd_state,
> - PAD_CIS),
> - v4l2_subdev_get_try_crop(sd, sd_state,
> - PAD_OUT)
> - };
> + &s5k5baf_cis_rect,
> + v4l2_subdev_state_get_crop(sd_state, PAD_CIS),
> + v4l2_subdev_state_get_compose(sd_state, PAD_CIS),
> + v4l2_subdev_state_get_crop(sd_state, PAD_OUT)
> + };
> s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
> return 0;
> }
> diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> index 295e083f38e8..be58260ea67e 100644
> --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
> struct v4l2_mbus_framefmt *mf = &fmt->format;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> fmt->format = *mf;
> return 0;
> }
> @@ -1305,7 +1305,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
> __camif_subdev_try_format(camif, mf, fmt->pad);
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> *mf = fmt->format;
> mutex_unlock(&camif->lock);
> return 0;
> diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c
> index cea454ed9c20..61433744c6c4 100644
> --- b/drivers/media/platform/ti/cal/cal-camerarx.c
> +++ a/drivers/media/platform/ti/cal/cal-camerarx.c
> @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
> struct v4l2_subdev_state *state,
> struct v4l2_subdev_mbus_code_enum *code)
> {
> - struct cal_camerarx *phy = to_cal_camerarx(sd);
> -
> /* No transcoding, source and sink codes must match. */
> if (cal_rx_pad_is_source(code->pad)) {
> struct v4l2_mbus_framefmt *fmt;
> diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c
> index dd558fac6477..61d69f19657e 100644
> --- b/drivers/staging/media/imx/imx-ic-prp.c
> +++ a/drivers/staging/media/imx/imx-ic-prp.c
> @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt *
> __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state,
> unsigned int pad, enum v4l2_subdev_format_whence which)
> {
> - struct imx_ic_priv *ic_priv = priv->ic_priv;
> -
> if (which == V4L2_SUBDEV_FORMAT_TRY)
> return v4l2_subdev_state_get_format(sd_state, pad);
> else
> diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c
> index 02db7dbb884b..ec73c901079e 100644
> --- b/drivers/staging/media/imx/imx-ic-prpencvf.c
> +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c
> @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt *
> __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state,
> unsigned int pad, enum v4l2_subdev_format_whence which)
> {
> - struct imx_ic_priv *ic_priv = priv->ic_priv;
> -
> if (which == V4L2_SUBDEV_FORMAT_TRY)
> return v4l2_subdev_state_get_format(sd_state, pad);
> else
> diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
> index 9c9361354c00..b08a249b5fdd 100644
> --- a/drivers/media/i2c/st-mipid02.c
> +++ b/drivers/media/i2c/st-mipid02.c
> @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd,
> format->format = bridge->fmt;
> else
> format->format = *v4l2_subdev_state_get_format(sd_state,
> - MIPID02_SINK_0);
> + MIPID02_SINK_0);
>
> /* but code may need to be converted */
> format->format.code = serial_to_parallel_code(format->format.code);
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> index 117912d3bfbd..96353648c032 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
> rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);
>
> src_fmt = v4l2_subdev_state_get_format(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
> src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
>
> if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
> @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
> sink_fmt = v4l2_subdev_state_get_format(sd_state,
> RKISP1_ISP_PAD_SINK_VIDEO);
> src_fmt = v4l2_subdev_state_get_format(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
> src_crop = v4l2_subdev_state_get_crop(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
>
> /*
> * Media bus code. The ISP can operate in pass-through mode (Bayer in,
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 10:37:10 +03:00
framefmt = v4l2_subdev_state_get_format ( sd_state , fmt - > pad ) ;
2021-05-27 17:21:41 +03:00
fmt - > format = * framefmt ;
} else {
imx335_fill_pad_format ( imx335 , imx335 - > cur_mode , fmt ) ;
}
mutex_unlock ( & imx335 - > mutex ) ;
return 0 ;
}
/**
* imx335_set_pad_format ( ) - Set subdevice pad format
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
* @ fmt : V4L2 sub - device format need to be set
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_set_pad_format ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_format * fmt )
{
struct imx335 * imx335 = to_imx335 ( sd ) ;
const struct imx335_mode * mode ;
2023-12-11 15:59:49 +03:00
int i , ret = 0 ;
2021-05-27 17:21:41 +03:00
mutex_lock ( & imx335 - > mutex ) ;
mode = & supported_mode ;
2023-12-11 15:59:49 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( imx335_mbus_codes ) ; i + + ) {
if ( imx335_mbus_codes [ i ] = = fmt - > format . code )
imx335 - > cur_mbus_code = imx335_mbus_codes [ i ] ;
}
2021-05-27 17:21:41 +03:00
imx335_fill_pad_format ( imx335 , mode , fmt ) ;
if ( fmt - > which = = V4L2_SUBDEV_FORMAT_TRY ) {
struct v4l2_mbus_framefmt * framefmt ;
media: v4l: subdev: Switch to stream-aware state functions
Switch all drivers accessing sub-device state to use the stream-aware
functions. We will soon remove the old ones.
This patch has been generated using the following Coccinelle script:
---------8<------------
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_format(E1, E2, E3)
+ v4l2_subdev_state_get_format(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_crop(E1, E2, E3)
+ v4l2_subdev_state_get_crop(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_pad_compose(E1, E2, E3)
+ v4l2_subdev_state_get_compose(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_format(E1, E2, E3)
+ v4l2_subdev_state_get_format(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_crop(E1, E2, E3)
+ v4l2_subdev_state_get_crop(E2, E3)
@@
expression E1, E2, E3;
@@
- v4l2_subdev_get_try_compose(E1, E2, E3)
+ v4l2_subdev_state_get_compose(E2, E3)
---------8<------------
Additionally drivers/media/i2c/s5k5baf.c and
drivers/media/platform/samsung/s3c-camif/camif-capture.c have been
manually changed as Coccinelle didn't. Further local variables have been
removed as they became unused as a result of the other changes.
Also Coccinelle introduced indentation by space in files
drivers/media/i2c/st-mipid02.c and
drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c. This has been also
corrected.
The diff from Coccinelle-generated changes are:
> diff --git b/drivers/media/i2c/imx319.c a/drivers/media/i2c/imx319.c
> index e549692ff478..420984382173 100644
> --- b/drivers/media/i2c/imx319.c
> +++ a/drivers/media/i2c/imx319.c
> @@ -2001,7 +2001,6 @@ static int imx319_do_get_pad_format(struct imx319 *imx319,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &imx319->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/imx355.c a/drivers/media/i2c/imx355.c
> index 96bdde685d65..e1b1d2fc79dd 100644
> --- b/drivers/media/i2c/imx355.c
> +++ a/drivers/media/i2c/imx355.c
> @@ -1299,7 +1299,6 @@ static int imx355_do_get_pad_format(struct imx355 *imx355,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &imx355->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov08x40.c a/drivers/media/i2c/ov08x40.c
> index ca799bbcfdb7..abbb0b774d43 100644
> --- b/drivers/media/i2c/ov08x40.c
> +++ a/drivers/media/i2c/ov08x40.c
> @@ -2774,7 +2774,6 @@ static int ov08x40_do_get_pad_format(struct ov08x40 *ov08x,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov08x->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov13858.c a/drivers/media/i2c/ov13858.c
> index 7816d9787c61..09387e335d80 100644
> --- b/drivers/media/i2c/ov13858.c
> +++ a/drivers/media/i2c/ov13858.c
> @@ -1316,7 +1316,6 @@ static int ov13858_do_get_pad_format(struct ov13858 *ov13858,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov13858->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/ov13b10.c a/drivers/media/i2c/ov13b10.c
> index 268cd4b03f9c..c06411d5ee2b 100644
> --- b/drivers/media/i2c/ov13b10.c
> +++ a/drivers/media/i2c/ov13b10.c
> @@ -1001,7 +1001,6 @@ static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b,
> struct v4l2_subdev_format *fmt)
> {
> struct v4l2_mbus_framefmt *framefmt;
> - struct v4l2_subdev *sd = &ov13b->sd;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> diff --git b/drivers/media/i2c/s5c73m3/s5c73m3-core.c a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> index 47605e36bc60..8f9b5713daf7 100644
> --- b/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> +++ a/drivers/media/i2c/s5c73m3/s5c73m3-core.c
> @@ -819,7 +819,6 @@ static void s5c73m3_oif_try_format(struct s5c73m3 *state,
> struct v4l2_subdev_format *fmt,
> const struct s5c73m3_frame_size **fs)
> {
> - struct v4l2_subdev *sd = &state->sensor_sd;
> u32 code;
>
> switch (fmt->pad) {
> diff --git a/drivers/media/i2c/s5k5baf.c b/drivers/media/i2c/s5k5baf.c
> index 67da2045f543..03ccfb0e1e11 100644
> --- a/drivers/media/i2c/s5k5baf.c
> +++ b/drivers/media/i2c/s5k5baf.c
> @@ -1472,14 +1472,11 @@ static int s5k5baf_set_selection(struct v4l2_subdev *sd,
>
> if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
> rects = (struct v4l2_rect * []) {
> - &s5k5baf_cis_rect,
> - v4l2_subdev_get_try_crop(sd, sd_state,
> - PAD_CIS),
> - v4l2_subdev_get_try_compose(sd, sd_state,
> - PAD_CIS),
> - v4l2_subdev_get_try_crop(sd, sd_state,
> - PAD_OUT)
> - };
> + &s5k5baf_cis_rect,
> + v4l2_subdev_state_get_crop(sd_state, PAD_CIS),
> + v4l2_subdev_state_get_compose(sd_state, PAD_CIS),
> + v4l2_subdev_state_get_crop(sd_state, PAD_OUT)
> + };
> s5k5baf_set_rect_and_adjust(rects, rtype, &sel->r);
> return 0;
> }
> diff --git b/drivers/media/platform/samsung/s3c-camif/camif-capture.c a/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> index 295e083f38e8..be58260ea67e 100644
> --- b/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> +++ a/drivers/media/platform/samsung/s3c-camif/camif-capture.c
> @@ -1216,7 +1216,7 @@ static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
> struct v4l2_mbus_framefmt *mf = &fmt->format;
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> fmt->format = *mf;
> return 0;
> }
> @@ -1305,7 +1305,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
> __camif_subdev_try_format(camif, mf, fmt->pad);
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> - mf = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> + mf = v4l2_subdev_state_get_format(sd_state, fmt->pad);
> *mf = fmt->format;
> mutex_unlock(&camif->lock);
> return 0;
> diff --git b/drivers/media/platform/ti/cal/cal-camerarx.c a/drivers/media/platform/ti/cal/cal-camerarx.c
> index cea454ed9c20..61433744c6c4 100644
> --- b/drivers/media/platform/ti/cal/cal-camerarx.c
> +++ a/drivers/media/platform/ti/cal/cal-camerarx.c
> @@ -621,8 +621,6 @@ static int cal_camerarx_sd_enum_mbus_code(struct v4l2_subdev *sd,
> struct v4l2_subdev_state *state,
> struct v4l2_subdev_mbus_code_enum *code)
> {
> - struct cal_camerarx *phy = to_cal_camerarx(sd);
> -
> /* No transcoding, source and sink codes must match. */
> if (cal_rx_pad_is_source(code->pad)) {
> struct v4l2_mbus_framefmt *fmt;
> diff --git b/drivers/staging/media/imx/imx-ic-prp.c a/drivers/staging/media/imx/imx-ic-prp.c
> index dd558fac6477..61d69f19657e 100644
> --- b/drivers/staging/media/imx/imx-ic-prp.c
> +++ a/drivers/staging/media/imx/imx-ic-prp.c
> @@ -82,8 +82,6 @@ static struct v4l2_mbus_framefmt *
> __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state,
> unsigned int pad, enum v4l2_subdev_format_whence which)
> {
> - struct imx_ic_priv *ic_priv = priv->ic_priv;
> -
> if (which == V4L2_SUBDEV_FORMAT_TRY)
> return v4l2_subdev_state_get_format(sd_state, pad);
> else
> diff --git b/drivers/staging/media/imx/imx-ic-prpencvf.c a/drivers/staging/media/imx/imx-ic-prpencvf.c
> index 02db7dbb884b..ec73c901079e 100644
> --- b/drivers/staging/media/imx/imx-ic-prpencvf.c
> +++ a/drivers/staging/media/imx/imx-ic-prpencvf.c
> @@ -790,8 +790,6 @@ static struct v4l2_mbus_framefmt *
> __prp_get_fmt(struct prp_priv *priv, struct v4l2_subdev_state *sd_state,
> unsigned int pad, enum v4l2_subdev_format_whence which)
> {
> - struct imx_ic_priv *ic_priv = priv->ic_priv;
> -
> if (which == V4L2_SUBDEV_FORMAT_TRY)
> return v4l2_subdev_state_get_format(sd_state, pad);
> else
> diff --git a/drivers/media/i2c/st-mipid02.c b/drivers/media/i2c/st-mipid02.c
> index 9c9361354c00..b08a249b5fdd 100644
> --- a/drivers/media/i2c/st-mipid02.c
> +++ b/drivers/media/i2c/st-mipid02.c
> @@ -751,7 +751,7 @@ static void mipid02_set_fmt_source(struct v4l2_subdev *sd,
> format->format = bridge->fmt;
> else
> format->format = *v4l2_subdev_state_get_format(sd_state,
> - MIPID02_SINK_0);
> + MIPID02_SINK_0);
>
> /* but code may need to be converted */
> format->format.code = serial_to_parallel_code(format->format.code);
> diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> index 117912d3bfbd..96353648c032 100644
> --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c
> @@ -319,7 +319,7 @@ static void rkisp1_isp_start(struct rkisp1_isp *isp,
> rkisp1_write(rkisp1, RKISP1_CIF_ISP_CTRL, val);
>
> src_fmt = v4l2_subdev_state_get_format(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
> src_info = rkisp1_mbus_info_get_by_code(src_fmt->code);
>
> if (src_info->pixel_enc != V4L2_PIXEL_ENC_BAYER)
> @@ -475,9 +475,9 @@ static void rkisp1_isp_set_src_fmt(struct rkisp1_isp *isp,
> sink_fmt = v4l2_subdev_state_get_format(sd_state,
> RKISP1_ISP_PAD_SINK_VIDEO);
> src_fmt = v4l2_subdev_state_get_format(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
> src_crop = v4l2_subdev_state_get_crop(sd_state,
> - RKISP1_ISP_PAD_SOURCE_VIDEO);
> + RKISP1_ISP_PAD_SOURCE_VIDEO);
>
> /*
> * Media bus code. The ISP can operate in pass-through mode (Bayer in,
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2023-10-13 10:37:10 +03:00
framefmt = v4l2_subdev_state_get_format ( sd_state , fmt - > pad ) ;
2021-05-27 17:21:41 +03:00
* framefmt = fmt - > format ;
} else {
ret = imx335_update_controls ( imx335 , mode ) ;
if ( ! ret )
imx335 - > cur_mode = mode ;
}
mutex_unlock ( & imx335 - > mutex ) ;
return ret ;
}
/**
2023-11-27 12:07:44 +03:00
* imx335_init_state ( ) - Initialize sub - device state
2021-05-27 17:21:41 +03:00
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
*
* Return : 0 if successful , error code otherwise .
*/
2023-11-27 12:07:44 +03:00
static int imx335_init_state ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state )
2021-05-27 17:21:41 +03:00
{
struct imx335 * imx335 = to_imx335 ( sd ) ;
struct v4l2_subdev_format fmt = { 0 } ;
fmt . which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE ;
imx335_fill_pad_format ( imx335 , & supported_mode , & fmt ) ;
return imx335_set_pad_format ( sd , sd_state , & fmt ) ;
}
2023-12-11 15:59:47 +03:00
/**
* imx335_get_selection ( ) - Selection API
* @ sd : pointer to imx335 V4L2 sub - device structure
* @ sd_state : V4L2 sub - device configuration
* @ sel : V4L2 selection info
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_get_selection ( struct v4l2_subdev * sd ,
struct v4l2_subdev_state * sd_state ,
struct v4l2_subdev_selection * sel )
{
switch ( sel - > target ) {
case V4L2_SEL_TGT_NATIVE_SIZE :
sel - > r . top = 0 ;
sel - > r . left = 0 ;
sel - > r . width = IMX335_NATIVE_WIDTH ;
sel - > r . height = IMX335_NATIVE_HEIGHT ;
return 0 ;
case V4L2_SEL_TGT_CROP :
case V4L2_SEL_TGT_CROP_DEFAULT :
case V4L2_SEL_TGT_CROP_BOUNDS :
sel - > r . top = IMX335_PIXEL_ARRAY_TOP ;
sel - > r . left = IMX335_PIXEL_ARRAY_LEFT ;
sel - > r . width = IMX335_PIXEL_ARRAY_WIDTH ;
sel - > r . height = IMX335_PIXEL_ARRAY_HEIGHT ;
return 0 ;
}
return - EINVAL ;
}
2023-12-11 15:59:49 +03:00
static int imx335_set_framefmt ( struct imx335 * imx335 )
{
switch ( imx335 - > cur_mbus_code ) {
case MEDIA_BUS_FMT_SRGGB10_1X10 :
return imx335_write_regs ( imx335 , raw10_framefmt_regs ,
ARRAY_SIZE ( raw10_framefmt_regs ) ) ;
case MEDIA_BUS_FMT_SRGGB12_1X12 :
return imx335_write_regs ( imx335 , raw12_framefmt_regs ,
ARRAY_SIZE ( raw12_framefmt_regs ) ) ;
}
return - EINVAL ;
}
2021-05-27 17:21:41 +03:00
/**
* imx335_start_streaming ( ) - Start sensor stream
* @ imx335 : pointer to imx335 device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_start_streaming ( struct imx335 * imx335 )
{
const struct imx335_reg_list * reg_list ;
int ret ;
/* Write sensor mode registers */
reg_list = & imx335 - > cur_mode - > reg_list ;
ret = imx335_write_regs ( imx335 , reg_list - > regs ,
reg_list - > num_of_regs ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " fail to write initial registers \n " ) ;
2021-05-27 17:21:41 +03:00
return ret ;
}
2023-12-11 15:59:49 +03:00
ret = imx335_set_framefmt ( imx335 ) ;
if ( ret ) {
dev_err ( imx335 - > dev , " %s failed to set frame format: %d \n " ,
__func__ , ret ) ;
return ret ;
}
2021-05-27 17:21:41 +03:00
/* Setup handler will write actual exposure and gain */
ret = __v4l2_ctrl_handler_setup ( imx335 - > sd . ctrl_handler ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " fail to setup handler \n " ) ;
2021-05-27 17:21:41 +03:00
return ret ;
}
/* Start streaming */
ret = imx335_write_reg ( imx335 , IMX335_REG_MODE_SELECT ,
1 , IMX335_MODE_STREAMING ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " fail to start streaming \n " ) ;
2021-05-27 17:21:41 +03:00
return ret ;
}
/* Initial regulator stabilization period */
usleep_range ( 18000 , 20000 ) ;
return 0 ;
}
/**
* imx335_stop_streaming ( ) - Stop sensor stream
* @ imx335 : pointer to imx335 device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_stop_streaming ( struct imx335 * imx335 )
{
return imx335_write_reg ( imx335 , IMX335_REG_MODE_SELECT ,
1 , IMX335_MODE_STANDBY ) ;
}
/**
* imx335_set_stream ( ) - Enable sensor streaming
* @ sd : pointer to imx335 subdevice
* @ enable : set to enable sensor streaming
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_set_stream ( struct v4l2_subdev * sd , int enable )
{
struct imx335 * imx335 = to_imx335 ( sd ) ;
int ret ;
mutex_lock ( & imx335 - > mutex ) ;
if ( enable ) {
ret = pm_runtime_resume_and_get ( imx335 - > dev ) ;
if ( ret )
goto error_unlock ;
ret = imx335_start_streaming ( imx335 ) ;
if ( ret )
goto error_power_off ;
} else {
imx335_stop_streaming ( imx335 ) ;
pm_runtime_put ( imx335 - > dev ) ;
}
mutex_unlock ( & imx335 - > mutex ) ;
return 0 ;
error_power_off :
pm_runtime_put ( imx335 - > dev ) ;
error_unlock :
mutex_unlock ( & imx335 - > mutex ) ;
return ret ;
}
/**
* imx335_detect ( ) - Detect imx335 sensor
* @ imx335 : pointer to imx335 device
*
* Return : 0 if successful , - EIO if sensor id does not match
*/
static int imx335_detect ( struct imx335 * imx335 )
{
int ret ;
u32 val ;
ret = imx335_read_reg ( imx335 , IMX335_REG_ID , 2 , & val ) ;
if ( ret )
return ret ;
if ( val ! = IMX335_ID ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " chip id mismatch: %x!=%x \n " ,
2021-05-27 17:21:41 +03:00
IMX335_ID , val ) ;
return - ENXIO ;
}
return 0 ;
}
/**
* imx335_parse_hw_config ( ) - Parse HW configuration and check if supported
* @ imx335 : pointer to imx335 device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_parse_hw_config ( struct imx335 * imx335 )
{
struct fwnode_handle * fwnode = dev_fwnode ( imx335 - > dev ) ;
struct v4l2_fwnode_endpoint bus_cfg = {
. bus_type = V4L2_MBUS_CSI2_DPHY
} ;
struct fwnode_handle * ep ;
unsigned long rate ;
unsigned int i ;
int ret ;
if ( ! fwnode )
return - ENXIO ;
/* Request optional reset pin */
imx335 - > reset_gpio = devm_gpiod_get_optional ( imx335 - > dev , " reset " ,
GPIOD_OUT_LOW ) ;
if ( IS_ERR ( imx335 - > reset_gpio ) ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " failed to get reset gpio %ld \n " ,
2021-05-27 17:21:41 +03:00
PTR_ERR ( imx335 - > reset_gpio ) ) ;
return PTR_ERR ( imx335 - > reset_gpio ) ;
}
2023-12-11 15:59:46 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( imx335_supply_name ) ; i + + )
imx335 - > supplies [ i ] . supply = imx335_supply_name [ i ] ;
ret = devm_regulator_bulk_get ( imx335 - > dev ,
ARRAY_SIZE ( imx335_supply_name ) ,
imx335 - > supplies ) ;
if ( ret ) {
dev_err ( imx335 - > dev , " Failed to get regulators \n " ) ;
return ret ;
}
2021-05-27 17:21:41 +03:00
/* Get sensor input clock */
imx335 - > inclk = devm_clk_get ( imx335 - > dev , NULL ) ;
if ( IS_ERR ( imx335 - > inclk ) ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " could not get inclk \n " ) ;
2021-05-27 17:21:41 +03:00
return PTR_ERR ( imx335 - > inclk ) ;
}
rate = clk_get_rate ( imx335 - > inclk ) ;
if ( rate ! = IMX335_INCLK_RATE ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " inclk frequency mismatch \n " ) ;
2021-05-27 17:21:41 +03:00
return - EINVAL ;
}
ep = fwnode_graph_get_next_endpoint ( fwnode , NULL ) ;
2023-12-11 15:59:45 +03:00
if ( ! ep ) {
dev_err ( imx335 - > dev , " Failed to get next endpoint \n " ) ;
2021-05-27 17:21:41 +03:00
return - ENXIO ;
2023-12-11 15:59:45 +03:00
}
2021-05-27 17:21:41 +03:00
ret = v4l2_fwnode_endpoint_alloc_parse ( ep , & bus_cfg ) ;
fwnode_handle_put ( ep ) ;
if ( ret )
return ret ;
if ( bus_cfg . bus . mipi_csi2 . num_data_lanes ! = IMX335_NUM_DATA_LANES ) {
dev_err ( imx335 - > dev ,
2023-12-11 15:59:44 +03:00
" number of CSI2 data lanes %d is not supported \n " ,
2021-05-27 17:21:41 +03:00
bus_cfg . bus . mipi_csi2 . num_data_lanes ) ;
ret = - EINVAL ;
goto done_endpoint_free ;
}
if ( ! bus_cfg . nr_of_link_frequencies ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " no link frequencies defined \n " ) ;
2021-05-27 17:21:41 +03:00
ret = - EINVAL ;
goto done_endpoint_free ;
}
for ( i = 0 ; i < bus_cfg . nr_of_link_frequencies ; i + + )
if ( bus_cfg . link_frequencies [ i ] = = IMX335_LINK_FREQ )
goto done_endpoint_free ;
2023-12-11 15:59:45 +03:00
dev_err ( imx335 - > dev , " no compatible link frequencies found \n " ) ;
2021-05-27 17:21:41 +03:00
ret = - EINVAL ;
done_endpoint_free :
v4l2_fwnode_endpoint_free ( & bus_cfg ) ;
return ret ;
}
/* V4l2 subdevice ops */
static const struct v4l2_subdev_video_ops imx335_video_ops = {
. s_stream = imx335_set_stream ,
} ;
static const struct v4l2_subdev_pad_ops imx335_pad_ops = {
. enum_mbus_code = imx335_enum_mbus_code ,
. enum_frame_size = imx335_enum_frame_size ,
2023-12-11 15:59:47 +03:00
. get_selection = imx335_get_selection ,
. set_selection = imx335_get_selection ,
2021-05-27 17:21:41 +03:00
. get_fmt = imx335_get_pad_format ,
. set_fmt = imx335_set_pad_format ,
} ;
static const struct v4l2_subdev_ops imx335_subdev_ops = {
. video = & imx335_video_ops ,
. pad = & imx335_pad_ops ,
} ;
2023-11-27 12:07:44 +03:00
static const struct v4l2_subdev_internal_ops imx335_internal_ops = {
. init_state = imx335_init_state ,
} ;
2021-05-27 17:21:41 +03:00
/**
* imx335_power_on ( ) - Sensor power on sequence
* @ dev : pointer to i2c device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_power_on ( struct device * dev )
{
struct v4l2_subdev * sd = dev_get_drvdata ( dev ) ;
struct imx335 * imx335 = to_imx335 ( sd ) ;
int ret ;
2023-12-11 15:59:46 +03:00
ret = regulator_bulk_enable ( ARRAY_SIZE ( imx335_supply_name ) ,
imx335 - > supplies ) ;
if ( ret ) {
dev_err ( dev , " %s: failed to enable regulators \n " ,
__func__ ) ;
return ret ;
}
usleep_range ( 500 , 550 ) ; /* Tlow */
/* Set XCLR */
2021-05-27 17:21:41 +03:00
gpiod_set_value_cansleep ( imx335 - > reset_gpio , 1 ) ;
ret = clk_prepare_enable ( imx335 - > inclk ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " fail to enable inclk \n " ) ;
2021-05-27 17:21:41 +03:00
goto error_reset ;
}
2023-12-11 15:59:46 +03:00
usleep_range ( 20 , 22 ) ; /* T4 */
2021-05-27 17:21:41 +03:00
return 0 ;
error_reset :
gpiod_set_value_cansleep ( imx335 - > reset_gpio , 0 ) ;
2023-12-11 15:59:46 +03:00
regulator_bulk_disable ( ARRAY_SIZE ( imx335_supply_name ) , imx335 - > supplies ) ;
2021-05-27 17:21:41 +03:00
return ret ;
}
/**
* imx335_power_off ( ) - Sensor power off sequence
* @ dev : pointer to i2c device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_power_off ( struct device * dev )
{
struct v4l2_subdev * sd = dev_get_drvdata ( dev ) ;
struct imx335 * imx335 = to_imx335 ( sd ) ;
gpiod_set_value_cansleep ( imx335 - > reset_gpio , 0 ) ;
clk_disable_unprepare ( imx335 - > inclk ) ;
2023-12-11 15:59:46 +03:00
regulator_bulk_disable ( ARRAY_SIZE ( imx335_supply_name ) , imx335 - > supplies ) ;
2021-05-27 17:21:41 +03:00
return 0 ;
}
/**
* imx335_init_controls ( ) - Initialize sensor subdevice controls
* @ imx335 : pointer to imx335 device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_init_controls ( struct imx335 * imx335 )
{
struct v4l2_ctrl_handler * ctrl_hdlr = & imx335 - > ctrl_handler ;
const struct imx335_mode * mode = imx335 - > cur_mode ;
u32 lpfr ;
int ret ;
ret = v4l2_ctrl_handler_init ( ctrl_hdlr , 6 ) ;
if ( ret )
return ret ;
/* Serialize controls with sensor device */
ctrl_hdlr - > lock = & imx335 - > mutex ;
/* Initialize exposure and gain */
lpfr = mode - > vblank + mode - > height ;
imx335 - > exp_ctrl = v4l2_ctrl_new_std ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_EXPOSURE ,
IMX335_EXPOSURE_MIN ,
lpfr - IMX335_EXPOSURE_OFFSET ,
IMX335_EXPOSURE_STEP ,
IMX335_EXPOSURE_DEFAULT ) ;
imx335 - > again_ctrl = v4l2_ctrl_new_std ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_ANALOGUE_GAIN ,
IMX335_AGAIN_MIN ,
IMX335_AGAIN_MAX ,
IMX335_AGAIN_STEP ,
IMX335_AGAIN_DEFAULT ) ;
v4l2_ctrl_cluster ( 2 , & imx335 - > exp_ctrl ) ;
imx335 - > vblank_ctrl = v4l2_ctrl_new_std ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_VBLANK ,
mode - > vblank_min ,
mode - > vblank_max ,
1 , mode - > vblank ) ;
/* Read only controls */
imx335 - > pclk_ctrl = v4l2_ctrl_new_std ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_PIXEL_RATE ,
mode - > pclk , mode - > pclk ,
1 , mode - > pclk ) ;
imx335 - > link_freq_ctrl = v4l2_ctrl_new_int_menu ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_LINK_FREQ ,
ARRAY_SIZE ( link_freq ) -
1 ,
mode - > link_freq_idx ,
link_freq ) ;
if ( imx335 - > link_freq_ctrl )
imx335 - > link_freq_ctrl - > flags | = V4L2_CTRL_FLAG_READ_ONLY ;
imx335 - > hblank_ctrl = v4l2_ctrl_new_std ( ctrl_hdlr ,
& imx335_ctrl_ops ,
V4L2_CID_HBLANK ,
2023-12-11 15:59:48 +03:00
mode - > hblank ,
mode - > hblank ,
2021-05-27 17:21:41 +03:00
1 , mode - > hblank ) ;
if ( imx335 - > hblank_ctrl )
imx335 - > hblank_ctrl - > flags | = V4L2_CTRL_FLAG_READ_ONLY ;
if ( ctrl_hdlr - > error ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " control init failed: %d \n " ,
2021-05-27 17:21:41 +03:00
ctrl_hdlr - > error ) ;
v4l2_ctrl_handler_free ( ctrl_hdlr ) ;
return ctrl_hdlr - > error ;
}
imx335 - > sd . ctrl_handler = ctrl_hdlr ;
return 0 ;
}
/**
* imx335_probe ( ) - I2C client device binding
* @ client : pointer to i2c client device
*
* Return : 0 if successful , error code otherwise .
*/
static int imx335_probe ( struct i2c_client * client )
{
struct imx335 * imx335 ;
int ret ;
imx335 = devm_kzalloc ( & client - > dev , sizeof ( * imx335 ) , GFP_KERNEL ) ;
if ( ! imx335 )
return - ENOMEM ;
imx335 - > dev = & client - > dev ;
/* Initialize subdev */
v4l2_i2c_subdev_init ( & imx335 - > sd , client , & imx335_subdev_ops ) ;
2023-11-27 12:07:44 +03:00
imx335 - > sd . internal_ops = & imx335_internal_ops ;
2021-05-27 17:21:41 +03:00
ret = imx335_parse_hw_config ( imx335 ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " HW configuration is not supported \n " ) ;
2021-05-27 17:21:41 +03:00
return ret ;
}
mutex_init ( & imx335 - > mutex ) ;
ret = imx335_power_on ( imx335 - > dev ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " failed to power-on the sensor \n " ) ;
2021-05-27 17:21:41 +03:00
goto error_mutex_destroy ;
}
/* Check module identity */
ret = imx335_detect ( imx335 ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " failed to find sensor: %d \n " , ret ) ;
2021-05-27 17:21:41 +03:00
goto error_power_off ;
}
/* Set default mode to max resolution */
imx335 - > cur_mode = & supported_mode ;
2023-12-11 15:59:49 +03:00
imx335 - > cur_mbus_code = imx335_mbus_codes [ 0 ] ;
2021-05-27 17:21:41 +03:00
imx335 - > vblank = imx335 - > cur_mode - > vblank ;
ret = imx335_init_controls ( imx335 ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " failed to init controls: %d \n " , ret ) ;
2021-05-27 17:21:41 +03:00
goto error_power_off ;
}
/* Initialize subdev */
imx335 - > sd . flags | = V4L2_SUBDEV_FL_HAS_DEVNODE ;
imx335 - > sd . entity . function = MEDIA_ENT_F_CAM_SENSOR ;
/* Initialize source pad */
imx335 - > pad . flags = MEDIA_PAD_FL_SOURCE ;
ret = media_entity_pads_init ( & imx335 - > sd . entity , 1 , & imx335 - > pad ) ;
if ( ret ) {
2023-12-11 15:59:44 +03:00
dev_err ( imx335 - > dev , " failed to init entity pads: %d \n " , ret ) ;
2021-05-27 17:21:41 +03:00
goto error_handler_free ;
}
ret = v4l2_async_register_subdev_sensor ( & imx335 - > sd ) ;
if ( ret < 0 ) {
dev_err ( imx335 - > dev ,
2023-12-11 15:59:44 +03:00
" failed to register async subdev: %d \n " , ret ) ;
2021-05-27 17:21:41 +03:00
goto error_media_entity ;
}
pm_runtime_set_active ( imx335 - > dev ) ;
pm_runtime_enable ( imx335 - > dev ) ;
pm_runtime_idle ( imx335 - > dev ) ;
return 0 ;
error_media_entity :
media_entity_cleanup ( & imx335 - > sd . entity ) ;
error_handler_free :
v4l2_ctrl_handler_free ( imx335 - > sd . ctrl_handler ) ;
error_power_off :
imx335_power_off ( imx335 - > dev ) ;
error_mutex_destroy :
mutex_destroy ( & imx335 - > mutex ) ;
return ret ;
}
/**
* imx335_remove ( ) - I2C client device unbinding
* @ client : pointer to I2C client device
*
* Return : 0 if successful , error code otherwise .
*/
2022-08-15 11:02:30 +03:00
static void imx335_remove ( struct i2c_client * client )
2021-05-27 17:21:41 +03:00
{
struct v4l2_subdev * sd = i2c_get_clientdata ( client ) ;
struct imx335 * imx335 = to_imx335 ( sd ) ;
v4l2_async_unregister_subdev ( sd ) ;
media_entity_cleanup ( & sd - > entity ) ;
v4l2_ctrl_handler_free ( sd - > ctrl_handler ) ;
pm_runtime_disable ( & client - > dev ) ;
if ( ! pm_runtime_status_suspended ( & client - > dev ) )
imx335_power_off ( & client - > dev ) ;
pm_runtime_set_suspended ( & client - > dev ) ;
mutex_destroy ( & imx335 - > mutex ) ;
}
static const struct dev_pm_ops imx335_pm_ops = {
SET_RUNTIME_PM_OPS ( imx335_power_off , imx335_power_on , NULL )
} ;
static const struct of_device_id imx335_of_match [ ] = {
{ . compatible = " sony,imx335 " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , imx335_of_match ) ;
static struct i2c_driver imx335_driver = {
2023-05-14 15:04:07 +03:00
. probe = imx335_probe ,
2021-05-27 17:21:41 +03:00
. remove = imx335_remove ,
. driver = {
. name = " imx335 " ,
. pm = & imx335_pm_ops ,
. of_match_table = imx335_of_match ,
} ,
} ;
module_i2c_driver ( imx335_driver ) ;
MODULE_DESCRIPTION ( " Sony imx335 sensor driver " ) ;
MODULE_LICENSE ( " GPL " ) ;