File Index
Files and directories
Sign in
FILE

spi-kspi2.c

File preview with syntax highlighting.

linux-6.19.14/drivers/spi/spi-kspi2.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) KEBA Industrial Automation Gmbh 2024
  4 *
  5 * Driver for KEBA SPI host controller type 2 FPGA IP core
  6 */
  7
  8#include <linux/iopoll.h>
  9#include <linux/misc/keba.h>
 10#include <linux/spi/spi.h>
 11
 12#define KSPI2 "kspi2"
 13
 14#define KSPI2_CLK_FREQ_REG	0x03
 15#define  KSPI2_CLK_FREQ_MASK	0x0f
 16#define  KSPI2_CLK_FREQ_62_5M	0x0
 17#define  KSPI2_CLK_FREQ_33_3M	0x1
 18#define  KSPI2_CLK_FREQ_125M	0x2
 19#define  KSPI2_CLK_FREQ_50M	0x3
 20#define  KSPI2_CLK_FREQ_100M	0x4
 21
 22#define KSPI2_CONTROL_REG		0x04
 23#define  KSPI2_CONTROL_CLK_DIV_MAX	0x0f
 24#define  KSPI2_CONTROL_CLK_DIV_MASK	0x0f
 25#define  KSPI2_CONTROL_CPHA		0x10
 26#define  KSPI2_CONTROL_CPOL		0x20
 27#define  KSPI2_CONTROL_CLK_MODE_MASK	0x30
 28#define  KSPI2_CONTROL_INIT		KSPI2_CONTROL_CLK_DIV_MAX
 29
 30#define KSPI2_STATUS_REG	0x08
 31#define  KSPI2_STATUS_IN_USE	0x01
 32#define  KSPI2_STATUS_BUSY	0x02
 33
 34#define KSPI2_DATA_REG	0x0c
 35
 36#define KSPI2_CS_NR_REG		0x10
 37#define  KSPI2_CS_NR_NONE	0xff
 38
 39#define KSPI2_MODE_BITS	(SPI_CPHA | SPI_CPOL)
 40#define KSPI2_NUM_CS	255
 41
 42#define KSPI2_SPEED_HZ_MIN(kspi)	(kspi->base_speed_hz / 65536)
 43#define KSPI2_SPEED_HZ_MAX(kspi)	(kspi->base_speed_hz / 2)
 44
 45/* timeout is 10 times the time to transfer one byte at slowest clock */
 46#define KSPI2_XFER_TIMEOUT_US(kspi)	(USEC_PER_SEC / \
 47					 KSPI2_SPEED_HZ_MIN(kspi) * 8 * 10)
 48
 49#define KSPI2_INUSE_SLEEP_US	(2 * USEC_PER_MSEC)
 50#define KSPI2_INUSE_TIMEOUT_US	(10 * USEC_PER_SEC)
 51
 52struct kspi2 {
 53	struct keba_spi_auxdev *auxdev;
 54	void __iomem *base;
 55	struct spi_controller *host;
 56
 57	u32 base_speed_hz; /* SPI base clock frequency in HZ */
 58	u8 control_shadow;
 59
 60	struct spi_device **device;
 61	int device_size;
 62};
 63
 64static int kspi2_inuse_lock(struct kspi2 *kspi)
 65{
 66	u8 sts;
 67	int ret;
 68
 69	/*
 70	 * The SPI controller has an IN_USE bit for locking access to the
 71	 * controller. This enables the use of the SPI controller by other none
 72	 * Linux processors.
 73	 *
 74	 * If the SPI controller is free, then the first read returns
 75	 * IN_USE == 0. After that the SPI controller is locked and further
 76	 * reads of IN_USE return 1.
 77	 *
 78	 * The SPI controller is unlocked by writing 1 into IN_USE.
 79	 *
 80	 * The IN_USE bit acts as a hardware semaphore for the SPI controller.
 81	 * Poll for semaphore, but sleep while polling to free the CPU.
 82	 */
 83	ret = readb_poll_timeout(kspi->base + KSPI2_STATUS_REG,
 84				 sts, (sts & KSPI2_STATUS_IN_USE) == 0,
 85				 KSPI2_INUSE_SLEEP_US, KSPI2_INUSE_TIMEOUT_US);
 86	if (ret != 0)
 87		dev_warn(&kspi->auxdev->auxdev.dev, "%s err!\n", __func__);
 88
 89	return ret;
 90}
 91
 92static void kspi2_inuse_unlock(struct kspi2 *kspi)
 93{
 94	/* unlock the controller by writing 1 into IN_USE */
 95	iowrite8(KSPI2_STATUS_IN_USE, kspi->base + KSPI2_STATUS_REG);
 96}
 97
 98static int kspi2_prepare_hardware(struct spi_controller *host)
 99{
100	struct kspi2 *kspi = spi_controller_get_devdata(host);
101
102	/* lock hardware semaphore before actual use of controller */
103	return kspi2_inuse_lock(kspi);
104}
105
106static int kspi2_unprepare_hardware(struct spi_controller *host)
107{
108	struct kspi2 *kspi = spi_controller_get_devdata(host);
109
110	/* unlock hardware semaphore after actual use of controller */
111	kspi2_inuse_unlock(kspi);
112
113	return 0;
114}
115
116static u8 kspi2_calc_minimal_divider(struct kspi2 *kspi, u32 max_speed_hz)
117{
118	u8 div;
119
120	/*
121	 * Divider values 2, 4, 8, 16, ..., 65536 are possible. They are coded
122	 * as 0, 1, 2, 3, ..., 15 in the CONTROL_CLK_DIV bit.
123	 */
124	for (div = 0; div < KSPI2_CONTROL_CLK_DIV_MAX; div++) {
125		if ((kspi->base_speed_hz >> (div + 1)) <= max_speed_hz)
126			return div;
127	}
128
129	/* return divider for slowest clock if loop fails to find one */
130	return KSPI2_CONTROL_CLK_DIV_MAX;
131}
132
133static void kspi2_write_control_reg(struct kspi2 *kspi, u8 val, u8 mask)
134{
135	/* write control register only when necessary to improve performance */
136	if (val != (kspi->control_shadow & mask)) {
137		kspi->control_shadow = (kspi->control_shadow & ~mask) | val;
138		iowrite8(kspi->control_shadow, kspi->base + KSPI2_CONTROL_REG);
139	}
140}
141
142static int kspi2_txrx_byte(struct kspi2 *kspi, u8 tx, u8 *rx)
143{
144	u8 sts;
145	int ret;
146
147	/* start transfer by writing TX byte */
148	iowrite8(tx, kspi->base + KSPI2_DATA_REG);
149
150	/* wait till finished (BUSY == 0) */
151	ret = readb_poll_timeout(kspi->base + KSPI2_STATUS_REG,
152				 sts, (sts & KSPI2_STATUS_BUSY) == 0,
153				 0, KSPI2_XFER_TIMEOUT_US(kspi));
154	if (ret != 0)
155		return ret;
156
157	/* read RX byte */
158	if (rx)
159		*rx = ioread8(kspi->base + KSPI2_DATA_REG);
160
161	return 0;
162}
163
164static int kspi2_process_transfer(struct kspi2 *kspi, struct spi_transfer *t)
165{
166	u8 tx = 0;
167	u8 rx;
168	int i;
169	int ret;
170
171	for (i = 0; i < t->len; i++) {
172		if (t->tx_buf)
173			tx = ((const u8 *)t->tx_buf)[i];
174
175		ret = kspi2_txrx_byte(kspi, tx, &rx);
176		if (ret)
177			return ret;
178
179		if (t->rx_buf)
180			((u8 *)t->rx_buf)[i] = rx;
181	}
182
183	return 0;
184}
185
186static int kspi2_setup_transfer(struct kspi2 *kspi,
187				 struct spi_device *spi,
188				 struct spi_transfer *t)
189{
190	u32 max_speed_hz = spi->max_speed_hz;
191	u8 clk_div;
192
193	/*
194	 * spi_device (spi) has default parameters. Some of these can be
195	 * overwritten by parameters in spi_transfer (t).
196	 */
197	if (t->bits_per_word && ((t->bits_per_word % 8) != 0)) {
198		dev_err(&spi->dev, "Word width %d not supported!\n",
199			t->bits_per_word);
200
201		return -EINVAL;
202	}
203
204	if (t->speed_hz && (t->speed_hz < max_speed_hz))
205		max_speed_hz = t->speed_hz;
206
207	clk_div = kspi2_calc_minimal_divider(kspi, max_speed_hz);
208	kspi2_write_control_reg(kspi, clk_div, KSPI2_CONTROL_CLK_DIV_MASK);
209
210	return 0;
211}
212
213static int kspi2_transfer_one(struct spi_controller *host,
214			      struct spi_device *spi,
215			      struct spi_transfer *t)
216{
217	struct kspi2 *kspi = spi_controller_get_devdata(host);
218	int ret;
219
220	ret = kspi2_setup_transfer(kspi, spi, t);
221	if (ret != 0)
222		return ret;
223
224	if (t->len) {
225		ret = kspi2_process_transfer(kspi, t);
226		if (ret != 0)
227			return ret;
228	}
229
230	return 0;
231}
232
233static void kspi2_set_cs(struct spi_device *spi, bool enable)
234{
235	struct spi_controller *host = spi->controller;
236	struct kspi2 *kspi = spi_controller_get_devdata(host);
237
238	/* controller is using active low chip select signals by design */
239	if (!enable)
240		iowrite8(spi_get_chipselect(spi, 0), kspi->base + KSPI2_CS_NR_REG);
241	else
242		iowrite8(KSPI2_CS_NR_NONE, kspi->base + KSPI2_CS_NR_REG);
243}
244
245static int kspi2_prepare_message(struct spi_controller *host,
246				 struct spi_message *msg)
247{
248	struct kspi2 *kspi = spi_controller_get_devdata(host);
249	struct spi_device *spi = msg->spi;
250	u8 mode = 0;
251
252	/* setup SPI clock phase and polarity */
253	if (spi->mode & SPI_CPHA)
254		mode |= KSPI2_CONTROL_CPHA;
255	if (spi->mode & SPI_CPOL)
256		mode |= KSPI2_CONTROL_CPOL;
257	kspi2_write_control_reg(kspi, mode, KSPI2_CONTROL_CLK_MODE_MASK);
258
259	return 0;
260}
261
262static int kspi2_setup(struct spi_device *spi)
263{
264	struct kspi2 *kspi = spi_controller_get_devdata(spi->controller);
265
266	/*
267	 * Check only parameters. Actual setup is done in kspi2_prepare_message
268	 * and directly before the SPI transfer starts.
269	 */
270
271	if (spi->mode & ~KSPI2_MODE_BITS) {
272		dev_err(&spi->dev, "Mode %d not supported!\n", spi->mode);
273
274		return -EINVAL;
275	}
276
277	if ((spi->bits_per_word % 8) != 0) {
278		dev_err(&spi->dev, "Word width %d not supported!\n",
279			spi->bits_per_word);
280
281		return -EINVAL;
282	}
283
284	if ((spi->max_speed_hz == 0) ||
285	    (spi->max_speed_hz > KSPI2_SPEED_HZ_MAX(kspi)))
286		spi->max_speed_hz = KSPI2_SPEED_HZ_MAX(kspi);
287
288	if (spi->max_speed_hz < KSPI2_SPEED_HZ_MIN(kspi)) {
289		dev_err(&spi->dev, "Requested speed of %d Hz is too low!\n",
290			spi->max_speed_hz);
291
292		return -EINVAL;
293	}
294
295	return 0;
296}
297
298static void kspi2_unregister_devices(struct kspi2 *kspi)
299{
300	int i;
301
302	for (i = 0; i < kspi->device_size; i++) {
303		struct spi_device *device = kspi->device[i];
304
305		if (device)
306			spi_unregister_device(device);
307	}
308}
309
310static int kspi2_register_devices(struct kspi2 *kspi)
311{
312	struct spi_board_info *info = kspi->auxdev->info;
313	int i;
314
315	/* register all known SPI devices */
316	for (i = 0; i < kspi->auxdev->info_size; i++) {
317		struct spi_device *device = spi_new_device(kspi->host, &info[i]);
318
319		if (!device) {
320			kspi2_unregister_devices(kspi);
321
322			return -ENODEV;
323		}
324		kspi->device[i] = device;
325	}
326
327	return 0;
328}
329
330static void kspi2_init(struct kspi2 *kspi)
331{
332	iowrite8(KSPI2_CONTROL_INIT, kspi->base + KSPI2_CONTROL_REG);
333	kspi->control_shadow = KSPI2_CONTROL_INIT;
334
335	iowrite8(KSPI2_CS_NR_NONE, kspi->base + KSPI2_CS_NR_REG);
336}
337
338static int kspi2_probe(struct auxiliary_device *auxdev,
339		       const struct auxiliary_device_id *id)
340{
341	struct device *dev = &auxdev->dev;
342	struct spi_controller *host;
343	struct kspi2 *kspi;
344	u8 clk_reg;
345	int ret;
346
347	host = devm_spi_alloc_host(dev, sizeof(struct kspi2));
348	if (!host)
349		return -ENOMEM;
350	kspi = spi_controller_get_devdata(host);
351	kspi->auxdev = container_of(auxdev, struct keba_spi_auxdev, auxdev);
352	kspi->host = host;
353	kspi->device = devm_kcalloc(dev, kspi->auxdev->info_size,
354				    sizeof(*kspi->device), GFP_KERNEL);
355	if (!kspi->device)
356		return -ENOMEM;
357	kspi->device_size = kspi->auxdev->info_size;
358	auxiliary_set_drvdata(auxdev, kspi);
359
360	kspi->base = devm_ioremap_resource(dev, &kspi->auxdev->io);
361	if (IS_ERR(kspi->base))
362		return PTR_ERR(kspi->base);
363
364	/* read the SPI base clock frequency */
365	clk_reg = ioread8(kspi->base + KSPI2_CLK_FREQ_REG);
366	switch (clk_reg & KSPI2_CLK_FREQ_MASK) {
367	case KSPI2_CLK_FREQ_62_5M:
368		kspi->base_speed_hz = 62500000; break;
369	case KSPI2_CLK_FREQ_33_3M:
370		kspi->base_speed_hz = 33333333; break;
371	case KSPI2_CLK_FREQ_125M:
372		kspi->base_speed_hz = 125000000; break;
373	case KSPI2_CLK_FREQ_50M:
374		kspi->base_speed_hz = 50000000; break;
375	case KSPI2_CLK_FREQ_100M:
376		kspi->base_speed_hz = 100000000; break;
377	default:
378		dev_err(dev, "Undefined SPI base clock frequency!\n");
379		return -ENODEV;
380	}
381
382	kspi2_init(kspi);
383
384	host->bus_num = -1;
385	host->num_chipselect = KSPI2_NUM_CS;
386	host->mode_bits = KSPI2_MODE_BITS;
387	host->setup = kspi2_setup;
388	host->prepare_transfer_hardware = kspi2_prepare_hardware;
389	host->unprepare_transfer_hardware = kspi2_unprepare_hardware;
390	host->prepare_message = kspi2_prepare_message;
391	host->set_cs = kspi2_set_cs;
392	host->transfer_one = kspi2_transfer_one;
393	ret = devm_spi_register_controller(dev, host);
394	if (ret) {
395		dev_err(dev, "Failed to register host (%d)!\n", ret);
396		return ret;
397	}
398
399	ret = kspi2_register_devices(kspi);
400	if (ret) {
401		dev_err(dev, "Failed to register devices (%d)!\n", ret);
402		return ret;
403	}
404
405	return 0;
406}
407
408static void kspi2_remove(struct auxiliary_device *auxdev)
409{
410	struct kspi2 *kspi = auxiliary_get_drvdata(auxdev);
411
412	kspi2_unregister_devices(kspi);
413}
414
415static const struct auxiliary_device_id kspi2_devtype_aux[] = {
416	{ .name = "keba.spi" },
417	{ },
418};
419MODULE_DEVICE_TABLE(auxiliary, kspi2_devtype_aux);
420
421static struct auxiliary_driver kspi2_driver_aux = {
422	.name = KSPI2,
423	.id_table = kspi2_devtype_aux,
424	.probe = kspi2_probe,
425	.remove = kspi2_remove,
426};
427module_auxiliary_driver(kspi2_driver_aux);
428
429MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>");
430MODULE_DESCRIPTION("KEBA SPI host controller driver");
431MODULE_LICENSE("GPL");
~/ Read-only file preview.