xref: /linux/include/media/v4l2-cci.h (revision 7fbcd195e2b8cc952e4aeaeb50867b798040314c)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * MIPI Camera Control Interface (CCI) register access helpers.
4  *
5  * Copyright (C) 2023 Hans de Goede <hansg@kernel.org>
6  */
7 #ifndef _V4L2_CCI_H
8 #define _V4L2_CCI_H
9 
10 #include <linux/types.h>
11 
12 struct i2c_client;
13 struct regmap;
14 
15 /**
16  * struct cci_reg_sequence - An individual write from a sequence of CCI writes
17  *
18  * @reg: Register address, use CCI_REG#() macros to encode reg width
19  * @val: Register value
20  *
21  * Register/value pairs for sequences of writes.
22  */
23 struct cci_reg_sequence {
24 	u32 reg;
25 	u64 val;
26 };
27 
28 /*
29  * Macros to define register address with the register width encoded
30  * into the higher bits.
31  */
32 #define CCI_REG_ADDR_MASK		GENMASK(15, 0)
33 #define CCI_REG_WIDTH_SHIFT		16
34 #define CCI_REG_WIDTH_MASK		GENMASK(19, 16)
35 
36 #define CCI_REG8(x)			((1 << CCI_REG_WIDTH_SHIFT) | (x))
37 #define CCI_REG16(x)			((2 << CCI_REG_WIDTH_SHIFT) | (x))
38 #define CCI_REG24(x)			((3 << CCI_REG_WIDTH_SHIFT) | (x))
39 #define CCI_REG32(x)			((4 << CCI_REG_WIDTH_SHIFT) | (x))
40 #define CCI_REG64(x)			((8 << CCI_REG_WIDTH_SHIFT) | (x))
41 
42 /**
43  * cci_read() - Read a value from a single CCI register
44  *
45  * @map: Register map to read from
46  * @reg: Register address to read, use CCI_REG#() macros to encode reg width
47  * @val: Pointer to store read value
48  * @err: Optional pointer to store errors, if a previous error is set
49  *       then the read will be skipped
50  *
51  * Return: %0 on success or a negative error code on failure.
52  */
53 int cci_read(struct regmap *map, u32 reg, u64 *val, int *err);
54 
55 /**
56  * cci_write() - Write a value to a single CCI register
57  *
58  * @map: Register map to write to
59  * @reg: Register address to write, use CCI_REG#() macros to encode reg width
60  * @val: Value to be written
61  * @err: Optional pointer to store errors, if a previous error is set
62  *       then the write will be skipped
63  *
64  * Return: %0 on success or a negative error code on failure.
65  */
66 int cci_write(struct regmap *map, u32 reg, u64 val, int *err);
67 
68 /**
69  * cci_update_bits() - Perform a read/modify/write cycle on
70  *                     a single CCI register
71  *
72  * @map: Register map to update
73  * @reg: Register address to update, use CCI_REG#() macros to encode reg width
74  * @mask: Bitmask to change
75  * @val: New value for bitmask
76  * @err: Optional pointer to store errors, if a previous error is set
77  *       then the update will be skipped
78  *
79  * Note this uses read-modify-write to update the bits, atomicity with regards
80  * to other cci_*() register access functions is NOT guaranteed.
81  *
82  * Return: %0 on success or a negative error code on failure.
83  */
84 int cci_update_bits(struct regmap *map, u32 reg, u64 mask, u64 val, int *err);
85 
86 /**
87  * cci_multi_reg_write() - Write multiple registers to the device
88  *
89  * @map: Register map to write to
90  * @regs: Array of structures containing register-address, -value pairs to be
91  *        written, register-addresses use CCI_REG#() macros to encode reg width
92  * @num_regs: Number of registers to write
93  * @err: Optional pointer to store errors, if a previous error is set
94  *       then the write will be skipped
95  *
96  * Write multiple registers to the device where the set of register, value
97  * pairs are supplied in any order, possibly not all in a single range.
98  *
99  * Use of the CCI_REG#() macros to encode reg width is mandatory.
100  *
101  * For raw lists of register-address, -value pairs with only 8 bit
102  * wide writes regmap_multi_reg_write() can be used instead.
103  *
104  * Return: %0 on success or a negative error code on failure.
105  */
106 int cci_multi_reg_write(struct regmap *map, const struct cci_reg_sequence *regs,
107 			unsigned int num_regs, int *err);
108 
109 #if IS_ENABLED(CONFIG_V4L2_CCI_I2C)
110 /**
111  * devm_cci_regmap_init_i2c() - Create regmap to use with cci_*() register
112  *                              access functions
113  *
114  * @client: i2c_client to create the regmap for
115  * @reg_addr_bits: register address width to use (8 or 16)
116  *
117  * Note the memory for the created regmap is devm() managed, tied to the client.
118  *
119  * Return: %0 on success or a negative error code on failure.
120  */
121 struct regmap *devm_cci_regmap_init_i2c(struct i2c_client *client,
122 					int reg_addr_bits);
123 #endif
124 
125 #endif
126