brintos

brintos / linux-shallow public Read only

0
0
Text · 12.1 KiB · 03b820e Raw
547 lines · c
1/*2 * MicroWire interface driver for OMAP3 *4 * Copyright 2003 MontaVista Software Inc. <source@mvista.com>5 *6 * Ported to 2.6 OMAP uwire interface.7 * Copyright (C) 2004 Texas Instruments.8 *9 * Generalization patches by Juha Yrjola <juha.yrjola@nokia.com>10 *11 * Copyright (C) 2005 David Brownell (ported to 2.6 SPI interface)12 * Copyright (C) 2006 Nokia13 *14 * Many updates by Imre Deak <imre.deak@nokia.com>15 *16 * This program is free software; you can redistribute it and/or modify it17 * under the terms of the GNU General Public License as published by the18 * Free Software Foundation; either version 2 of the License, or (at your19 * option) any later version.20 *21 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED22 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF23 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31 */32#include <linux/kernel.h>33#include <linux/init.h>34#include <linux/delay.h>35#include <linux/platform_device.h>36#include <linux/interrupt.h>37#include <linux/err.h>38#include <linux/clk.h>39#include <linux/slab.h>40#include <linux/device.h>41 42#include <linux/spi/spi.h>43#include <linux/spi/spi_bitbang.h>44#include <linux/module.h>45#include <linux/io.h>46 47#include <asm/mach-types.h>48#include <linux/soc/ti/omap1-io.h>49#include <linux/soc/ti/omap1-soc.h>50#include <linux/soc/ti/omap1-mux.h>51 52/* FIXME address is now a platform device resource,53 * and irqs should show there too...54 */55#define UWIRE_BASE_PHYS		0xFFFB300056 57/* uWire Registers: */58#define UWIRE_IO_SIZE 0x2059#define UWIRE_TDR     0x0060#define UWIRE_RDR     0x0061#define UWIRE_CSR     0x0162#define UWIRE_SR1     0x0263#define UWIRE_SR2     0x0364#define UWIRE_SR3     0x0465#define UWIRE_SR4     0x0566#define UWIRE_SR5     0x0667 68/* CSR bits */69#define	RDRB	(1 << 15)70#define	CSRB	(1 << 14)71#define	START	(1 << 13)72#define	CS_CMD	(1 << 12)73 74/* SR1 or SR2 bits */75#define UWIRE_READ_FALLING_EDGE		0x000176#define UWIRE_READ_RISING_EDGE		0x000077#define UWIRE_WRITE_FALLING_EDGE	0x000078#define UWIRE_WRITE_RISING_EDGE		0x000279#define UWIRE_CS_ACTIVE_LOW		0x000080#define UWIRE_CS_ACTIVE_HIGH		0x000481#define UWIRE_FREQ_DIV_2		0x000082#define UWIRE_FREQ_DIV_4		0x000883#define UWIRE_FREQ_DIV_8		0x001084#define UWIRE_CHK_READY			0x002085#define UWIRE_CLK_INVERTED		0x004086 87 88struct uwire_spi {89	struct spi_bitbang	bitbang;90	struct clk		*ck;91};92 93struct uwire_state {94	unsigned	div1_idx;95};96 97/* REVISIT compile time constant for idx_shift? */98/*99 * Or, put it in a structure which is used throughout the driver;100 * that avoids having to issue two loads for each bit of static data.101 */102static unsigned int uwire_idx_shift = 2;103static void __iomem *uwire_base;104 105static inline void uwire_write_reg(int idx, u16 val)106{107	__raw_writew(val, uwire_base + (idx << uwire_idx_shift));108}109 110static inline u16 uwire_read_reg(int idx)111{112	return __raw_readw(uwire_base + (idx << uwire_idx_shift));113}114 115static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)116{117	u16	w, val = 0;118	int	shift, reg;119 120	if (flags & UWIRE_CLK_INVERTED)121		val ^= 0x03;122	val = flags & 0x3f;123	if (cs & 1)124		shift = 6;125	else126		shift = 0;127	if (cs <= 1)128		reg = UWIRE_SR1;129	else130		reg = UWIRE_SR2;131 132	w = uwire_read_reg(reg);133	w &= ~(0x3f << shift);134	w |= val << shift;135	uwire_write_reg(reg, w);136}137 138static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch)139{140	u16 w;141	int c = 0;142	unsigned long max_jiffies = jiffies + HZ;143 144	for (;;) {145		w = uwire_read_reg(UWIRE_CSR);146		if ((w & mask) == val)147			break;148		if (time_after(jiffies, max_jiffies)) {149			printk(KERN_ERR "%s: timeout. reg=%#06x "150					"mask=%#06x val=%#06x\n",151			       __func__, w, mask, val);152			return -1;153		}154		c++;155		if (might_not_catch && c > 64)156			break;157	}158	return 0;159}160 161static void uwire_set_clk1_div(int div1_idx)162{163	u16 w;164 165	w = uwire_read_reg(UWIRE_SR3);166	w &= ~(0x03 << 1);167	w |= div1_idx << 1;168	uwire_write_reg(UWIRE_SR3, w);169}170 171static void uwire_chipselect(struct spi_device *spi, int value)172{173	struct	uwire_state *ust = spi->controller_state;174	u16	w;175	int	old_cs;176 177 178	BUG_ON(wait_uwire_csr_flag(CSRB, 0, 0));179 180	w = uwire_read_reg(UWIRE_CSR);181	old_cs = (w >> 10) & 0x03;182	if (value == BITBANG_CS_INACTIVE || old_cs != spi_get_chipselect(spi, 0)) {183		/* Deselect this CS, or the previous CS */184		w &= ~CS_CMD;185		uwire_write_reg(UWIRE_CSR, w);186	}187	/* activate specfied chipselect */188	if (value == BITBANG_CS_ACTIVE) {189		uwire_set_clk1_div(ust->div1_idx);190		/* invert clock? */191		if (spi->mode & SPI_CPOL)192			uwire_write_reg(UWIRE_SR4, 1);193		else194			uwire_write_reg(UWIRE_SR4, 0);195 196		w = spi_get_chipselect(spi, 0) << 10;197		w |= CS_CMD;198		uwire_write_reg(UWIRE_CSR, w);199	}200}201 202static int uwire_txrx(struct spi_device *spi, struct spi_transfer *t)203{204	unsigned	len = t->len;205	unsigned	bits = t->bits_per_word;206	unsigned	bytes;207	u16		val, w;208	int		status = 0;209 210	if (!t->tx_buf && !t->rx_buf)211		return 0;212 213	w = spi_get_chipselect(spi, 0) << 10;214	w |= CS_CMD;215 216	if (t->tx_buf) {217		const u8	*buf = t->tx_buf;218 219		/* NOTE:  DMA could be used for TX transfers */220 221		/* write one or two bytes at a time */222		while (len >= 1) {223			/* tx bit 15 is first sent; we byteswap multibyte words224			 * (msb-first) on the way out from memory.225			 */226			val = *buf++;227			if (bits > 8) {228				bytes = 2;229				val |= *buf++ << 8;230			} else231				bytes = 1;232			val <<= 16 - bits;233 234#ifdef	VERBOSE235			pr_debug("%s: write-%d =%04x\n",236					dev_name(&spi->dev), bits, val);237#endif238			if (wait_uwire_csr_flag(CSRB, 0, 0))239				goto eio;240 241			uwire_write_reg(UWIRE_TDR, val);242 243			/* start write */244			val = START | w | (bits << 5);245 246			uwire_write_reg(UWIRE_CSR, val);247			len -= bytes;248 249			/* Wait till write actually starts.250			 * This is needed with MPU clock 60+ MHz.251			 * REVISIT: we may not have time to catch it...252			 */253			if (wait_uwire_csr_flag(CSRB, CSRB, 1))254				goto eio;255 256			status += bytes;257		}258 259		/* REVISIT:  save this for later to get more i/o overlap */260		if (wait_uwire_csr_flag(CSRB, 0, 0))261			goto eio;262 263	} else if (t->rx_buf) {264		u8		*buf = t->rx_buf;265 266		/* read one or two bytes at a time */267		while (len) {268			if (bits > 8) {269				bytes = 2;270			} else271				bytes = 1;272 273			/* start read */274			val = START | w | (bits << 0);275			uwire_write_reg(UWIRE_CSR, val);276			len -= bytes;277 278			/* Wait till read actually starts */279			(void) wait_uwire_csr_flag(CSRB, CSRB, 1);280 281			if (wait_uwire_csr_flag(RDRB | CSRB,282						RDRB, 0))283				goto eio;284 285			/* rx bit 0 is last received; multibyte words will286			 * be properly byteswapped on the way to memory.287			 */288			val = uwire_read_reg(UWIRE_RDR);289			val &= (1 << bits) - 1;290			*buf++ = (u8) val;291			if (bytes == 2)292				*buf++ = val >> 8;293			status += bytes;294#ifdef	VERBOSE295			pr_debug("%s: read-%d =%04x\n",296					dev_name(&spi->dev), bits, val);297#endif298 299		}300	}301	return status;302eio:303	return -EIO;304}305 306static int uwire_setup_transfer(struct spi_device *spi, struct spi_transfer *t)307{308	struct uwire_state	*ust = spi->controller_state;309	struct uwire_spi	*uwire;310	unsigned		flags = 0;311	unsigned		hz;312	unsigned long		rate;313	int			div1_idx;314	int			div1;315	int			div2;316	int			status;317 318	uwire = spi_controller_get_devdata(spi->controller);319 320	/* mode 0..3, clock inverted separately;321	 * standard nCS signaling;322	 * don't treat DI=high as "not ready"323	 */324	if (spi->mode & SPI_CS_HIGH)325		flags |= UWIRE_CS_ACTIVE_HIGH;326 327	if (spi->mode & SPI_CPOL)328		flags |= UWIRE_CLK_INVERTED;329 330	switch (spi->mode & SPI_MODE_X_MASK) {331	case SPI_MODE_0:332	case SPI_MODE_3:333		flags |= UWIRE_WRITE_FALLING_EDGE | UWIRE_READ_RISING_EDGE;334		break;335	case SPI_MODE_1:336	case SPI_MODE_2:337		flags |= UWIRE_WRITE_RISING_EDGE | UWIRE_READ_FALLING_EDGE;338		break;339	}340 341	/* assume it's already enabled */342	rate = clk_get_rate(uwire->ck);343 344	if (t != NULL)345		hz = t->speed_hz;346	else347		hz = spi->max_speed_hz;348 349	if (!hz) {350		pr_debug("%s: zero speed?\n", dev_name(&spi->dev));351		status = -EINVAL;352		goto done;353	}354 355	/* F_INT = mpu_xor_clk / DIV1 */356	for (div1_idx = 0; div1_idx < 4; div1_idx++) {357		switch (div1_idx) {358		case 0:359			div1 = 2;360			break;361		case 1:362			div1 = 4;363			break;364		case 2:365			div1 = 7;366			break;367		default:368		case 3:369			div1 = 10;370			break;371		}372		div2 = (rate / div1 + hz - 1) / hz;373		if (div2 <= 8)374			break;375	}376	if (div1_idx == 4) {377		pr_debug("%s: lowest clock %ld, need %d\n",378			dev_name(&spi->dev), rate / 10 / 8, hz);379		status = -EDOM;380		goto done;381	}382 383	/* we have to cache this and reset in uwire_chipselect as this is a384	 * global parameter and another uwire device can change it under385	 * us */386	ust->div1_idx = div1_idx;387	uwire_set_clk1_div(div1_idx);388 389	rate /= div1;390 391	switch (div2) {392	case 0:393	case 1:394	case 2:395		flags |= UWIRE_FREQ_DIV_2;396		rate /= 2;397		break;398	case 3:399	case 4:400		flags |= UWIRE_FREQ_DIV_4;401		rate /= 4;402		break;403	case 5:404	case 6:405	case 7:406	case 8:407		flags |= UWIRE_FREQ_DIV_8;408		rate /= 8;409		break;410	}411	omap_uwire_configure_mode(spi_get_chipselect(spi, 0), flags);412	pr_debug("%s: uwire flags %02x, armxor %lu KHz, SCK %lu KHz\n",413			__func__, flags,414			clk_get_rate(uwire->ck) / 1000,415			rate / 1000);416	status = 0;417done:418	return status;419}420 421static int uwire_setup(struct spi_device *spi)422{423	struct uwire_state *ust = spi->controller_state;424	bool initial_setup = false;425	int status;426 427	if (ust == NULL) {428		ust = kzalloc(sizeof(*ust), GFP_KERNEL);429		if (ust == NULL)430			return -ENOMEM;431		spi->controller_state = ust;432		initial_setup = true;433	}434 435	status = uwire_setup_transfer(spi, NULL);436	if (status && initial_setup)437		kfree(ust);438 439	return status;440}441 442static void uwire_cleanup(struct spi_device *spi)443{444	kfree(spi->controller_state);445}446 447static void uwire_off(struct uwire_spi *uwire)448{449	uwire_write_reg(UWIRE_SR3, 0);450	clk_disable_unprepare(uwire->ck);451	spi_controller_put(uwire->bitbang.ctlr);452}453 454static int uwire_probe(struct platform_device *pdev)455{456	struct spi_controller	*host;457	struct uwire_spi	*uwire;458	int			status;459 460	host = spi_alloc_host(&pdev->dev, sizeof(*uwire));461	if (!host)462		return -ENODEV;463 464	uwire = spi_controller_get_devdata(host);465 466	uwire_base = devm_ioremap(&pdev->dev, UWIRE_BASE_PHYS, UWIRE_IO_SIZE);467	if (!uwire_base) {468		dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");469		spi_controller_put(host);470		return -ENOMEM;471	}472 473	platform_set_drvdata(pdev, uwire);474 475	uwire->ck = devm_clk_get(&pdev->dev, "fck");476	if (IS_ERR(uwire->ck)) {477		status = PTR_ERR(uwire->ck);478		dev_dbg(&pdev->dev, "no functional clock?\n");479		spi_controller_put(host);480		return status;481	}482	clk_prepare_enable(uwire->ck);483 484	uwire_write_reg(UWIRE_SR3, 1);485 486	/* the spi->mode bits understood by this driver: */487	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;488	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);489	host->flags = SPI_CONTROLLER_HALF_DUPLEX;490 491	host->bus_num = 2;	/* "official" */492	host->num_chipselect = 4;493	host->setup = uwire_setup;494	host->cleanup = uwire_cleanup;495 496	uwire->bitbang.ctlr = host;497	uwire->bitbang.chipselect = uwire_chipselect;498	uwire->bitbang.setup_transfer = uwire_setup_transfer;499	uwire->bitbang.txrx_bufs = uwire_txrx;500 501	status = spi_bitbang_start(&uwire->bitbang);502	if (status < 0) {503		uwire_off(uwire);504	}505	return status;506}507 508static void uwire_remove(struct platform_device *pdev)509{510	struct uwire_spi	*uwire = platform_get_drvdata(pdev);511 512	// FIXME remove all child devices, somewhere ...513 514	spi_bitbang_stop(&uwire->bitbang);515	uwire_off(uwire);516}517 518/* work with hotplug and coldplug */519MODULE_ALIAS("platform:omap_uwire");520 521static struct platform_driver uwire_driver = {522	.driver = {523		.name		= "omap_uwire",524	},525	.probe = uwire_probe,526	.remove_new = uwire_remove,527	// suspend ... unuse ck528	// resume ... use ck529};530 531static int __init omap_uwire_init(void)532{533	return platform_driver_register(&uwire_driver);534}535 536static void __exit omap_uwire_exit(void)537{538	platform_driver_unregister(&uwire_driver);539}540 541subsys_initcall(omap_uwire_init);542module_exit(omap_uwire_exit);543 544MODULE_DESCRIPTION("MicroWire interface driver for OMAP");545MODULE_LICENSE("GPL");546 547