Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.36-rc4 573 lines 13 kB view raw
1/* 2 * orion_spi.c -- Marvell Orion SPI controller driver 3 * 4 * Author: Shadi Ammouri <shadi@marvell.com> 5 * Copyright (C) 2007-2008 Marvell Ltd. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/init.h> 13#include <linux/interrupt.h> 14#include <linux/delay.h> 15#include <linux/platform_device.h> 16#include <linux/err.h> 17#include <linux/io.h> 18#include <linux/spi/spi.h> 19#include <linux/spi/orion_spi.h> 20#include <asm/unaligned.h> 21 22#define DRIVER_NAME "orion_spi" 23 24#define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/ 25#define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */ 26 27#define ORION_SPI_IF_CTRL_REG 0x00 28#define ORION_SPI_IF_CONFIG_REG 0x04 29#define ORION_SPI_DATA_OUT_REG 0x08 30#define ORION_SPI_DATA_IN_REG 0x0c 31#define ORION_SPI_INT_CAUSE_REG 0x10 32 33#define ORION_SPI_IF_8_16_BIT_MODE (1 << 5) 34#define ORION_SPI_CLK_PRESCALE_MASK 0x1F 35 36struct orion_spi { 37 struct work_struct work; 38 39 /* Lock access to transfer list. */ 40 spinlock_t lock; 41 42 struct list_head msg_queue; 43 struct spi_master *master; 44 void __iomem *base; 45 unsigned int max_speed; 46 unsigned int min_speed; 47 struct orion_spi_info *spi_info; 48}; 49 50static struct workqueue_struct *orion_spi_wq; 51 52static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg) 53{ 54 return orion_spi->base + reg; 55} 56 57static inline void 58orion_spi_setbits(struct orion_spi *orion_spi, u32 reg, u32 mask) 59{ 60 void __iomem *reg_addr = spi_reg(orion_spi, reg); 61 u32 val; 62 63 val = readl(reg_addr); 64 val |= mask; 65 writel(val, reg_addr); 66} 67 68static inline void 69orion_spi_clrbits(struct orion_spi *orion_spi, u32 reg, u32 mask) 70{ 71 void __iomem *reg_addr = spi_reg(orion_spi, reg); 72 u32 val; 73 74 val = readl(reg_addr); 75 val &= ~mask; 76 writel(val, reg_addr); 77} 78 79static int orion_spi_set_transfer_size(struct orion_spi *orion_spi, int size) 80{ 81 if (size == 16) { 82 orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, 83 ORION_SPI_IF_8_16_BIT_MODE); 84 } else if (size == 8) { 85 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CONFIG_REG, 86 ORION_SPI_IF_8_16_BIT_MODE); 87 } else { 88 pr_debug("Bad bits per word value %d (only 8 or 16 are " 89 "allowed).\n", size); 90 return -EINVAL; 91 } 92 93 return 0; 94} 95 96static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) 97{ 98 u32 tclk_hz; 99 u32 rate; 100 u32 prescale; 101 u32 reg; 102 struct orion_spi *orion_spi; 103 104 orion_spi = spi_master_get_devdata(spi->master); 105 106 tclk_hz = orion_spi->spi_info->tclk; 107 108 /* 109 * the supported rates are: 4,6,8...30 110 * round up as we look for equal or less speed 111 */ 112 rate = DIV_ROUND_UP(tclk_hz, speed); 113 rate = roundup(rate, 2); 114 115 /* check if requested speed is too small */ 116 if (rate > 30) 117 return -EINVAL; 118 119 if (rate < 4) 120 rate = 4; 121 122 /* Convert the rate to SPI clock divisor value. */ 123 prescale = 0x10 + rate/2; 124 125 reg = readl(spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); 126 reg = ((reg & ~ORION_SPI_CLK_PRESCALE_MASK) | prescale); 127 writel(reg, spi_reg(orion_spi, ORION_SPI_IF_CONFIG_REG)); 128 129 return 0; 130} 131 132/* 133 * called only when no transfer is active on the bus 134 */ 135static int 136orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) 137{ 138 struct orion_spi *orion_spi; 139 unsigned int speed = spi->max_speed_hz; 140 unsigned int bits_per_word = spi->bits_per_word; 141 int rc; 142 143 orion_spi = spi_master_get_devdata(spi->master); 144 145 if ((t != NULL) && t->speed_hz) 146 speed = t->speed_hz; 147 148 if ((t != NULL) && t->bits_per_word) 149 bits_per_word = t->bits_per_word; 150 151 rc = orion_spi_baudrate_set(spi, speed); 152 if (rc) 153 return rc; 154 155 return orion_spi_set_transfer_size(orion_spi, bits_per_word); 156} 157 158static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable) 159{ 160 if (enable) 161 orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); 162 else 163 orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); 164} 165 166static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi) 167{ 168 int i; 169 170 for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) { 171 if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG))) 172 return 1; 173 else 174 udelay(1); 175 } 176 177 return -1; 178} 179 180static inline int 181orion_spi_write_read_8bit(struct spi_device *spi, 182 const u8 **tx_buf, u8 **rx_buf) 183{ 184 void __iomem *tx_reg, *rx_reg, *int_reg; 185 struct orion_spi *orion_spi; 186 187 orion_spi = spi_master_get_devdata(spi->master); 188 tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG); 189 rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG); 190 int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG); 191 192 /* clear the interrupt cause register */ 193 writel(0x0, int_reg); 194 195 if (tx_buf && *tx_buf) 196 writel(*(*tx_buf)++, tx_reg); 197 else 198 writel(0, tx_reg); 199 200 if (orion_spi_wait_till_ready(orion_spi) < 0) { 201 dev_err(&spi->dev, "TXS timed out\n"); 202 return -1; 203 } 204 205 if (rx_buf && *rx_buf) 206 *(*rx_buf)++ = readl(rx_reg); 207 208 return 1; 209} 210 211static inline int 212orion_spi_write_read_16bit(struct spi_device *spi, 213 const u16 **tx_buf, u16 **rx_buf) 214{ 215 void __iomem *tx_reg, *rx_reg, *int_reg; 216 struct orion_spi *orion_spi; 217 218 orion_spi = spi_master_get_devdata(spi->master); 219 tx_reg = spi_reg(orion_spi, ORION_SPI_DATA_OUT_REG); 220 rx_reg = spi_reg(orion_spi, ORION_SPI_DATA_IN_REG); 221 int_reg = spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG); 222 223 /* clear the interrupt cause register */ 224 writel(0x0, int_reg); 225 226 if (tx_buf && *tx_buf) 227 writel(__cpu_to_le16(get_unaligned((*tx_buf)++)), tx_reg); 228 else 229 writel(0, tx_reg); 230 231 if (orion_spi_wait_till_ready(orion_spi) < 0) { 232 dev_err(&spi->dev, "TXS timed out\n"); 233 return -1; 234 } 235 236 if (rx_buf && *rx_buf) 237 put_unaligned(__le16_to_cpu(readl(rx_reg)), (*rx_buf)++); 238 239 return 1; 240} 241 242static unsigned int 243orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer) 244{ 245 struct orion_spi *orion_spi; 246 unsigned int count; 247 int word_len; 248 249 orion_spi = spi_master_get_devdata(spi->master); 250 word_len = spi->bits_per_word; 251 count = xfer->len; 252 253 if (word_len == 8) { 254 const u8 *tx = xfer->tx_buf; 255 u8 *rx = xfer->rx_buf; 256 257 do { 258 if (orion_spi_write_read_8bit(spi, &tx, &rx) < 0) 259 goto out; 260 count--; 261 } while (count); 262 } else if (word_len == 16) { 263 const u16 *tx = xfer->tx_buf; 264 u16 *rx = xfer->rx_buf; 265 266 do { 267 if (orion_spi_write_read_16bit(spi, &tx, &rx) < 0) 268 goto out; 269 count -= 2; 270 } while (count); 271 } 272 273out: 274 return xfer->len - count; 275} 276 277 278static void orion_spi_work(struct work_struct *work) 279{ 280 struct orion_spi *orion_spi = 281 container_of(work, struct orion_spi, work); 282 283 spin_lock_irq(&orion_spi->lock); 284 while (!list_empty(&orion_spi->msg_queue)) { 285 struct spi_message *m; 286 struct spi_device *spi; 287 struct spi_transfer *t = NULL; 288 int par_override = 0; 289 int status = 0; 290 int cs_active = 0; 291 292 m = container_of(orion_spi->msg_queue.next, struct spi_message, 293 queue); 294 295 list_del_init(&m->queue); 296 spin_unlock_irq(&orion_spi->lock); 297 298 spi = m->spi; 299 300 /* Load defaults */ 301 status = orion_spi_setup_transfer(spi, NULL); 302 303 if (status < 0) 304 goto msg_done; 305 306 list_for_each_entry(t, &m->transfers, transfer_list) { 307 if (par_override || t->speed_hz || t->bits_per_word) { 308 par_override = 1; 309 status = orion_spi_setup_transfer(spi, t); 310 if (status < 0) 311 break; 312 if (!t->speed_hz && !t->bits_per_word) 313 par_override = 0; 314 } 315 316 if (!cs_active) { 317 orion_spi_set_cs(orion_spi, 1); 318 cs_active = 1; 319 } 320 321 if (t->len) 322 m->actual_length += 323 orion_spi_write_read(spi, t); 324 325 if (t->delay_usecs) 326 udelay(t->delay_usecs); 327 328 if (t->cs_change) { 329 orion_spi_set_cs(orion_spi, 0); 330 cs_active = 0; 331 } 332 } 333 334msg_done: 335 if (cs_active) 336 orion_spi_set_cs(orion_spi, 0); 337 338 m->status = status; 339 m->complete(m->context); 340 341 spin_lock_irq(&orion_spi->lock); 342 } 343 344 spin_unlock_irq(&orion_spi->lock); 345} 346 347static int __init orion_spi_reset(struct orion_spi *orion_spi) 348{ 349 /* Verify that the CS is deasserted */ 350 orion_spi_set_cs(orion_spi, 0); 351 352 return 0; 353} 354 355static int orion_spi_setup(struct spi_device *spi) 356{ 357 struct orion_spi *orion_spi; 358 359 orion_spi = spi_master_get_devdata(spi->master); 360 361 /* Fix ac timing if required. */ 362 if (orion_spi->spi_info->enable_clock_fix) 363 orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, 364 (1 << 14)); 365 366 if ((spi->max_speed_hz == 0) 367 || (spi->max_speed_hz > orion_spi->max_speed)) 368 spi->max_speed_hz = orion_spi->max_speed; 369 370 if (spi->max_speed_hz < orion_spi->min_speed) { 371 dev_err(&spi->dev, "setup: requested speed too low %d Hz\n", 372 spi->max_speed_hz); 373 return -EINVAL; 374 } 375 376 /* 377 * baudrate & width will be set orion_spi_setup_transfer 378 */ 379 return 0; 380} 381 382static int orion_spi_transfer(struct spi_device *spi, struct spi_message *m) 383{ 384 struct orion_spi *orion_spi; 385 struct spi_transfer *t = NULL; 386 unsigned long flags; 387 388 m->actual_length = 0; 389 m->status = 0; 390 391 /* reject invalid messages and transfers */ 392 if (list_empty(&m->transfers) || !m->complete) 393 return -EINVAL; 394 395 orion_spi = spi_master_get_devdata(spi->master); 396 397 list_for_each_entry(t, &m->transfers, transfer_list) { 398 unsigned int bits_per_word = spi->bits_per_word; 399 400 if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { 401 dev_err(&spi->dev, 402 "message rejected : " 403 "invalid transfer data buffers\n"); 404 goto msg_rejected; 405 } 406 407 if ((t != NULL) && t->bits_per_word) 408 bits_per_word = t->bits_per_word; 409 410 if ((bits_per_word != 8) && (bits_per_word != 16)) { 411 dev_err(&spi->dev, 412 "message rejected : " 413 "invalid transfer bits_per_word (%d bits)\n", 414 bits_per_word); 415 goto msg_rejected; 416 } 417 /*make sure buffer length is even when working in 16 bit mode*/ 418 if ((t != NULL) && (t->bits_per_word == 16) && (t->len & 1)) { 419 dev_err(&spi->dev, 420 "message rejected : " 421 "odd data length (%d) while in 16 bit mode\n", 422 t->len); 423 goto msg_rejected; 424 } 425 426 if (t->speed_hz && t->speed_hz < orion_spi->min_speed) { 427 dev_err(&spi->dev, 428 "message rejected : " 429 "device min speed (%d Hz) exceeds " 430 "required transfer speed (%d Hz)\n", 431 orion_spi->min_speed, t->speed_hz); 432 goto msg_rejected; 433 } 434 } 435 436 437 spin_lock_irqsave(&orion_spi->lock, flags); 438 list_add_tail(&m->queue, &orion_spi->msg_queue); 439 queue_work(orion_spi_wq, &orion_spi->work); 440 spin_unlock_irqrestore(&orion_spi->lock, flags); 441 442 return 0; 443msg_rejected: 444 /* Message rejected and not queued */ 445 m->status = -EINVAL; 446 if (m->complete) 447 m->complete(m->context); 448 return -EINVAL; 449} 450 451static int __init orion_spi_probe(struct platform_device *pdev) 452{ 453 struct spi_master *master; 454 struct orion_spi *spi; 455 struct resource *r; 456 struct orion_spi_info *spi_info; 457 int status = 0; 458 459 spi_info = pdev->dev.platform_data; 460 461 master = spi_alloc_master(&pdev->dev, sizeof *spi); 462 if (master == NULL) { 463 dev_dbg(&pdev->dev, "master allocation failed\n"); 464 return -ENOMEM; 465 } 466 467 if (pdev->id != -1) 468 master->bus_num = pdev->id; 469 470 /* we support only mode 0, and no options */ 471 master->mode_bits = 0; 472 473 master->setup = orion_spi_setup; 474 master->transfer = orion_spi_transfer; 475 master->num_chipselect = ORION_NUM_CHIPSELECTS; 476 477 dev_set_drvdata(&pdev->dev, master); 478 479 spi = spi_master_get_devdata(master); 480 spi->master = master; 481 spi->spi_info = spi_info; 482 483 spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4); 484 spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30); 485 486 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 487 if (r == NULL) { 488 status = -ENODEV; 489 goto out; 490 } 491 492 if (!request_mem_region(r->start, (r->end - r->start) + 1, 493 dev_name(&pdev->dev))) { 494 status = -EBUSY; 495 goto out; 496 } 497 spi->base = ioremap(r->start, SZ_1K); 498 499 INIT_WORK(&spi->work, orion_spi_work); 500 501 spin_lock_init(&spi->lock); 502 INIT_LIST_HEAD(&spi->msg_queue); 503 504 if (orion_spi_reset(spi) < 0) 505 goto out_rel_mem; 506 507 status = spi_register_master(master); 508 if (status < 0) 509 goto out_rel_mem; 510 511 return status; 512 513out_rel_mem: 514 release_mem_region(r->start, (r->end - r->start) + 1); 515 516out: 517 spi_master_put(master); 518 return status; 519} 520 521 522static int __exit orion_spi_remove(struct platform_device *pdev) 523{ 524 struct spi_master *master; 525 struct orion_spi *spi; 526 struct resource *r; 527 528 master = dev_get_drvdata(&pdev->dev); 529 spi = spi_master_get_devdata(master); 530 531 cancel_work_sync(&spi->work); 532 533 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 534 release_mem_region(r->start, (r->end - r->start) + 1); 535 536 spi_unregister_master(master); 537 538 return 0; 539} 540 541MODULE_ALIAS("platform:" DRIVER_NAME); 542 543static struct platform_driver orion_spi_driver = { 544 .driver = { 545 .name = DRIVER_NAME, 546 .owner = THIS_MODULE, 547 }, 548 .remove = __exit_p(orion_spi_remove), 549}; 550 551static int __init orion_spi_init(void) 552{ 553 orion_spi_wq = create_singlethread_workqueue( 554 orion_spi_driver.driver.name); 555 if (orion_spi_wq == NULL) 556 return -ENOMEM; 557 558 return platform_driver_probe(&orion_spi_driver, orion_spi_probe); 559} 560module_init(orion_spi_init); 561 562static void __exit orion_spi_exit(void) 563{ 564 flush_workqueue(orion_spi_wq); 565 platform_driver_unregister(&orion_spi_driver); 566 567 destroy_workqueue(orion_spi_wq); 568} 569module_exit(orion_spi_exit); 570 571MODULE_DESCRIPTION("Orion SPI driver"); 572MODULE_AUTHOR("Shadi Ammouri <shadi@marvell.com>"); 573MODULE_LICENSE("GPL");