1b24cc2a1SSakari Ailus // SPDX-License-Identifier: GPL-2.0-only 2b24cc2a1SSakari Ailus /* 3b24cc2a1SSakari Ailus * drivers/media/i2c/ccs/ccs-reg-access.c 4b24cc2a1SSakari Ailus * 5b24cc2a1SSakari Ailus * Generic driver for MIPI CCS/SMIA/SMIA++ compliant camera sensors 6b24cc2a1SSakari Ailus * 7b24cc2a1SSakari Ailus * Copyright (C) 2020 Intel Corporation 8b24cc2a1SSakari Ailus * Copyright (C) 2011--2012 Nokia Corporation 9b24cc2a1SSakari Ailus * Contact: Sakari Ailus <sakari.ailus@iki.fi> 10b24cc2a1SSakari Ailus */ 11b24cc2a1SSakari Ailus 12b24cc2a1SSakari Ailus #include <asm/unaligned.h> 13b24cc2a1SSakari Ailus 14b24cc2a1SSakari Ailus #include <linux/delay.h> 15b24cc2a1SSakari Ailus #include <linux/i2c.h> 16b24cc2a1SSakari Ailus 17b24cc2a1SSakari Ailus #include "ccs.h" 18*fe652254SSakari Ailus #include "ccs-limits.h" 19b24cc2a1SSakari Ailus 20b24cc2a1SSakari Ailus static uint32_t float_to_u32_mul_1000000(struct i2c_client *client, 21b24cc2a1SSakari Ailus uint32_t phloat) 22b24cc2a1SSakari Ailus { 23b24cc2a1SSakari Ailus int32_t exp; 24b24cc2a1SSakari Ailus uint64_t man; 25b24cc2a1SSakari Ailus 26b24cc2a1SSakari Ailus if (phloat >= 0x80000000) { 27b24cc2a1SSakari Ailus dev_err(&client->dev, "this is a negative number\n"); 28b24cc2a1SSakari Ailus return 0; 29b24cc2a1SSakari Ailus } 30b24cc2a1SSakari Ailus 31b24cc2a1SSakari Ailus if (phloat == 0x7f800000) 32b24cc2a1SSakari Ailus return ~0; /* Inf. */ 33b24cc2a1SSakari Ailus 34b24cc2a1SSakari Ailus if ((phloat & 0x7f800000) == 0x7f800000) { 35b24cc2a1SSakari Ailus dev_err(&client->dev, "NaN or other special number\n"); 36b24cc2a1SSakari Ailus return 0; 37b24cc2a1SSakari Ailus } 38b24cc2a1SSakari Ailus 39b24cc2a1SSakari Ailus /* Valid cases begin here */ 40b24cc2a1SSakari Ailus if (phloat == 0) 41b24cc2a1SSakari Ailus return 0; /* Valid zero */ 42b24cc2a1SSakari Ailus 43b24cc2a1SSakari Ailus if (phloat > 0x4f800000) 44b24cc2a1SSakari Ailus return ~0; /* larger than 4294967295 */ 45b24cc2a1SSakari Ailus 46b24cc2a1SSakari Ailus /* 47b24cc2a1SSakari Ailus * Unbias exponent (note how phloat is now guaranteed to 48b24cc2a1SSakari Ailus * have 0 in the high bit) 49b24cc2a1SSakari Ailus */ 50b24cc2a1SSakari Ailus exp = ((int32_t)phloat >> 23) - 127; 51b24cc2a1SSakari Ailus 52b24cc2a1SSakari Ailus /* Extract mantissa, add missing '1' bit and it's in MHz */ 53b24cc2a1SSakari Ailus man = ((phloat & 0x7fffff) | 0x800000) * 1000000ULL; 54b24cc2a1SSakari Ailus 55b24cc2a1SSakari Ailus if (exp < 0) 56b24cc2a1SSakari Ailus man >>= -exp; 57b24cc2a1SSakari Ailus else 58b24cc2a1SSakari Ailus man <<= exp; 59b24cc2a1SSakari Ailus 60b24cc2a1SSakari Ailus man >>= 23; /* Remove mantissa bias */ 61b24cc2a1SSakari Ailus 62b24cc2a1SSakari Ailus return man & 0xffffffff; 63b24cc2a1SSakari Ailus } 64b24cc2a1SSakari Ailus 65b24cc2a1SSakari Ailus 66b24cc2a1SSakari Ailus /* 67b24cc2a1SSakari Ailus * Read a 8/16/32-bit i2c register. The value is returned in 'val'. 68b24cc2a1SSakari Ailus * Returns zero if successful, or non-zero otherwise. 69b24cc2a1SSakari Ailus */ 70b24cc2a1SSakari Ailus static int ____ccs_read_addr(struct ccs_sensor *sensor, u16 reg, u16 len, 71b24cc2a1SSakari Ailus u32 *val) 72b24cc2a1SSakari Ailus { 73b24cc2a1SSakari Ailus struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); 74b24cc2a1SSakari Ailus struct i2c_msg msg; 75b24cc2a1SSakari Ailus unsigned char data_buf[sizeof(u32)] = { 0 }; 76b24cc2a1SSakari Ailus unsigned char offset_buf[sizeof(u16)]; 77b24cc2a1SSakari Ailus int r; 78b24cc2a1SSakari Ailus 79b24cc2a1SSakari Ailus if (len > sizeof(data_buf)) 80b24cc2a1SSakari Ailus return -EINVAL; 81b24cc2a1SSakari Ailus 82b24cc2a1SSakari Ailus msg.addr = client->addr; 83b24cc2a1SSakari Ailus msg.flags = 0; 84b24cc2a1SSakari Ailus msg.len = sizeof(offset_buf); 85b24cc2a1SSakari Ailus msg.buf = offset_buf; 86b24cc2a1SSakari Ailus put_unaligned_be16(reg, offset_buf); 87b24cc2a1SSakari Ailus 88b24cc2a1SSakari Ailus r = i2c_transfer(client->adapter, &msg, 1); 89b24cc2a1SSakari Ailus if (r != 1) { 90b24cc2a1SSakari Ailus if (r >= 0) 91b24cc2a1SSakari Ailus r = -EBUSY; 92b24cc2a1SSakari Ailus goto err; 93b24cc2a1SSakari Ailus } 94b24cc2a1SSakari Ailus 95b24cc2a1SSakari Ailus msg.len = len; 96b24cc2a1SSakari Ailus msg.flags = I2C_M_RD; 97b24cc2a1SSakari Ailus msg.buf = &data_buf[sizeof(data_buf) - len]; 98b24cc2a1SSakari Ailus 99b24cc2a1SSakari Ailus r = i2c_transfer(client->adapter, &msg, 1); 100b24cc2a1SSakari Ailus if (r != 1) { 101b24cc2a1SSakari Ailus if (r >= 0) 102b24cc2a1SSakari Ailus r = -EBUSY; 103b24cc2a1SSakari Ailus goto err; 104b24cc2a1SSakari Ailus } 105b24cc2a1SSakari Ailus 106b24cc2a1SSakari Ailus *val = get_unaligned_be32(data_buf); 107b24cc2a1SSakari Ailus 108b24cc2a1SSakari Ailus return 0; 109b24cc2a1SSakari Ailus 110b24cc2a1SSakari Ailus err: 111b24cc2a1SSakari Ailus dev_err(&client->dev, "read from offset 0x%x error %d\n", reg, r); 112b24cc2a1SSakari Ailus 113b24cc2a1SSakari Ailus return r; 114b24cc2a1SSakari Ailus } 115b24cc2a1SSakari Ailus 116b24cc2a1SSakari Ailus /* Read a register using 8-bit access only. */ 117b24cc2a1SSakari Ailus static int ____ccs_read_addr_8only(struct ccs_sensor *sensor, u16 reg, 118b24cc2a1SSakari Ailus u16 len, u32 *val) 119b24cc2a1SSakari Ailus { 120b24cc2a1SSakari Ailus unsigned int i; 121b24cc2a1SSakari Ailus int rval; 122b24cc2a1SSakari Ailus 123b24cc2a1SSakari Ailus *val = 0; 124b24cc2a1SSakari Ailus 125b24cc2a1SSakari Ailus for (i = 0; i < len; i++) { 126b24cc2a1SSakari Ailus u32 val8; 127b24cc2a1SSakari Ailus 128b24cc2a1SSakari Ailus rval = ____ccs_read_addr(sensor, reg + i, 1, &val8); 129b24cc2a1SSakari Ailus if (rval < 0) 130b24cc2a1SSakari Ailus return rval; 131b24cc2a1SSakari Ailus *val |= val8 << ((len - i - 1) << 3); 132b24cc2a1SSakari Ailus } 133b24cc2a1SSakari Ailus 134b24cc2a1SSakari Ailus return 0; 135b24cc2a1SSakari Ailus } 136b24cc2a1SSakari Ailus 137b24cc2a1SSakari Ailus unsigned int ccs_reg_width(u32 reg) 138b24cc2a1SSakari Ailus { 139b24cc2a1SSakari Ailus if (reg & CCS_FL_16BIT) 140b24cc2a1SSakari Ailus return sizeof(uint16_t); 141b24cc2a1SSakari Ailus if (reg & CCS_FL_32BIT) 142b24cc2a1SSakari Ailus return sizeof(uint32_t); 143b24cc2a1SSakari Ailus 144b24cc2a1SSakari Ailus return sizeof(uint8_t); 145b24cc2a1SSakari Ailus } 146b24cc2a1SSakari Ailus 147*fe652254SSakari Ailus static u32 ireal32_to_u32_mul_1000000(struct i2c_client *client, u32 val) 148*fe652254SSakari Ailus { 149*fe652254SSakari Ailus if (val >> 10 > U32_MAX / 15625) { 150*fe652254SSakari Ailus dev_warn(&client->dev, "value %u overflows!\n", val); 151*fe652254SSakari Ailus return U32_MAX; 152*fe652254SSakari Ailus } 153*fe652254SSakari Ailus 154*fe652254SSakari Ailus return ((val >> 10) * 15625) + 155*fe652254SSakari Ailus (val & GENMASK(9, 0)) * 15625 / 1024; 156*fe652254SSakari Ailus } 157*fe652254SSakari Ailus 1587d2f8ddaSSakari Ailus u32 ccs_reg_conv(struct ccs_sensor *sensor, u32 reg, u32 val) 1597d2f8ddaSSakari Ailus { 1607d2f8ddaSSakari Ailus struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); 1617d2f8ddaSSakari Ailus 162*fe652254SSakari Ailus if (reg & CCS_FL_FLOAT_IREAL) { 163*fe652254SSakari Ailus if (CCS_LIM(sensor, CLOCK_CAPA_TYPE_CAPABILITY) & 164*fe652254SSakari Ailus CCS_CLOCK_CAPA_TYPE_CAPABILITY_IREAL) 165*fe652254SSakari Ailus val = ireal32_to_u32_mul_1000000(client, val); 166*fe652254SSakari Ailus else 1677d2f8ddaSSakari Ailus val = float_to_u32_mul_1000000(client, val); 168*fe652254SSakari Ailus } else if (reg & CCS_FL_IREAL) { 169*fe652254SSakari Ailus val = ireal32_to_u32_mul_1000000(client, val); 170*fe652254SSakari Ailus } 1717d2f8ddaSSakari Ailus 1727d2f8ddaSSakari Ailus return val; 1737d2f8ddaSSakari Ailus } 1747d2f8ddaSSakari Ailus 175b24cc2a1SSakari Ailus /* 176b24cc2a1SSakari Ailus * Read a 8/16/32-bit i2c register. The value is returned in 'val'. 177b24cc2a1SSakari Ailus * Returns zero if successful, or non-zero otherwise. 178b24cc2a1SSakari Ailus */ 179b24cc2a1SSakari Ailus static int __ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val, 1807d2f8ddaSSakari Ailus bool only8, bool conv) 181b24cc2a1SSakari Ailus { 182b24cc2a1SSakari Ailus unsigned int len = ccs_reg_width(reg); 183b24cc2a1SSakari Ailus int rval; 184b24cc2a1SSakari Ailus 185b24cc2a1SSakari Ailus if (!only8) 186b24cc2a1SSakari Ailus rval = ____ccs_read_addr(sensor, CCS_REG_ADDR(reg), len, val); 187b24cc2a1SSakari Ailus else 188b24cc2a1SSakari Ailus rval = ____ccs_read_addr_8only(sensor, CCS_REG_ADDR(reg), len, 189b24cc2a1SSakari Ailus val); 190b24cc2a1SSakari Ailus if (rval < 0) 191b24cc2a1SSakari Ailus return rval; 192b24cc2a1SSakari Ailus 1937d2f8ddaSSakari Ailus if (!conv) 1947d2f8ddaSSakari Ailus return 0; 1957d2f8ddaSSakari Ailus 1967d2f8ddaSSakari Ailus *val = ccs_reg_conv(sensor, reg, *val); 197b24cc2a1SSakari Ailus 198b24cc2a1SSakari Ailus return 0; 199b24cc2a1SSakari Ailus } 200b24cc2a1SSakari Ailus 2012989a457SSakari Ailus static int ccs_read_addr_raw(struct ccs_sensor *sensor, u32 reg, u32 *val, 2027d2f8ddaSSakari Ailus bool force8, bool quirk, bool conv) 203b24cc2a1SSakari Ailus { 204b24cc2a1SSakari Ailus int rval; 205b24cc2a1SSakari Ailus 2062989a457SSakari Ailus if (quirk) { 207b24cc2a1SSakari Ailus *val = 0; 208b24cc2a1SSakari Ailus rval = ccs_call_quirk(sensor, reg_access, false, ®, val); 209b24cc2a1SSakari Ailus if (rval == -ENOIOCTLCMD) 210b24cc2a1SSakari Ailus return 0; 211b24cc2a1SSakari Ailus if (rval < 0) 212b24cc2a1SSakari Ailus return rval; 213b24cc2a1SSakari Ailus 214b24cc2a1SSakari Ailus if (force8) 2157d2f8ddaSSakari Ailus return __ccs_read_addr(sensor, reg, val, true, conv); 2162989a457SSakari Ailus } 217b24cc2a1SSakari Ailus 2182989a457SSakari Ailus return __ccs_read_addr(sensor, reg, val, 2192989a457SSakari Ailus ccs_needs_quirk(sensor, 2207d2f8ddaSSakari Ailus CCS_QUIRK_FLAG_8BIT_READ_ONLY), 2217d2f8ddaSSakari Ailus conv); 222b24cc2a1SSakari Ailus } 223b24cc2a1SSakari Ailus 224b24cc2a1SSakari Ailus int ccs_read_addr(struct ccs_sensor *sensor, u32 reg, u32 *val) 225b24cc2a1SSakari Ailus { 2267d2f8ddaSSakari Ailus return ccs_read_addr_raw(sensor, reg, val, false, true, true); 227b24cc2a1SSakari Ailus } 228b24cc2a1SSakari Ailus 229b24cc2a1SSakari Ailus int ccs_read_addr_8only(struct ccs_sensor *sensor, u32 reg, u32 *val) 230b24cc2a1SSakari Ailus { 2317d2f8ddaSSakari Ailus return ccs_read_addr_raw(sensor, reg, val, true, true, true); 2327d2f8ddaSSakari Ailus } 2337d2f8ddaSSakari Ailus 2347d2f8ddaSSakari Ailus int ccs_read_addr_noconv(struct ccs_sensor *sensor, u32 reg, u32 *val) 2357d2f8ddaSSakari Ailus { 2367d2f8ddaSSakari Ailus return ccs_read_addr_raw(sensor, reg, val, false, true, false); 237b24cc2a1SSakari Ailus } 238b24cc2a1SSakari Ailus 239b24cc2a1SSakari Ailus int ccs_write_addr_no_quirk(struct ccs_sensor *sensor, u32 reg, u32 val) 240b24cc2a1SSakari Ailus { 241b24cc2a1SSakari Ailus struct i2c_client *client = v4l2_get_subdevdata(&sensor->src->sd); 242b24cc2a1SSakari Ailus struct i2c_msg msg; 243b24cc2a1SSakari Ailus unsigned char data[6]; 244b24cc2a1SSakari Ailus unsigned int retries; 245b24cc2a1SSakari Ailus unsigned int len = ccs_reg_width(reg); 246b24cc2a1SSakari Ailus int r; 247b24cc2a1SSakari Ailus 248b24cc2a1SSakari Ailus if (len > sizeof(data) - 2) 249b24cc2a1SSakari Ailus return -EINVAL; 250b24cc2a1SSakari Ailus 251b24cc2a1SSakari Ailus msg.addr = client->addr; 252b24cc2a1SSakari Ailus msg.flags = 0; /* Write */ 253b24cc2a1SSakari Ailus msg.len = 2 + len; 254b24cc2a1SSakari Ailus msg.buf = data; 255b24cc2a1SSakari Ailus 256b24cc2a1SSakari Ailus put_unaligned_be16(CCS_REG_ADDR(reg), data); 257b24cc2a1SSakari Ailus put_unaligned_be32(val << (8 * (sizeof(val) - len)), data + 2); 258b24cc2a1SSakari Ailus 259b24cc2a1SSakari Ailus for (retries = 0; retries < 5; retries++) { 260b24cc2a1SSakari Ailus /* 261b24cc2a1SSakari Ailus * Due to unknown reason sensor stops responding. This 262b24cc2a1SSakari Ailus * loop is a temporaty solution until the root cause 263b24cc2a1SSakari Ailus * is found. 264b24cc2a1SSakari Ailus */ 265b24cc2a1SSakari Ailus r = i2c_transfer(client->adapter, &msg, 1); 266b24cc2a1SSakari Ailus if (r == 1) { 267b24cc2a1SSakari Ailus if (retries) 268b24cc2a1SSakari Ailus dev_err(&client->dev, 269b24cc2a1SSakari Ailus "sensor i2c stall encountered. retries: %d\n", 270b24cc2a1SSakari Ailus retries); 271b24cc2a1SSakari Ailus return 0; 272b24cc2a1SSakari Ailus } 273b24cc2a1SSakari Ailus 274b24cc2a1SSakari Ailus usleep_range(2000, 2000); 275b24cc2a1SSakari Ailus } 276b24cc2a1SSakari Ailus 277b24cc2a1SSakari Ailus dev_err(&client->dev, 278b24cc2a1SSakari Ailus "wrote 0x%x to offset 0x%x error %d\n", val, 279b24cc2a1SSakari Ailus CCS_REG_ADDR(reg), r); 280b24cc2a1SSakari Ailus 281b24cc2a1SSakari Ailus return r; 282b24cc2a1SSakari Ailus } 283b24cc2a1SSakari Ailus 284b24cc2a1SSakari Ailus /* 285b24cc2a1SSakari Ailus * Write to a 8/16-bit register. 286b24cc2a1SSakari Ailus * Returns zero if successful, or non-zero otherwise. 287b24cc2a1SSakari Ailus */ 288b24cc2a1SSakari Ailus int ccs_write_addr(struct ccs_sensor *sensor, u32 reg, u32 val) 289b24cc2a1SSakari Ailus { 290b24cc2a1SSakari Ailus int rval; 291b24cc2a1SSakari Ailus 292b24cc2a1SSakari Ailus rval = ccs_call_quirk(sensor, reg_access, true, ®, &val); 293b24cc2a1SSakari Ailus if (rval == -ENOIOCTLCMD) 294b24cc2a1SSakari Ailus return 0; 295b24cc2a1SSakari Ailus if (rval < 0) 296b24cc2a1SSakari Ailus return rval; 297b24cc2a1SSakari Ailus 298b24cc2a1SSakari Ailus return ccs_write_addr_no_quirk(sensor, reg, val); 299b24cc2a1SSakari Ailus } 300