brintos

brintos / linux-shallow public Read only

0
0
Text · 9.5 KiB · 28f0612 Raw
369 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * MPC52xx PSC in SPI mode driver.4 *5 * Maintainer: Dragos Carp6 *7 * Copyright (C) 2006 TOPTICA Photonics AG.8 */9 10#include <linux/module.h>11#include <linux/types.h>12#include <linux/errno.h>13#include <linux/interrupt.h>14#include <linux/platform_device.h>15#include <linux/property.h>16#include <linux/workqueue.h>17#include <linux/completion.h>18#include <linux/io.h>19#include <linux/delay.h>20#include <linux/spi/spi.h>21#include <linux/slab.h>22 23#include <asm/mpc52xx.h>24#include <asm/mpc52xx_psc.h>25 26#define MCLK 20000000 /* PSC port MClk in hz */27 28struct mpc52xx_psc_spi {29	/* driver internal data */30	struct mpc52xx_psc __iomem *psc;31	struct mpc52xx_psc_fifo __iomem *fifo;32	int irq;33	u8 bits_per_word;34 35	struct completion done;36};37 38/* controller state */39struct mpc52xx_psc_spi_cs {40	int bits_per_word;41	int speed_hz;42};43 44/* set clock freq, clock ramp, bits per work45 * if t is NULL then reset the values to the default values46 */47static int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi,48		struct spi_transfer *t)49{50	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;51 52	cs->speed_hz = (t && t->speed_hz)53			? t->speed_hz : spi->max_speed_hz;54	cs->bits_per_word = (t && t->bits_per_word)55			? t->bits_per_word : spi->bits_per_word;56	cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;57	return 0;58}59 60static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)61{62	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;63	struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller);64	struct mpc52xx_psc __iomem *psc = mps->psc;65	u32 sicr;66	u16 ccr;67 68	sicr = in_be32(&psc->sicr);69 70	/* Set clock phase and polarity */71	if (spi->mode & SPI_CPHA)72		sicr |= 0x00001000;73	else74		sicr &= ~0x00001000;75	if (spi->mode & SPI_CPOL)76		sicr |= 0x00002000;77	else78		sicr &= ~0x00002000;79 80	if (spi->mode & SPI_LSB_FIRST)81		sicr |= 0x10000000;82	else83		sicr &= ~0x10000000;84	out_be32(&psc->sicr, sicr);85 86	/* Set clock frequency and bits per word87	 * Because psc->ccr is defined as 16bit register instead of 32bit88	 * just set the lower byte of BitClkDiv89	 */90	ccr = in_be16((u16 __iomem *)&psc->ccr);91	ccr &= 0xFF00;92	if (cs->speed_hz)93		ccr |= (MCLK / cs->speed_hz - 1) & 0xFF;94	else /* by default SPI Clk 1MHz */95		ccr |= (MCLK / 1000000 - 1) & 0xFF;96	out_be16((u16 __iomem *)&psc->ccr, ccr);97	mps->bits_per_word = cs->bits_per_word;98}99 100#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1)101/* wake up when 80% fifo full */102#define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100)103 104static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,105						struct spi_transfer *t)106{107	struct mpc52xx_psc_spi *mps = spi_controller_get_devdata(spi->controller);108	struct mpc52xx_psc __iomem *psc = mps->psc;109	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;110	unsigned rb = 0;	/* number of bytes receieved */111	unsigned sb = 0;	/* number of bytes sent */112	unsigned char *rx_buf = (unsigned char *)t->rx_buf;113	unsigned char *tx_buf = (unsigned char *)t->tx_buf;114	unsigned rfalarm;115	unsigned send_at_once = MPC52xx_PSC_BUFSIZE;116	unsigned recv_at_once;117	int last_block = 0;118 119	if (!t->tx_buf && !t->rx_buf && t->len)120		return -EINVAL;121 122	/* enable transmiter/receiver */123	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);124	while (rb < t->len) {125		if (t->len - rb > MPC52xx_PSC_BUFSIZE) {126			rfalarm = MPC52xx_PSC_RFALARM;127			last_block = 0;128		} else {129			send_at_once = t->len - sb;130			rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb);131			last_block = 1;132		}133 134		dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once);135		for (; send_at_once; sb++, send_at_once--) {136			/* set EOF flag before the last word is sent */137			if (send_at_once == 1 && last_block)138				out_8(&psc->ircr2, 0x01);139 140			if (tx_buf)141				out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]);142			else143				out_8(&psc->mpc52xx_psc_buffer_8, 0);144		}145 146 147		/* enable interrupts and wait for wake up148		 * if just one byte is expected the Rx FIFO genererates no149		 * FFULL interrupt, so activate the RxRDY interrupt150		 */151		out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);152		if (t->len - rb == 1) {153			out_8(&psc->mode, 0);154		} else {155			out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);156			out_be16(&fifo->rfalarm, rfalarm);157		}158		out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY);159		wait_for_completion(&mps->done);160		recv_at_once = in_be16(&fifo->rfnum);161		dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once);162 163		send_at_once = recv_at_once;164		if (rx_buf) {165			for (; recv_at_once; rb++, recv_at_once--)166				rx_buf[rb] = in_8(&psc->mpc52xx_psc_buffer_8);167		} else {168			for (; recv_at_once; rb++, recv_at_once--)169				in_8(&psc->mpc52xx_psc_buffer_8);170		}171	}172	/* disable transmiter/receiver */173	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);174 175	return 0;176}177 178static int mpc52xx_psc_spi_transfer_one_message(struct spi_controller *ctlr,179						struct spi_message *m)180{181	struct spi_device *spi;182	struct spi_transfer *t = NULL;183	unsigned cs_change;184	int status;185 186	spi = m->spi;187	cs_change = 1;188	status = 0;189	list_for_each_entry (t, &m->transfers, transfer_list) {190		if (t->bits_per_word || t->speed_hz) {191			status = mpc52xx_psc_spi_transfer_setup(spi, t);192			if (status < 0)193				break;194		}195 196		if (cs_change)197			mpc52xx_psc_spi_activate_cs(spi);198		cs_change = t->cs_change;199 200		status = mpc52xx_psc_spi_transfer_rxtx(spi, t);201		if (status)202			break;203		m->actual_length += t->len;204 205		spi_transfer_delay_exec(t);206	}207 208	m->status = status;209 210	mpc52xx_psc_spi_transfer_setup(spi, NULL);211 212	spi_finalize_current_message(ctlr);213 214	return 0;215}216 217static int mpc52xx_psc_spi_setup(struct spi_device *spi)218{219	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;220 221	if (spi->bits_per_word%8)222		return -EINVAL;223 224	if (!cs) {225		cs = kzalloc(sizeof(*cs), GFP_KERNEL);226		if (!cs)227			return -ENOMEM;228		spi->controller_state = cs;229	}230 231	cs->bits_per_word = spi->bits_per_word;232	cs->speed_hz = spi->max_speed_hz;233 234	return 0;235}236 237static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)238{239	kfree(spi->controller_state);240}241 242static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)243{244	struct mpc52xx_psc __iomem *psc = mps->psc;245	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;246	u32 mclken_div;247	int ret;248 249	/* default sysclk is 512MHz */250	mclken_div = 512000000 / MCLK;251	ret = mpc52xx_set_psc_clkdiv(psc_id, mclken_div);252	if (ret)253		return ret;254 255	/* Reset the PSC into a known state */256	out_8(&psc->command, MPC52xx_PSC_RST_RX);257	out_8(&psc->command, MPC52xx_PSC_RST_TX);258	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);259 260	/* Disable interrupts, interrupts are based on alarm level */261	out_be16(&psc->mpc52xx_psc_imr, 0);262	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);263	out_8(&fifo->rfcntl, 0);264	out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);265 266	/* Configure 8bit codec mode as a SPI host and use EOF flags */267	/* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */268	out_be32(&psc->sicr, 0x0180C800);269	out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */270 271	/* Set 2ms DTL delay */272	out_8(&psc->ctur, 0x00);273	out_8(&psc->ctlr, 0x84);274 275	mps->bits_per_word = 8;276 277	return 0;278}279 280static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id)281{282	struct mpc52xx_psc_spi *mps = (struct mpc52xx_psc_spi *)dev_id;283	struct mpc52xx_psc __iomem *psc = mps->psc;284 285	/* disable interrupt and wake up the work queue */286	if (in_be16(&psc->mpc52xx_psc_isr) & MPC52xx_PSC_IMR_RXRDY) {287		out_be16(&psc->mpc52xx_psc_imr, 0);288		complete(&mps->done);289		return IRQ_HANDLED;290	}291	return IRQ_NONE;292}293 294static int mpc52xx_psc_spi_of_probe(struct platform_device *pdev)295{296	struct device *dev = &pdev->dev;297	struct mpc52xx_psc_spi *mps;298	struct spi_controller *host;299	u32 bus_num;300	int ret;301 302	host = devm_spi_alloc_host(dev, sizeof(*mps));303	if (host == NULL)304		return -ENOMEM;305 306	dev_set_drvdata(dev, host);307	mps = spi_controller_get_devdata(host);308 309	/* the spi->mode bits understood by this driver: */310	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;311 312	ret = device_property_read_u32(dev, "cell-index", &bus_num);313	if (ret || bus_num > 5)314		return dev_err_probe(dev, ret ? : -EINVAL, "Invalid cell-index property\n");315	host->bus_num = bus_num + 1;316 317	host->num_chipselect = 255;318	host->setup = mpc52xx_psc_spi_setup;319	host->transfer_one_message = mpc52xx_psc_spi_transfer_one_message;320	host->cleanup = mpc52xx_psc_spi_cleanup;321 322	device_set_node(&host->dev, dev_fwnode(dev));323 324	mps->psc = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);325	if (IS_ERR(mps->psc))326		return dev_err_probe(dev, PTR_ERR(mps->psc), "could not ioremap I/O port range\n");327 328	/* On the 5200, fifo regs are immediately ajacent to the psc regs */329	mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc);330 331	mps->irq = platform_get_irq(pdev, 0);332	if (mps->irq < 0)333		return mps->irq;334 335	ret = devm_request_irq(dev, mps->irq, mpc52xx_psc_spi_isr, 0,336			       "mpc52xx-psc-spi", mps);337	if (ret)338		return ret;339 340	ret = mpc52xx_psc_spi_port_config(host->bus_num, mps);341	if (ret < 0)342		return dev_err_probe(dev, ret, "can't configure PSC! Is it capable of SPI?\n");343 344	init_completion(&mps->done);345 346	return devm_spi_register_controller(dev, host);347}348 349static const struct of_device_id mpc52xx_psc_spi_of_match[] = {350	{ .compatible = "fsl,mpc5200-psc-spi", },351	{ .compatible = "mpc5200-psc-spi", }, /* old */352	{}353};354 355MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);356 357static struct platform_driver mpc52xx_psc_spi_of_driver = {358	.probe = mpc52xx_psc_spi_of_probe,359	.driver = {360		.name = "mpc52xx-psc-spi",361		.of_match_table = mpc52xx_psc_spi_of_match,362	},363};364module_platform_driver(mpc52xx_psc_spi_of_driver);365 366MODULE_AUTHOR("Dragos Carp");367MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");368MODULE_LICENSE("GPL");369