Re: [PATCH 6/6] media: ccs: Use V4L2 CCI for accessing sensor registers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Sakari,

Thank you for the patch.

On Fri, Nov 10, 2023 at 11:47:05AM +0200, Sakari Ailus wrote:
> Use V4L2 CCI for accessing device's registers. The 8-bit compatibility
> read option is removed but this is supported by regmap through other
> means.
> 
> Also the CCS register definitions are re-generated with V4L2 CCI
> definitions. The older SMIA++ register definitions have been manually
> converted.

Unrelated to this series, could ccs-regs.h be generated as part of the
kernel build process ?

> Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx>
> ---
>  drivers/media/i2c/ccs/ccs-core.c        |  80 +-
>  drivers/media/i2c/ccs/ccs-reg-access.c  | 191 +----
>  drivers/media/i2c/ccs/ccs-regs.h        | 904 +++++++++++-----------
>  drivers/media/i2c/ccs/ccs.h             |   2 +
>  drivers/media/i2c/ccs/smiapp-reg-defs.h | 948 ++++++++++++------------
>  5 files changed, 988 insertions(+), 1137 deletions(-)
> 
> diff --git a/drivers/media/i2c/ccs/ccs-core.c b/drivers/media/i2c/ccs/ccs-core.c
> index d210b6c87db4..471bb30ab298 100644
> --- a/drivers/media/i2c/ccs/ccs-core.c
> +++ b/drivers/media/i2c/ccs/ccs-core.c
> @@ -25,8 +25,9 @@
>  #include <linux/slab.h>
>  #include <linux/smiapp.h>
>  #include <linux/v4l2-mediabus.h>
> -#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-cci.h>
>  #include <media/v4l2-device.h>
> +#include <media/v4l2-fwnode.h>

As you're also sorting includes, mediabus goes last.

>  #include <uapi/linux/ccs.h>
>  
>  #include "ccs.h"
> @@ -98,7 +99,7 @@ static int ccs_limit_ptr(struct ccs_sensor *sensor, unsigned int limit,
>  	linfo = &ccs_limits[ccs_limit_offsets[limit].info];
>  
>  	if (WARN_ON(!sensor->ccs_limits) ||
> -	    WARN_ON(offset + ccs_reg_width(linfo->reg) >
> +	    WARN_ON(offset + CCI_REG_WIDTH_BYTES(linfo->reg) >
>  		    ccs_limit_offsets[limit + 1].lim))
>  		return -EINVAL;
>  
> @@ -124,7 +125,7 @@ void ccs_replace_limit(struct ccs_sensor *sensor,
>  	dev_dbg(&client->dev, "quirk: 0x%8.8x \"%s\" %u = %u, 0x%x\n",
>  		linfo->reg, linfo->name, offset, val, val);
>  
> -	ccs_assign_limit(ptr, ccs_reg_width(linfo->reg), val);
> +	ccs_assign_limit(ptr, CCI_REG_WIDTH_BYTES(linfo->reg), val);
>  }
>  
>  u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
> @@ -138,7 +139,7 @@ u32 ccs_get_limit(struct ccs_sensor *sensor, unsigned int limit,
>  	if (ret)
>  		return 0;
>  
> -	switch (ccs_reg_width(ccs_limits[ccs_limit_offsets[limit].info].reg)) {
> +	switch (CCI_REG_WIDTH_BYTES(ccs_limits[ccs_limit_offsets[limit].info].reg)) {
>  	case sizeof(u8):
>  		val = *(u8 *)ptr;
>  		break;
> @@ -176,7 +177,7 @@ static int ccs_read_all_limits(struct ccs_sensor *sensor)
>  
>  	for (i = 0, l = 0, ptr = alloc; ccs_limits[i].size; i++) {
>  		u32 reg = ccs_limits[i].reg;
> -		unsigned int width = ccs_reg_width(reg);
> +		unsigned int width = CCI_REG_WIDTH_BYTES(reg);
>  		unsigned int j;
>  
>  		if (l == CCS_L_LAST) {
> @@ -2725,66 +2726,54 @@ static int ccs_identify_module(struct ccs_sensor *sensor)
>  	rval = ccs_read(sensor, MODULE_MANUFACTURER_ID,
>  			&minfo->mipi_manufacturer_id);
>  	if (!rval && !minfo->mipi_manufacturer_id)
> -		rval = ccs_read_addr_8only(sensor,
> -					   SMIAPP_REG_U8_MANUFACTURER_ID,
> -					   &minfo->smia_manufacturer_id);
> +		rval = ccs_read_addr(sensor, SMIAPP_REG_U8_MANUFACTURER_ID,
> +				     &minfo->smia_manufacturer_id);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_MODEL_ID,
> -					   &minfo->model_id);
> +		rval = ccs_read(sensor, MODULE_MODEL_ID, &minfo->model_id);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_MODULE_REVISION_NUMBER_MAJOR,
> -					   &rev);
> +		rval = ccs_read(sensor, MODULE_REVISION_NUMBER_MAJOR, &rev);
>  	if (!rval) {
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_MODULE_REVISION_NUMBER_MINOR,
> -					   &minfo->revision_number);
> +		rval = ccs_read(sensor, MODULE_REVISION_NUMBER_MINOR,
> +				&minfo->revision_number);
>  		minfo->revision_number |= rev << 8;
>  	}
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_YEAR,
> -					   &minfo->module_year);
> +		rval = ccs_read(sensor, MODULE_DATE_YEAR, &minfo->module_year);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_MONTH,
> -					   &minfo->module_month);
> +		rval = ccs_read(sensor, MODULE_DATE_MONTH,
> +				&minfo->module_month);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor, CCS_R_MODULE_DATE_DAY,
> -					   &minfo->module_day);
> +		rval = ccs_read(sensor, MODULE_DATE_DAY, &minfo->module_day);
>  
>  	/* Sensor info */
>  	if (!rval)
>  		rval = ccs_read(sensor, SENSOR_MANUFACTURER_ID,
>  				&minfo->sensor_mipi_manufacturer_id);
>  	if (!rval && !minfo->sensor_mipi_manufacturer_id)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_SENSOR_MANUFACTURER_ID,
> -					   &minfo->sensor_smia_manufacturer_id);
> +		rval = ccs_read(sensor, SENSOR_MANUFACTURER_ID,
> +				&minfo->sensor_smia_manufacturer_id);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_SENSOR_MODEL_ID,
> -					   &minfo->sensor_model_id);
> +		rval = ccs_read(sensor, SENSOR_MODEL_ID,
> +				&minfo->sensor_model_id);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_SENSOR_REVISION_NUMBER,
> -					   &minfo->sensor_revision_number);
> +		rval = ccs_read(sensor, SENSOR_REVISION_NUMBER,
> +				&minfo->sensor_revision_number);
>  	if (!rval && !minfo->sensor_revision_number)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_SENSOR_REVISION_NUMBER_16,
> -					   &minfo->sensor_revision_number);
> +		rval = ccs_read(sensor, SENSOR_REVISION_NUMBER_16,
> +				&minfo->sensor_revision_number);
>  	if (!rval)
> -		rval = ccs_read_addr_8only(sensor,
> -					   CCS_R_SENSOR_FIRMWARE_VERSION,
> -					   &minfo->sensor_firmware_version);
> +		rval = ccs_read(sensor, SENSOR_FIRMWARE_VERSION,
> +				&minfo->sensor_firmware_version);
>  
>  	/* SMIA */
>  	if (!rval)
>  		rval = ccs_read(sensor, MIPI_CCS_VERSION, &minfo->ccs_version);
>  	if (!rval && !minfo->ccs_version)
> -		rval = ccs_read_addr_8only(sensor, SMIAPP_REG_U8_SMIA_VERSION,
> -					   &minfo->smia_version);
> +		rval = ccs_read_addr(sensor, SMIAPP_REG_U8_SMIA_VERSION,
> +				     &minfo->smia_version);
>  	if (!rval && !minfo->ccs_version)
> -		rval = ccs_read_addr_8only(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
> -					   &minfo->smiapp_version);
> +		rval = ccs_read_addr(sensor, SMIAPP_REG_U8_SMIAPP_VERSION,
> +				     &minfo->smiapp_version);
>  
>  	if (rval) {
>  		dev_err(&client->dev, "sensor detection failed\n");
> @@ -3318,6 +3307,13 @@ static int ccs_probe(struct i2c_client *client)
>  	if (IS_ERR(sensor->xshutdown))
>  		return PTR_ERR(sensor->xshutdown);
>  
> +	sensor->regmap = devm_cci_regmap_init_i2c(client, 16);
> +	if (IS_ERR(sensor->regmap)) {
> +		dev_err(&client->dev, "can't initialise CCI (%ld)\n",
> +			PTR_ERR(sensor->regmap));
> +		return PTR_ERR(sensor->regmap);
> +	}
> +
>  	rval = ccs_power_on(&client->dev);
>  	if (rval < 0)
>  		return rval;
> @@ -3653,7 +3649,7 @@ static int ccs_module_init(void)
>  			ccs_limit_offsets[l + 1].lim =
>  				ALIGN(ccs_limit_offsets[l].lim +
>  				      ccs_limits[i].size,
> -				      ccs_reg_width(ccs_limits[i + 1].reg));
> +				      max(CCI_REG_WIDTH_BYTES(ccs_limits[i + 1].reg), 1UL));

What's the reason for the max() here ?

>  			ccs_limit_offsets[l].info = i;
>  			l++;
>  		} else {
> diff --git a/drivers/media/i2c/ccs/ccs-reg-access.c b/drivers/media/i2c/ccs/ccs-reg-access.c
> index 652d705a2ef5..81d3e2db38f1 100644
> --- a/drivers/media/i2c/ccs/ccs-reg-access.c
> +++ b/drivers/media/i2c/ccs/ccs-reg-access.c
> @@ -62,87 +62,6 @@ static u32 float_to_u32_mul_1000000(struct i2c_client *client, u32 phloat)
>  }
>  
>  
> -/*
> - * Read a 8/16/32-bit i2c register.  The value is returned in 'val'.
> - * Returns zero if successful, or non-zero otherwise.
> - */
> -static int ____ccs_read_addr(struct ccs_sensor *sensor, u16 reg, u16 len,
> -			     u32 *val)
> -{
> -	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
> -	struct i2c_msg msg;
> -	unsigned char data_buf[sizeof(u32)] = { 0 };
> -	unsigned char offset_buf[sizeof(u16)];
> -	int r;
> -
> -	if (len > sizeof(data_buf))
> -		return -EINVAL;
> -
> -	msg.addr = client->addr;
> -	msg.flags = 0;
> -	msg.len = sizeof(offset_buf);
> -	msg.buf = offset_buf;
> -	put_unaligned_be16(reg, offset_buf);
> -
> -	r = i2c_transfer(client->adapter, &msg, 1);
> -	if (r != 1) {
> -		if (r >= 0)
> -			r = -EBUSY;
> -		goto err;
> -	}
> -
> -	msg.len = len;
> -	msg.flags = I2C_M_RD;
> -	msg.buf = &data_buf[sizeof(data_buf) - len];
> -
> -	r = i2c_transfer(client->adapter, &msg, 1);
> -	if (r != 1) {
> -		if (r >= 0)
> -			r = -EBUSY;
> -		goto err;
> -	}
> -
> -	*val = get_unaligned_be32(data_buf);
> -
> -	return 0;
> -
> -err:
> -	dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r);
> -
> -	return r;
> -}
> -
> -/* Read a register using 8-bit access only. */
> -static int ____ccs_read_addr_8only(struct ccs_sensor *sensor, u16 reg,
> -				   u16 len, u32 *val)
> -{
> -	unsigned int i;
> -	int rval;
> -
> -	*val = 0;
> -
> -	for (i = 0; i < len; i++) {
> -		u32 val8;
> -
> -		rval = ____ccs_read_addr(sensor, reg + i, 1, &val8);
> -		if (rval < 0)
> -			return rval;
> -		*val |= val8 << ((len - i - 1) << 3);
> -	}
> -
> -	return 0;
> -}
> -
> -unsigned int ccs_reg_width(u32 reg)
> -{
> -	if (reg & CCS_FL_16BIT)
> -		return sizeof(u16);
> -	if (reg & CCS_FL_32BIT)
> -		return sizeof(u32);
> -
> -	return sizeof(u8);
> -}
> -
>  static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val)
>  {
>  	if (val >> 10 > U32_MAX / 15625) {
> @@ -178,21 +97,14 @@ u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val)
>  static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val,
>  			   bool only8, bool conv)
>  {
> -	unsigned int len = ccs_reg_width(reg);
> +	u64 __val;
>  	int rval;
>  
> -	if (!only8)
> -		rval = ____ccs_read_addr(sensor, CCS_REG_ADDR(reg), len, val);
> -	else
> -		rval = ____ccs_read_addr_8only(sensor, CCS_REG_ADDR(reg), len,
> -					       val);
> +	rval = cci_read(sensor->regmap, reg, &__val, NULL);
>  	if (rval < 0)
>  		return rval;
>  
> -	if (!conv)
> -		return 0;
> -
> -	*val = ccs_reg_conv(sensor, reg, *val);
> +	*val = conv ? ccs_reg_conv(sensor, reg, __val) : __val;
>  
>  	return 0;
>  }
> @@ -200,7 +112,7 @@ static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val,
>  static int __ccs_static_read_only(struct ccs_reg *regs, size_t num_regs,
>  				  u32 reg, u32 *val)
>  {
> -	unsigned int width = ccs_reg_width(reg);
> +	unsigned int width = CCI_REG_WIDTH_BYTES(reg);
>  	size_t i;
>  
>  	for (i = 0; i < num_regs; i++, regs++) {
> @@ -291,71 +203,13 @@ int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val)
>  	return ccs_read_addr_raw(sensor, reg, val, false, true, false, true);
>  }
>  
> -static int ccs_write_retry(struct i2c_client *client, struct i2c_msg *msg)
> -{
> -	unsigned int retries;
> -	int r;
> -
> -	for (retries = 0; retries < 10; retries++) {
> -		/*
> -		 * Due to unknown reason sensor stops responding. This
> -		 * loop is a temporaty solution until the root cause
> -		 * is found.
> -		 */
> -		r = i2c_transfer(client->adapter, msg, 1);
> -		if (r != 1) {
> -			usleep_range(1000, 2000);
> -			continue;
> -		}
> -
> -		if (retries)
> -			dev_err(&client->dev,
> -				"sensor i2c stall encountered. retries: %d\n",
> -				retries);
> -		return 0;
> -	}
> -
> -	return r;
> -}
> -
> -int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val)
> -{
> -	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
> -	struct i2c_msg msg;
> -	unsigned char data[6];
> -	unsigned int len = ccs_reg_width(reg);
> -	int r;
> -
> -	if (len > sizeof(data) - 2)
> -		return -EINVAL;
> -
> -	msg.addr = client->addr;
> -	msg.flags = 0; /* Write */
> -	msg.len = 2 + len;
> -	msg.buf = data;
> -
> -	put_unaligned_be16(CCS_REG_ADDR(reg), data);
> -	put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2);
> -
> -	dev_dbg(&client->dev, "writing reg 0x%4.4x value 0x%*.*x (%u)\n",
> -		CCS_REG_ADDR(reg), ccs_reg_width(reg) << 1,
> -		ccs_reg_width(reg) << 1, val, val);
> -
> -	r = ccs_write_retry(client, &msg);
> -	if (r)
> -		dev_err(&client->dev,
> -			"wrote 0x%x to offset 0x%x error %d\n", val,
> -			CCS_REG_ADDR(reg), r);
> -
> -	return r;
> -}
> -
>  /*
>   * Write to a 8/16-bit register.
>   * Returns zero if successful, or non-zero otherwise.
>   */
>  int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
>  {
> +	unsigned int retries = 10;

This is really not nice, but unrelated to this patch.

>  	int rval;
>  
>  	rval = ccs_call_quirk(sensor, reg_access, true, &reg, &val);
> @@ -364,7 +218,12 @@ int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val)
>  	if (rval < 0)
>  		return rval;

Here you test rval < 0, but below cci_write() will consider any positive
value as an error too. There may not be an actual bug if the function
call above doesn't return positive values, but it's error-prone
nonetheless.

>  
> -	return ccs_write_addr_no_quirk(sensor, reg, val);
> +	do {
> +		if (cci_write(sensor->regmap, reg, val, &rval))
> +			fsleep(1000);
> +	} while (rval && --retries);
> +
> +	return rval;
>  }
>  
>  #define MAX_WRITE_LEN	32U
> @@ -373,40 +232,36 @@ int ccs_write_data_regs(struct ccs_sensor *sensor, struct ccs_reg *regs,
>  			size_t num_regs)
>  {
>  	struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd);
> -	unsigned char buf[2 + MAX_WRITE_LEN];
> -	struct i2c_msg msg = {
> -		.addr = client->addr,
> -		.buf = buf,
> -	};
>  	size_t i;
>  
>  	for (i = 0; i < num_regs; i++, regs++) {
>  		unsigned char *regdata = regs->value;
>  		unsigned int j;
> +		int len;
>  
> -		for (j = 0; j < regs->len;
> -		     j += msg.len - 2, regdata += msg.len - 2) {
> +		for (j = 0; j < regs->len; j += len, regdata += len) {
>  			char printbuf[(MAX_WRITE_LEN << 1) +
>  				      1 /* \0 */] = { 0 };
> +			unsigned int retries = 10;
>  			int rval;
>  
> -			msg.len = min(regs->len - j, MAX_WRITE_LEN);
> +			len = min(regs->len - j, MAX_WRITE_LEN);
>  
> -			bin2hex(printbuf, regdata, msg.len);
> +			bin2hex(printbuf, regdata, len);
>  			dev_dbg(&client->dev,
>  				"writing msr reg 0x%4.4x value 0x%s\n",
>  				regs->addr + j, printbuf);
>  
> -			put_unaligned_be16(regs->addr + j, buf);
> -			memcpy(buf + 2, regdata, msg.len);
> -
> -			msg.len += 2;
> -
> -			rval = ccs_write_retry(client, &msg);
> +			do {
> +				rval = regmap_bulk_write(sensor->regmap,
> +							 regs->addr + j, regdata, len);

I'm surprised by the line length ;-)

> +				if (rval)
> +					fsleep(1000);
> +			} while (rval && --retries);

A blank line would be nice.

>  			if (rval) {
>  				dev_err(&client->dev,
>  					"error writing %u octets to address 0x%4.4x\n",
> -					msg.len, regs->addr + j);
> +					len, regs->addr + j);
>  				return rval;
>  			}
>  		}
> diff --git a/drivers/media/i2c/ccs/ccs-regs.h b/drivers/media/i2c/ccs/ccs-regs.h
> index 6ce84c5ecf20..45f933cbe478 100644
> --- a/drivers/media/i2c/ccs/ccs-regs.h
> +++ b/drivers/media/i2c/ccs/ccs-regs.h
> @@ -10,59 +10,57 @@
>  
>  #include <linux/bits.h>
>  
> -#define CCS_FL_BASE		16
> -#define CCS_FL_16BIT		BIT(CCS_FL_BASE)
> -#define CCS_FL_32BIT		BIT(CCS_FL_BASE + 1)
> -#define CCS_FL_FLOAT_IREAL	BIT(CCS_FL_BASE + 2)
> -#define CCS_FL_IREAL		BIT(CCS_FL_BASE + 3)
> -#define CCS_R_ADDR(r)		((r) & 0xffff)
> +#include <media/v4l2-cci.h>
>  
> -#define CCS_R_MODULE_MODEL_ID					(0x0000 | CCS_FL_16BIT)
> -#define CCS_R_MODULE_REVISION_NUMBER_MAJOR			0x0002
> -#define CCS_R_FRAME_COUNT					0x0005
> -#define CCS_R_PIXEL_ORDER					0x0006
> +#define CCS_FL_BASE		CCI_REG_FLAG_PRIVATE_START

Unless CCS_FL_BASE is used in the driver, I would drop it and use
CCI_REG_FLAG_PRIVATE_START in the two macros below. Up to you.

> +#define CCS_FL_FLOAT_IREAL	BIT(CCS_FL_BASE)
> +#define CCS_FL_IREAL		BIT(CCS_FL_BASE + 1)
> +#define CCS_R_MODULE_MODEL_ID					CCI_REG16(0x0000)
> +#define CCS_R_MODULE_REVISION_NUMBER_MAJOR			CCI_REG8(0x0002)
> +#define CCS_R_FRAME_COUNT					CCI_REG8(0x0005)
> +#define CCS_R_PIXEL_ORDER					CCI_REG8(0x0006)
>  #define CCS_PIXEL_ORDER_GRBG					0U
>  #define CCS_PIXEL_ORDER_RGGB					1U
>  #define CCS_PIXEL_ORDER_BGGR					2U
>  #define CCS_PIXEL_ORDER_GBRG					3U
> -#define CCS_R_MIPI_CCS_VERSION					0x0007
> +#define CCS_R_MIPI_CCS_VERSION					CCI_REG8(0x0007)
>  #define CCS_MIPI_CCS_VERSION_V1_0				0x10
>  #define CCS_MIPI_CCS_VERSION_V1_1				0x11
>  #define CCS_MIPI_CCS_VERSION_MAJOR_SHIFT			4U
>  #define CCS_MIPI_CCS_VERSION_MAJOR_MASK				0xf0
>  #define CCS_MIPI_CCS_VERSION_MINOR_SHIFT			0U
>  #define CCS_MIPI_CCS_VERSION_MINOR_MASK				0xf
> -#define CCS_R_DATA_PEDESTAL					(0x0008 | CCS_FL_16BIT)
> -#define CCS_R_MODULE_MANUFACTURER_ID				(0x000e | CCS_FL_16BIT)
> -#define CCS_R_MODULE_REVISION_NUMBER_MINOR			0x0010
> -#define CCS_R_MODULE_DATE_YEAR					0x0012
> -#define CCS_R_MODULE_DATE_MONTH					0x0013
> -#define CCS_R_MODULE_DATE_DAY					0x0014
> -#define CCS_R_MODULE_DATE_PHASE					0x0015
> +#define CCS_R_DATA_PEDESTAL					CCI_REG16(0x0008)
> +#define CCS_R_MODULE_MANUFACTURER_ID				CCI_REG16(0x000e)
> +#define CCS_R_MODULE_REVISION_NUMBER_MINOR			CCI_REG8(0x0010)
> +#define CCS_R_MODULE_DATE_YEAR					CCI_REG8(0x0012)
> +#define CCS_R_MODULE_DATE_MONTH					CCI_REG8(0x0013)
> +#define CCS_R_MODULE_DATE_DAY					CCI_REG8(0x0014)
> +#define CCS_R_MODULE_DATE_PHASE					CCI_REG8(0x0015)
>  #define CCS_MODULE_DATE_PHASE_SHIFT				0U
>  #define CCS_MODULE_DATE_PHASE_MASK				0x7
>  #define CCS_MODULE_DATE_PHASE_TS				0U
>  #define CCS_MODULE_DATE_PHASE_ES				1U
>  #define CCS_MODULE_DATE_PHASE_CS				2U
>  #define CCS_MODULE_DATE_PHASE_MP				3U
> -#define CCS_R_SENSOR_MODEL_ID					(0x0016 | CCS_FL_16BIT)
> -#define CCS_R_SENSOR_REVISION_NUMBER				0x0018
> -#define CCS_R_SENSOR_FIRMWARE_VERSION				0x001a
> -#define CCS_R_SERIAL_NUMBER					(0x001c | CCS_FL_32BIT)
> -#define CCS_R_SENSOR_MANUFACTURER_ID				(0x0020 | CCS_FL_16BIT)
> -#define CCS_R_SENSOR_REVISION_NUMBER_16				(0x0022 | CCS_FL_16BIT)
> -#define CCS_R_FRAME_FORMAT_MODEL_TYPE				0x0040
> +#define CCS_R_SENSOR_MODEL_ID					CCI_REG16(0x0016)
> +#define CCS_R_SENSOR_REVISION_NUMBER				CCI_REG8(0x0018)
> +#define CCS_R_SENSOR_FIRMWARE_VERSION				CCI_REG8(0x001a)
> +#define CCS_R_SERIAL_NUMBER					CCI_REG32(0x001c)
> +#define CCS_R_SENSOR_MANUFACTURER_ID				CCI_REG16(0x0020)
> +#define CCS_R_SENSOR_REVISION_NUMBER_16				CCI_REG16(0x0022)
> +#define CCS_R_FRAME_FORMAT_MODEL_TYPE				CCI_REG8(0x0040)
>  #define CCS_FRAME_FORMAT_MODEL_TYPE_2_BYTE			1U
>  #define CCS_FRAME_FORMAT_MODEL_TYPE_4_BYTE			2U
> -#define CCS_R_FRAME_FORMAT_MODEL_SUBTYPE			0x0041
> +#define CCS_R_FRAME_FORMAT_MODEL_SUBTYPE			CCI_REG8(0x0041)
>  #define CCS_FRAME_FORMAT_MODEL_SUBTYPE_ROWS_SHIFT		0U
>  #define CCS_FRAME_FORMAT_MODEL_SUBTYPE_ROWS_MASK		0xf
>  #define CCS_FRAME_FORMAT_MODEL_SUBTYPE_COLUMNS_SHIFT		4U
>  #define CCS_FRAME_FORMAT_MODEL_SUBTYPE_COLUMNS_MASK		0xf0
> -#define CCS_R_FRAME_FORMAT_DESCRIPTOR(n)			((0x0042 | CCS_FL_16BIT) + (n) * 2)
> +#define CCS_R_FRAME_FORMAT_DESCRIPTOR(n)			(CCI_REG16(0x0042) + (n) * 2)

This assumes that the address is encoded in the LSBs. I think it would
be better to write

#define CCS_R_FRAME_FORMAT_DESCRIPTOR(n)			CCI_REG16(0x0042 + (n) * 2)

>  #define CCS_LIM_FRAME_FORMAT_DESCRIPTOR_MIN_N			0U
>  #define CCS_LIM_FRAME_FORMAT_DESCRIPTOR_MAX_N			14U
> -#define CCS_R_FRAME_FORMAT_DESCRIPTOR_4(n)			((0x0060 | CCS_FL_32BIT) + (n) * 4)
> +#define CCS_R_FRAME_FORMAT_DESCRIPTOR_4(n)			(CCI_REG32(0x0060) + (n) * 4)
>  #define CCS_FRAME_FORMAT_DESCRIPTOR_PIXELS_SHIFT		0U
>  #define CCS_FRAME_FORMAT_DESCRIPTOR_PIXELS_MASK			0xfff
>  #define CCS_FRAME_FORMAT_DESCRIPTOR_PCODE_SHIFT			12U

[snip]

> diff --git a/drivers/media/i2c/ccs/ccs.h b/drivers/media/i2c/ccs/ccs.h
> index 2c013d96adcc..096573845a10 100644
> --- a/drivers/media/i2c/ccs/ccs.h
> +++ b/drivers/media/i2c/ccs/ccs.h
> @@ -13,6 +13,7 @@
>  #define __CCS_H__
>  
>  #include <linux/mutex.h>
> +#include <linux/regmap.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-subdev.h>
>  
> @@ -211,6 +212,7 @@ struct ccs_sensor {
>  	struct clk *ext_clk;
>  	struct gpio_desc *xshutdown;
>  	struct gpio_desc *reset;
> +	struct regmap *regmap;
>  	void *ccs_limits;
>  	u8 nbinning_subtypes;
>  	struct ccs_binning_subtype binning_subtypes[CCS_LIM_BINNING_SUB_TYPE_MAX_N + 1];
> diff --git a/drivers/media/i2c/ccs/smiapp-reg-defs.h b/drivers/media/i2c/ccs/smiapp-reg-defs.h
> index 177e3e51207a..72b1af2a9824 100644
> --- a/drivers/media/i2c/ccs/smiapp-reg-defs.h
> +++ b/drivers/media/i2c/ccs/smiapp-reg-defs.h
> @@ -13,480 +13,480 @@
>  #define __SMIAPP_REG_DEFS_H__

Shouldn't you include v4l2-cci.h ?

>  
>  /* Register addresses */

I haven't reviewed the manual changes here.

[snip]
>  
>  /* Register bit definitions */
>  #define SMIAPP_IMAGE_ORIENTATION_HFLIP			BIT(0)

-- 
Regards,

Laurent Pinchart




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux