1 // SPDX-License-Identifier: GPL-2.0
3 // CS42L43 SPI Controller Driver
5 // Copyright (C) 2022-2023 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
8 #include <linux/bits.h>
9 #include <linux/bitfield.h>
10 #include <linux/device.h>
11 #include <linux/errno.h>
12 #include <linux/mfd/cs42l43.h>
13 #include <linux/mfd/cs42l43-regs.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/spi/spi.h>
19 #include <linux/units.h>
21 #define CS42L43_FIFO_SIZE 16
22 #define CS42L43_SPI_ROOT_HZ (40 * HZ_PER_MHZ)
23 #define CS42L43_SPI_MAX_LENGTH 65532
25 enum cs42l43_spi_cmd
{
32 struct regmap
*regmap
;
33 struct spi_controller
*ctlr
;
36 static const unsigned int cs42l43_clock_divs
[] = {
37 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
40 static int cs42l43_spi_tx(struct regmap
*regmap
, const u8
*buf
, unsigned int len
)
42 const u8
*end
= buf
+ len
;
47 const u8
*block
= min(buf
+ CS42L43_FIFO_SIZE
, end
);
50 const u8
*word
= min(buf
+ sizeof(u32
), block
);
51 int pad
= (buf
+ sizeof(u32
)) - word
;
54 val
>>= BITS_PER_BYTE
;
55 val
|= FIELD_PREP(GENMASK(31, 24), *buf
);
60 val
>>= pad
* BITS_PER_BYTE
;
62 regmap_write(regmap
, CS42L43_TX_DATA
, val
);
65 regmap_write(regmap
, CS42L43_TRAN_CONFIG8
, CS42L43_SPI_TX_DONE_MASK
);
67 ret
= regmap_read_poll_timeout(regmap
, CS42L43_TRAN_STATUS1
,
68 val
, (val
& CS42L43_SPI_TX_REQUEST_MASK
),
77 static int cs42l43_spi_rx(struct regmap
*regmap
, u8
*buf
, unsigned int len
)
84 u8
*block
= min(buf
+ CS42L43_FIFO_SIZE
, end
);
86 ret
= regmap_read_poll_timeout(regmap
, CS42L43_TRAN_STATUS1
,
87 val
, (val
& CS42L43_SPI_RX_REQUEST_MASK
),
93 u8
*word
= min(buf
+ sizeof(u32
), block
);
95 ret
= regmap_read(regmap
, CS42L43_RX_DATA
, &val
);
100 *buf
= FIELD_GET(GENMASK(7, 0), val
);
102 val
>>= BITS_PER_BYTE
;
107 regmap_write(regmap
, CS42L43_TRAN_CONFIG8
, CS42L43_SPI_RX_DONE_MASK
);
113 static int cs42l43_transfer_one(struct spi_controller
*ctlr
, struct spi_device
*spi
,
114 struct spi_transfer
*tfr
)
116 struct cs42l43_spi
*priv
= spi_controller_get_devdata(spi
->controller
);
117 int i
, ret
= -EINVAL
;
119 for (i
= 0; i
< ARRAY_SIZE(cs42l43_clock_divs
); i
++) {
120 if (CS42L43_SPI_ROOT_HZ
/ cs42l43_clock_divs
[i
] <= tfr
->speed_hz
)
124 if (i
== ARRAY_SIZE(cs42l43_clock_divs
))
127 regmap_write(priv
->regmap
, CS42L43_SPI_CLK_CONFIG1
, i
);
130 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG3
, CS42L43_WRITE
);
131 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG4
, tfr
->len
- 1);
132 } else if (tfr
->rx_buf
) {
133 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG3
, CS42L43_READ
);
134 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG5
, tfr
->len
- 1);
137 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG1
, CS42L43_SPI_START_MASK
);
140 ret
= cs42l43_spi_tx(priv
->regmap
, (const u8
*)tfr
->tx_buf
, tfr
->len
);
141 else if (tfr
->rx_buf
)
142 ret
= cs42l43_spi_rx(priv
->regmap
, (u8
*)tfr
->rx_buf
, tfr
->len
);
147 static void cs42l43_set_cs(struct spi_device
*spi
, bool is_high
)
149 struct cs42l43_spi
*priv
= spi_controller_get_devdata(spi
->controller
);
151 regmap_write(priv
->regmap
, CS42L43_SPI_CONFIG2
, !is_high
);
154 static int cs42l43_prepare_message(struct spi_controller
*ctlr
, struct spi_message
*msg
)
156 struct cs42l43_spi
*priv
= spi_controller_get_devdata(ctlr
);
157 struct spi_device
*spi
= msg
->spi
;
158 unsigned int spi_config1
= 0;
160 /* select another internal CS, which doesn't exist, so CS 0 is not used */
161 if (spi_get_csgpiod(spi
, 0))
162 spi_config1
|= 1 << CS42L43_SPI_SS_SEL_SHIFT
;
163 if (spi
->mode
& SPI_CPOL
)
164 spi_config1
|= CS42L43_SPI_CPOL_MASK
;
165 if (spi
->mode
& SPI_CPHA
)
166 spi_config1
|= CS42L43_SPI_CPHA_MASK
;
167 if (spi
->mode
& SPI_3WIRE
)
168 spi_config1
|= CS42L43_SPI_THREE_WIRE_MASK
;
170 regmap_write(priv
->regmap
, CS42L43_SPI_CONFIG1
, spi_config1
);
175 static int cs42l43_prepare_transfer_hardware(struct spi_controller
*ctlr
)
177 struct cs42l43_spi
*priv
= spi_controller_get_devdata(ctlr
);
180 ret
= regmap_write(priv
->regmap
, CS42L43_BLOCK_EN2
, CS42L43_SPI_MSTR_EN_MASK
);
182 dev_err(priv
->dev
, "Failed to enable SPI controller: %d\n", ret
);
187 static int cs42l43_unprepare_transfer_hardware(struct spi_controller
*ctlr
)
189 struct cs42l43_spi
*priv
= spi_controller_get_devdata(ctlr
);
192 ret
= regmap_write(priv
->regmap
, CS42L43_BLOCK_EN2
, 0);
194 dev_err(priv
->dev
, "Failed to disable SPI controller: %d\n", ret
);
199 static size_t cs42l43_spi_max_length(struct spi_device
*spi
)
201 return CS42L43_SPI_MAX_LENGTH
;
204 static void cs42l43_release_of_node(void *data
)
206 fwnode_handle_put(data
);
209 static int cs42l43_spi_probe(struct platform_device
*pdev
)
211 struct cs42l43
*cs42l43
= dev_get_drvdata(pdev
->dev
.parent
);
212 struct cs42l43_spi
*priv
;
213 struct fwnode_handle
*fwnode
= dev_fwnode(cs42l43
->dev
);
216 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
220 priv
->ctlr
= devm_spi_alloc_host(&pdev
->dev
, sizeof(*priv
->ctlr
));
224 spi_controller_set_devdata(priv
->ctlr
, priv
);
226 priv
->dev
= &pdev
->dev
;
227 priv
->regmap
= cs42l43
->regmap
;
229 priv
->ctlr
->prepare_message
= cs42l43_prepare_message
;
230 priv
->ctlr
->prepare_transfer_hardware
= cs42l43_prepare_transfer_hardware
;
231 priv
->ctlr
->unprepare_transfer_hardware
= cs42l43_unprepare_transfer_hardware
;
232 priv
->ctlr
->transfer_one
= cs42l43_transfer_one
;
233 priv
->ctlr
->set_cs
= cs42l43_set_cs
;
234 priv
->ctlr
->max_transfer_size
= cs42l43_spi_max_length
;
235 priv
->ctlr
->mode_bits
= SPI_3WIRE
| SPI_MODE_X_MASK
;
236 priv
->ctlr
->flags
= SPI_CONTROLLER_HALF_DUPLEX
;
237 priv
->ctlr
->bits_per_word_mask
= SPI_BPW_MASK(8) | SPI_BPW_MASK(16) |
239 priv
->ctlr
->min_speed_hz
= CS42L43_SPI_ROOT_HZ
/
240 cs42l43_clock_divs
[ARRAY_SIZE(cs42l43_clock_divs
) - 1];
241 priv
->ctlr
->max_speed_hz
= CS42L43_SPI_ROOT_HZ
/ cs42l43_clock_divs
[0];
242 priv
->ctlr
->use_gpio_descriptors
= true;
243 priv
->ctlr
->auto_runtime_pm
= true;
245 ret
= devm_pm_runtime_enable(priv
->dev
);
249 pm_runtime_idle(priv
->dev
);
251 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG6
, CS42L43_FIFO_SIZE
- 1);
252 regmap_write(priv
->regmap
, CS42L43_TRAN_CONFIG7
, CS42L43_FIFO_SIZE
- 1);
254 // Disable Watchdog timer and enable stall
255 regmap_write(priv
->regmap
, CS42L43_SPI_CONFIG3
, 0);
256 regmap_write(priv
->regmap
, CS42L43_SPI_CONFIG4
, CS42L43_SPI_STALL_ENA_MASK
);
258 if (is_of_node(fwnode
)) {
259 fwnode
= fwnode_get_named_child_node(fwnode
, "spi");
260 ret
= devm_add_action(priv
->dev
, cs42l43_release_of_node
, fwnode
);
262 fwnode_handle_put(fwnode
);
267 device_set_node(&priv
->ctlr
->dev
, fwnode
);
269 ret
= devm_spi_register_controller(priv
->dev
, priv
->ctlr
);
271 dev_err(priv
->dev
, "Failed to register SPI controller: %d\n", ret
);
277 static const struct platform_device_id cs42l43_spi_id_table
[] = {
281 MODULE_DEVICE_TABLE(platform
, cs42l43_spi_id_table
);
283 static struct platform_driver cs42l43_spi_driver
= {
285 .name
= "cs42l43-spi",
287 .probe
= cs42l43_spi_probe
,
288 .id_table
= cs42l43_spi_id_table
,
290 module_platform_driver(cs42l43_spi_driver
);
292 MODULE_DESCRIPTION("CS42L43 SPI Driver");
293 MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
294 MODULE_AUTHOR("Maciej Strozek <mstrozek@opensource.cirrus.com>");
295 MODULE_LICENSE("GPL");