1613cbb91SHans de Goede /* SPDX-License-Identifier: GPL-2.0 */ 2613cbb91SHans de Goede /* 3613cbb91SHans de Goede * MIPI Camera Control Interface (CCI) register access helpers. 4613cbb91SHans de Goede * 5613cbb91SHans de Goede * Copyright (C) 2023 Hans de Goede <hansg@kernel.org> 6613cbb91SHans de Goede */ 7613cbb91SHans de Goede #ifndef _V4L2_CCI_H 8613cbb91SHans de Goede #define _V4L2_CCI_H 9613cbb91SHans de Goede 108d2cd172SSakari Ailus #include <linux/bitfield.h> 1136bf2a8fSSakari Ailus #include <linux/bits.h> 12613cbb91SHans de Goede #include <linux/types.h> 13613cbb91SHans de Goede 14613cbb91SHans de Goede struct i2c_client; 15613cbb91SHans de Goede struct regmap; 16613cbb91SHans de Goede 17613cbb91SHans de Goede /** 18613cbb91SHans de Goede * struct cci_reg_sequence - An individual write from a sequence of CCI writes 19613cbb91SHans de Goede * 20613cbb91SHans de Goede * @reg: Register address, use CCI_REG#() macros to encode reg width 21613cbb91SHans de Goede * @val: Register value 22613cbb91SHans de Goede * 23613cbb91SHans de Goede * Register/value pairs for sequences of writes. 24613cbb91SHans de Goede */ 25613cbb91SHans de Goede struct cci_reg_sequence { 26613cbb91SHans de Goede u32 reg; 27613cbb91SHans de Goede u64 val; 28613cbb91SHans de Goede }; 29613cbb91SHans de Goede 30613cbb91SHans de Goede /* 31613cbb91SHans de Goede * Macros to define register address with the register width encoded 32613cbb91SHans de Goede * into the higher bits. 33613cbb91SHans de Goede */ 34613cbb91SHans de Goede #define CCI_REG_ADDR_MASK GENMASK(15, 0) 35613cbb91SHans de Goede #define CCI_REG_WIDTH_SHIFT 16 36613cbb91SHans de Goede #define CCI_REG_WIDTH_MASK GENMASK(19, 16) 37613cbb91SHans de Goede 388d2cd172SSakari Ailus #define CCI_REG_WIDTH_BYTES(x) FIELD_GET(CCI_REG_WIDTH_MASK, x) 398d2cd172SSakari Ailus #define CCI_REG_WIDTH(x) (CCI_REG_WIDTH_BYTES(x) << 3) 408d2cd172SSakari Ailus #define CCI_REG_ADDR(x) FIELD_GET(CCI_REG_ADDR_MASK, x) 41*8798fdc2SAlexander Stein #define CCI_REG_LE BIT(20) 428d2cd172SSakari Ailus 43613cbb91SHans de Goede #define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x)) 44613cbb91SHans de Goede #define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x)) 45613cbb91SHans de Goede #define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x)) 46613cbb91SHans de Goede #define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x)) 47613cbb91SHans de Goede #define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x)) 48*8798fdc2SAlexander Stein #define CCI_REG16_LE(x) (CCI_REG_LE | (2U << CCI_REG_WIDTH_SHIFT) | (x)) 49*8798fdc2SAlexander Stein #define CCI_REG24_LE(x) (CCI_REG_LE | (3U << CCI_REG_WIDTH_SHIFT) | (x)) 50*8798fdc2SAlexander Stein #define CCI_REG32_LE(x) (CCI_REG_LE | (4U << CCI_REG_WIDTH_SHIFT) | (x)) 51*8798fdc2SAlexander Stein #define CCI_REG64_LE(x) (CCI_REG_LE | (8U << CCI_REG_WIDTH_SHIFT) | (x)) 52613cbb91SHans de Goede 53613cbb91SHans de Goede /** 54613cbb91SHans de Goede * cci_read() - Read a value from a single CCI register 55613cbb91SHans de Goede * 56613cbb91SHans de Goede * @map: Register map to read from 57613cbb91SHans de Goede * @reg: Register address to read, use CCI_REG#() macros to encode reg width 58613cbb91SHans de Goede * @val: Pointer to store read value 59613cbb91SHans de Goede * @err: Optional pointer to store errors, if a previous error is set 60613cbb91SHans de Goede * then the read will be skipped 61613cbb91SHans de Goede * 62613cbb91SHans de Goede * Return: %0 on success or a negative error code on failure. 63613cbb91SHans de Goede */ 64613cbb91SHans de Goede int cci_read(struct regmap *map, u32 reg, u64 *val, int *err); 65613cbb91SHans de Goede 66613cbb91SHans de Goede /** 67613cbb91SHans de Goede * cci_write() - Write a value to a single CCI register 68613cbb91SHans de Goede * 69613cbb91SHans de Goede * @map: Register map to write to 70613cbb91SHans de Goede * @reg: Register address to write, use CCI_REG#() macros to encode reg width 71613cbb91SHans de Goede * @val: Value to be written 72613cbb91SHans de Goede * @err: Optional pointer to store errors, if a previous error is set 73613cbb91SHans de Goede * then the write will be skipped 74613cbb91SHans de Goede * 75613cbb91SHans de Goede * Return: %0 on success or a negative error code on failure. 76613cbb91SHans de Goede */ 77613cbb91SHans de Goede int cci_write(struct regmap *map, u32 reg, u64 val, int *err); 78613cbb91SHans de Goede 79613cbb91SHans de Goede /** 80613cbb91SHans de Goede * cci_update_bits() - Perform a read/modify/write cycle on 81613cbb91SHans de Goede * a single CCI register 82613cbb91SHans de Goede * 83613cbb91SHans de Goede * @map: Register map to update 84613cbb91SHans de Goede * @reg: Register address to update, use CCI_REG#() macros to encode reg width 85613cbb91SHans de Goede * @mask: Bitmask to change 86613cbb91SHans de Goede * @val: New value for bitmask 87613cbb91SHans de Goede * @err: Optional pointer to store errors, if a previous error is set 88613cbb91SHans de Goede * then the update will be skipped 89613cbb91SHans de Goede * 90613cbb91SHans de Goede * Note this uses read-modify-write to update the bits, atomicity with regards 91613cbb91SHans de Goede * to other cci_*() register access functions is NOT guaranteed. 92613cbb91SHans de Goede * 93613cbb91SHans de Goede * Return: %0 on success or a negative error code on failure. 94613cbb91SHans de Goede */ 95613cbb91SHans de Goede int cci_update_bits(struct regmap *map, u32 reg, u64 mask, u64 val, int *err); 96613cbb91SHans de Goede 97613cbb91SHans de Goede /** 98613cbb91SHans de Goede * cci_multi_reg_write() - Write multiple registers to the device 99613cbb91SHans de Goede * 100613cbb91SHans de Goede * @map: Register map to write to 101613cbb91SHans de Goede * @regs: Array of structures containing register-address, -value pairs to be 102613cbb91SHans de Goede * written, register-addresses use CCI_REG#() macros to encode reg width 103613cbb91SHans de Goede * @num_regs: Number of registers to write 104613cbb91SHans de Goede * @err: Optional pointer to store errors, if a previous error is set 105613cbb91SHans de Goede * then the write will be skipped 106613cbb91SHans de Goede * 107613cbb91SHans de Goede * Write multiple registers to the device where the set of register, value 108613cbb91SHans de Goede * pairs are supplied in any order, possibly not all in a single range. 109613cbb91SHans de Goede * 110613cbb91SHans de Goede * Use of the CCI_REG#() macros to encode reg width is mandatory. 111613cbb91SHans de Goede * 112613cbb91SHans de Goede * For raw lists of register-address, -value pairs with only 8 bit 113613cbb91SHans de Goede * wide writes regmap_multi_reg_write() can be used instead. 114613cbb91SHans de Goede * 115613cbb91SHans de Goede * Return: %0 on success or a negative error code on failure. 116613cbb91SHans de Goede */ 117613cbb91SHans de Goede int cci_multi_reg_write(struct regmap *map, const struct cci_reg_sequence *regs, 118613cbb91SHans de Goede unsigned int num_regs, int *err); 119613cbb91SHans de Goede 120613cbb91SHans de Goede #if IS_ENABLED(CONFIG_V4L2_CCI_I2C) 121613cbb91SHans de Goede /** 122613cbb91SHans de Goede * devm_cci_regmap_init_i2c() - Create regmap to use with cci_*() register 123613cbb91SHans de Goede * access functions 124613cbb91SHans de Goede * 125613cbb91SHans de Goede * @client: i2c_client to create the regmap for 126613cbb91SHans de Goede * @reg_addr_bits: register address width to use (8 or 16) 127613cbb91SHans de Goede * 128613cbb91SHans de Goede * Note the memory for the created regmap is devm() managed, tied to the client. 129613cbb91SHans de Goede * 130613cbb91SHans de Goede * Return: %0 on success or a negative error code on failure. 131613cbb91SHans de Goede */ 132613cbb91SHans de Goede struct regmap *devm_cci_regmap_init_i2c(struct i2c_client *client, 133613cbb91SHans de Goede int reg_addr_bits); 134613cbb91SHans de Goede #endif 135613cbb91SHans de Goede 136613cbb91SHans de Goede #endif 137