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 v3.9-rc1 736 lines 17 kB view raw
1/* 2 * Copyright (c) 2006 Ben Dooks 3 * Copyright 2006-2009 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10*/ 11 12#include <linux/init.h> 13#include <linux/spinlock.h> 14#include <linux/workqueue.h> 15#include <linux/interrupt.h> 16#include <linux/delay.h> 17#include <linux/errno.h> 18#include <linux/err.h> 19#include <linux/clk.h> 20#include <linux/platform_device.h> 21#include <linux/gpio.h> 22#include <linux/io.h> 23#include <linux/slab.h> 24 25#include <linux/spi/spi.h> 26#include <linux/spi/spi_bitbang.h> 27#include <linux/spi/s3c24xx.h> 28#include <linux/module.h> 29 30#include <plat/regs-spi.h> 31 32#include <plat/fiq.h> 33#include <asm/fiq.h> 34 35#include "spi-s3c24xx-fiq.h" 36 37/** 38 * s3c24xx_spi_devstate - per device data 39 * @hz: Last frequency calculated for @sppre field. 40 * @mode: Last mode setting for the @spcon field. 41 * @spcon: Value to write to the SPCON register. 42 * @sppre: Value to write to the SPPRE register. 43 */ 44struct s3c24xx_spi_devstate { 45 unsigned int hz; 46 unsigned int mode; 47 u8 spcon; 48 u8 sppre; 49}; 50 51enum spi_fiq_mode { 52 FIQ_MODE_NONE = 0, 53 FIQ_MODE_TX = 1, 54 FIQ_MODE_RX = 2, 55 FIQ_MODE_TXRX = 3, 56}; 57 58struct s3c24xx_spi { 59 /* bitbang has to be first */ 60 struct spi_bitbang bitbang; 61 struct completion done; 62 63 void __iomem *regs; 64 int irq; 65 int len; 66 int count; 67 68 struct fiq_handler fiq_handler; 69 enum spi_fiq_mode fiq_mode; 70 unsigned char fiq_inuse; 71 unsigned char fiq_claimed; 72 73 void (*set_cs)(struct s3c2410_spi_info *spi, 74 int cs, int pol); 75 76 /* data buffers */ 77 const unsigned char *tx; 78 unsigned char *rx; 79 80 struct clk *clk; 81 struct resource *ioarea; 82 struct spi_master *master; 83 struct spi_device *curdev; 84 struct device *dev; 85 struct s3c2410_spi_info *pdata; 86}; 87 88 89#define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) 90#define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) 91 92static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) 93{ 94 return spi_master_get_devdata(sdev->master); 95} 96 97static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) 98{ 99 gpio_set_value(spi->pin_cs, pol); 100} 101 102static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) 103{ 104 struct s3c24xx_spi_devstate *cs = spi->controller_state; 105 struct s3c24xx_spi *hw = to_hw(spi); 106 unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; 107 108 /* change the chipselect state and the state of the spi engine clock */ 109 110 switch (value) { 111 case BITBANG_CS_INACTIVE: 112 hw->set_cs(hw->pdata, spi->chip_select, cspol^1); 113 writeb(cs->spcon, hw->regs + S3C2410_SPCON); 114 break; 115 116 case BITBANG_CS_ACTIVE: 117 writeb(cs->spcon | S3C2410_SPCON_ENSCK, 118 hw->regs + S3C2410_SPCON); 119 hw->set_cs(hw->pdata, spi->chip_select, cspol); 120 break; 121 } 122} 123 124static int s3c24xx_spi_update_state(struct spi_device *spi, 125 struct spi_transfer *t) 126{ 127 struct s3c24xx_spi *hw = to_hw(spi); 128 struct s3c24xx_spi_devstate *cs = spi->controller_state; 129 unsigned int bpw; 130 unsigned int hz; 131 unsigned int div; 132 unsigned long clk; 133 134 bpw = t ? t->bits_per_word : spi->bits_per_word; 135 hz = t ? t->speed_hz : spi->max_speed_hz; 136 137 if (!bpw) 138 bpw = 8; 139 140 if (!hz) 141 hz = spi->max_speed_hz; 142 143 if (bpw != 8) { 144 dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); 145 return -EINVAL; 146 } 147 148 if (spi->mode != cs->mode) { 149 u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK; 150 151 if (spi->mode & SPI_CPHA) 152 spcon |= S3C2410_SPCON_CPHA_FMTB; 153 154 if (spi->mode & SPI_CPOL) 155 spcon |= S3C2410_SPCON_CPOL_HIGH; 156 157 cs->mode = spi->mode; 158 cs->spcon = spcon; 159 } 160 161 if (cs->hz != hz) { 162 clk = clk_get_rate(hw->clk); 163 div = DIV_ROUND_UP(clk, hz * 2) - 1; 164 165 if (div > 255) 166 div = 255; 167 168 dev_dbg(&spi->dev, "pre-scaler=%d (wanted %d, got %ld)\n", 169 div, hz, clk / (2 * (div + 1))); 170 171 cs->hz = hz; 172 cs->sppre = div; 173 } 174 175 return 0; 176} 177 178static int s3c24xx_spi_setupxfer(struct spi_device *spi, 179 struct spi_transfer *t) 180{ 181 struct s3c24xx_spi_devstate *cs = spi->controller_state; 182 struct s3c24xx_spi *hw = to_hw(spi); 183 int ret; 184 185 ret = s3c24xx_spi_update_state(spi, t); 186 if (!ret) 187 writeb(cs->sppre, hw->regs + S3C2410_SPPRE); 188 189 return ret; 190} 191 192static int s3c24xx_spi_setup(struct spi_device *spi) 193{ 194 struct s3c24xx_spi_devstate *cs = spi->controller_state; 195 struct s3c24xx_spi *hw = to_hw(spi); 196 int ret; 197 198 /* allocate settings on the first call */ 199 if (!cs) { 200 cs = kzalloc(sizeof(struct s3c24xx_spi_devstate), GFP_KERNEL); 201 if (!cs) { 202 dev_err(&spi->dev, "no memory for controller state\n"); 203 return -ENOMEM; 204 } 205 206 cs->spcon = SPCON_DEFAULT; 207 cs->hz = -1; 208 spi->controller_state = cs; 209 } 210 211 /* initialise the state from the device */ 212 ret = s3c24xx_spi_update_state(spi, NULL); 213 if (ret) 214 return ret; 215 216 spin_lock(&hw->bitbang.lock); 217 if (!hw->bitbang.busy) { 218 hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); 219 /* need to ndelay for 0.5 clocktick ? */ 220 } 221 spin_unlock(&hw->bitbang.lock); 222 223 return 0; 224} 225 226static void s3c24xx_spi_cleanup(struct spi_device *spi) 227{ 228 kfree(spi->controller_state); 229} 230 231static inline unsigned int hw_txbyte(struct s3c24xx_spi *hw, int count) 232{ 233 return hw->tx ? hw->tx[count] : 0; 234} 235 236#ifdef CONFIG_SPI_S3C24XX_FIQ 237/* Support for FIQ based pseudo-DMA to improve the transfer speed. 238 * 239 * This code uses the assembly helper in spi_s3c24xx_spi.S which is 240 * used by the FIQ core to move data between main memory and the peripheral 241 * block. Since this is code running on the processor, there is no problem 242 * with cache coherency of the buffers, so we can use any buffer we like. 243 */ 244 245/** 246 * struct spi_fiq_code - FIQ code and header 247 * @length: The length of the code fragment, excluding this header. 248 * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at. 249 * @data: The code itself to install as a FIQ handler. 250 */ 251struct spi_fiq_code { 252 u32 length; 253 u32 ack_offset; 254 u8 data[0]; 255}; 256 257extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; 258extern struct spi_fiq_code s3c24xx_spi_fiq_tx; 259extern struct spi_fiq_code s3c24xx_spi_fiq_rx; 260 261/** 262 * ack_bit - turn IRQ into IRQ acknowledgement bit 263 * @irq: The interrupt number 264 * 265 * Returns the bit to write to the interrupt acknowledge register. 266 */ 267static inline u32 ack_bit(unsigned int irq) 268{ 269 return 1 << (irq - IRQ_EINT0); 270} 271 272/** 273 * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer 274 * @hw: The hardware state. 275 * 276 * Claim the FIQ handler (only one can be active at any one time) and 277 * then setup the correct transfer code for this transfer. 278 * 279 * This call updates all the necessary state information if successful, 280 * so the caller does not need to do anything more than start the transfer 281 * as normal, since the IRQ will have been re-routed to the FIQ handler. 282*/ 283void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) 284{ 285 struct pt_regs regs; 286 enum spi_fiq_mode mode; 287 struct spi_fiq_code *code; 288 int ret; 289 290 if (!hw->fiq_claimed) { 291 /* try and claim fiq if we haven't got it, and if not 292 * then return and simply use another transfer method */ 293 294 ret = claim_fiq(&hw->fiq_handler); 295 if (ret) 296 return; 297 } 298 299 if (hw->tx && !hw->rx) 300 mode = FIQ_MODE_TX; 301 else if (hw->rx && !hw->tx) 302 mode = FIQ_MODE_RX; 303 else 304 mode = FIQ_MODE_TXRX; 305 306 regs.uregs[fiq_rspi] = (long)hw->regs; 307 regs.uregs[fiq_rrx] = (long)hw->rx; 308 regs.uregs[fiq_rtx] = (long)hw->tx + 1; 309 regs.uregs[fiq_rcount] = hw->len - 1; 310 regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ; 311 312 set_fiq_regs(&regs); 313 314 if (hw->fiq_mode != mode) { 315 u32 *ack_ptr; 316 317 hw->fiq_mode = mode; 318 319 switch (mode) { 320 case FIQ_MODE_TX: 321 code = &s3c24xx_spi_fiq_tx; 322 break; 323 case FIQ_MODE_RX: 324 code = &s3c24xx_spi_fiq_rx; 325 break; 326 case FIQ_MODE_TXRX: 327 code = &s3c24xx_spi_fiq_txrx; 328 break; 329 default: 330 code = NULL; 331 } 332 333 BUG_ON(!code); 334 335 ack_ptr = (u32 *)&code->data[code->ack_offset]; 336 *ack_ptr = ack_bit(hw->irq); 337 338 set_fiq_handler(&code->data, code->length); 339 } 340 341 s3c24xx_set_fiq(hw->irq, true); 342 343 hw->fiq_mode = mode; 344 hw->fiq_inuse = 1; 345} 346 347/** 348 * s3c24xx_spi_fiqop - FIQ core code callback 349 * @pw: Data registered with the handler 350 * @release: Whether this is a release or a return. 351 * 352 * Called by the FIQ code when another module wants to use the FIQ, so 353 * return whether we are currently using this or not and then update our 354 * internal state. 355 */ 356static int s3c24xx_spi_fiqop(void *pw, int release) 357{ 358 struct s3c24xx_spi *hw = pw; 359 int ret = 0; 360 361 if (release) { 362 if (hw->fiq_inuse) 363 ret = -EBUSY; 364 365 /* note, we do not need to unroute the FIQ, as the FIQ 366 * vector code de-routes it to signal the end of transfer */ 367 368 hw->fiq_mode = FIQ_MODE_NONE; 369 hw->fiq_claimed = 0; 370 } else { 371 hw->fiq_claimed = 1; 372 } 373 374 return ret; 375} 376 377/** 378 * s3c24xx_spi_initfiq - setup the information for the FIQ core 379 * @hw: The hardware state. 380 * 381 * Setup the fiq_handler block to pass to the FIQ core. 382 */ 383static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw) 384{ 385 hw->fiq_handler.dev_id = hw; 386 hw->fiq_handler.name = dev_name(hw->dev); 387 hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop; 388} 389 390/** 391 * s3c24xx_spi_usefiq - return if we should be using FIQ. 392 * @hw: The hardware state. 393 * 394 * Return true if the platform data specifies whether this channel is 395 * allowed to use the FIQ. 396 */ 397static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw) 398{ 399 return hw->pdata->use_fiq; 400} 401 402/** 403 * s3c24xx_spi_usingfiq - return if channel is using FIQ 404 * @spi: The hardware state. 405 * 406 * Return whether the channel is currently using the FIQ (separate from 407 * whether the FIQ is claimed). 408 */ 409static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi) 410{ 411 return spi->fiq_inuse; 412} 413#else 414 415static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { } 416static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { } 417static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; } 418static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; } 419 420#endif /* CONFIG_SPI_S3C24XX_FIQ */ 421 422static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) 423{ 424 struct s3c24xx_spi *hw = to_hw(spi); 425 426 hw->tx = t->tx_buf; 427 hw->rx = t->rx_buf; 428 hw->len = t->len; 429 hw->count = 0; 430 431 init_completion(&hw->done); 432 433 hw->fiq_inuse = 0; 434 if (s3c24xx_spi_usefiq(hw) && t->len >= 3) 435 s3c24xx_spi_tryfiq(hw); 436 437 /* send the first byte */ 438 writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); 439 440 wait_for_completion(&hw->done); 441 return hw->count; 442} 443 444static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) 445{ 446 struct s3c24xx_spi *hw = dev; 447 unsigned int spsta = readb(hw->regs + S3C2410_SPSTA); 448 unsigned int count = hw->count; 449 450 if (spsta & S3C2410_SPSTA_DCOL) { 451 dev_dbg(hw->dev, "data-collision\n"); 452 complete(&hw->done); 453 goto irq_done; 454 } 455 456 if (!(spsta & S3C2410_SPSTA_READY)) { 457 dev_dbg(hw->dev, "spi not ready for tx?\n"); 458 complete(&hw->done); 459 goto irq_done; 460 } 461 462 if (!s3c24xx_spi_usingfiq(hw)) { 463 hw->count++; 464 465 if (hw->rx) 466 hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); 467 468 count++; 469 470 if (count < hw->len) 471 writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); 472 else 473 complete(&hw->done); 474 } else { 475 hw->count = hw->len; 476 hw->fiq_inuse = 0; 477 478 if (hw->rx) 479 hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT); 480 481 complete(&hw->done); 482 } 483 484 irq_done: 485 return IRQ_HANDLED; 486} 487 488static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) 489{ 490 /* for the moment, permanently enable the clock */ 491 492 clk_enable(hw->clk); 493 494 /* program defaults into the registers */ 495 496 writeb(0xff, hw->regs + S3C2410_SPPRE); 497 writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); 498 writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); 499 500 if (hw->pdata) { 501 if (hw->set_cs == s3c24xx_spi_gpiocs) 502 gpio_direction_output(hw->pdata->pin_cs, 1); 503 504 if (hw->pdata->gpio_setup) 505 hw->pdata->gpio_setup(hw->pdata, 1); 506 } 507} 508 509static int s3c24xx_spi_probe(struct platform_device *pdev) 510{ 511 struct s3c2410_spi_info *pdata; 512 struct s3c24xx_spi *hw; 513 struct spi_master *master; 514 struct resource *res; 515 int err = 0; 516 517 master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); 518 if (master == NULL) { 519 dev_err(&pdev->dev, "No memory for spi_master\n"); 520 err = -ENOMEM; 521 goto err_nomem; 522 } 523 524 hw = spi_master_get_devdata(master); 525 memset(hw, 0, sizeof(struct s3c24xx_spi)); 526 527 hw->master = spi_master_get(master); 528 hw->pdata = pdata = pdev->dev.platform_data; 529 hw->dev = &pdev->dev; 530 531 if (pdata == NULL) { 532 dev_err(&pdev->dev, "No platform data supplied\n"); 533 err = -ENOENT; 534 goto err_no_pdata; 535 } 536 537 platform_set_drvdata(pdev, hw); 538 init_completion(&hw->done); 539 540 /* initialise fiq handler */ 541 542 s3c24xx_spi_initfiq(hw); 543 544 /* setup the master state. */ 545 546 /* the spi->mode bits understood by this driver: */ 547 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 548 549 master->num_chipselect = hw->pdata->num_cs; 550 master->bus_num = pdata->bus_num; 551 552 /* setup the state for the bitbang driver */ 553 554 hw->bitbang.master = hw->master; 555 hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; 556 hw->bitbang.chipselect = s3c24xx_spi_chipsel; 557 hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; 558 559 hw->master->setup = s3c24xx_spi_setup; 560 hw->master->cleanup = s3c24xx_spi_cleanup; 561 562 dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); 563 564 /* find and map our resources */ 565 566 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 567 if (res == NULL) { 568 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); 569 err = -ENOENT; 570 goto err_no_iores; 571 } 572 573 hw->ioarea = request_mem_region(res->start, resource_size(res), 574 pdev->name); 575 576 if (hw->ioarea == NULL) { 577 dev_err(&pdev->dev, "Cannot reserve region\n"); 578 err = -ENXIO; 579 goto err_no_iores; 580 } 581 582 hw->regs = ioremap(res->start, resource_size(res)); 583 if (hw->regs == NULL) { 584 dev_err(&pdev->dev, "Cannot map IO\n"); 585 err = -ENXIO; 586 goto err_no_iomap; 587 } 588 589 hw->irq = platform_get_irq(pdev, 0); 590 if (hw->irq < 0) { 591 dev_err(&pdev->dev, "No IRQ specified\n"); 592 err = -ENOENT; 593 goto err_no_irq; 594 } 595 596 err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); 597 if (err) { 598 dev_err(&pdev->dev, "Cannot claim IRQ\n"); 599 goto err_no_irq; 600 } 601 602 hw->clk = clk_get(&pdev->dev, "spi"); 603 if (IS_ERR(hw->clk)) { 604 dev_err(&pdev->dev, "No clock for device\n"); 605 err = PTR_ERR(hw->clk); 606 goto err_no_clk; 607 } 608 609 /* setup any gpio we can */ 610 611 if (!pdata->set_cs) { 612 if (pdata->pin_cs < 0) { 613 dev_err(&pdev->dev, "No chipselect pin\n"); 614 err = -EINVAL; 615 goto err_register; 616 } 617 618 err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); 619 if (err) { 620 dev_err(&pdev->dev, "Failed to get gpio for cs\n"); 621 goto err_register; 622 } 623 624 hw->set_cs = s3c24xx_spi_gpiocs; 625 gpio_direction_output(pdata->pin_cs, 1); 626 } else 627 hw->set_cs = pdata->set_cs; 628 629 s3c24xx_spi_initialsetup(hw); 630 631 /* register our spi controller */ 632 633 err = spi_bitbang_start(&hw->bitbang); 634 if (err) { 635 dev_err(&pdev->dev, "Failed to register SPI master\n"); 636 goto err_register; 637 } 638 639 return 0; 640 641 err_register: 642 if (hw->set_cs == s3c24xx_spi_gpiocs) 643 gpio_free(pdata->pin_cs); 644 645 clk_disable(hw->clk); 646 clk_put(hw->clk); 647 648 err_no_clk: 649 free_irq(hw->irq, hw); 650 651 err_no_irq: 652 iounmap(hw->regs); 653 654 err_no_iomap: 655 release_resource(hw->ioarea); 656 kfree(hw->ioarea); 657 658 err_no_iores: 659 err_no_pdata: 660 spi_master_put(hw->master); 661 662 err_nomem: 663 return err; 664} 665 666static int s3c24xx_spi_remove(struct platform_device *dev) 667{ 668 struct s3c24xx_spi *hw = platform_get_drvdata(dev); 669 670 platform_set_drvdata(dev, NULL); 671 672 spi_bitbang_stop(&hw->bitbang); 673 674 clk_disable(hw->clk); 675 clk_put(hw->clk); 676 677 free_irq(hw->irq, hw); 678 iounmap(hw->regs); 679 680 if (hw->set_cs == s3c24xx_spi_gpiocs) 681 gpio_free(hw->pdata->pin_cs); 682 683 release_resource(hw->ioarea); 684 kfree(hw->ioarea); 685 686 spi_master_put(hw->master); 687 return 0; 688} 689 690 691#ifdef CONFIG_PM 692 693static int s3c24xx_spi_suspend(struct device *dev) 694{ 695 struct s3c24xx_spi *hw = platform_get_drvdata(to_platform_device(dev)); 696 697 if (hw->pdata && hw->pdata->gpio_setup) 698 hw->pdata->gpio_setup(hw->pdata, 0); 699 700 clk_disable(hw->clk); 701 return 0; 702} 703 704static int s3c24xx_spi_resume(struct device *dev) 705{ 706 struct s3c24xx_spi *hw = platform_get_drvdata(to_platform_device(dev)); 707 708 s3c24xx_spi_initialsetup(hw); 709 return 0; 710} 711 712static const struct dev_pm_ops s3c24xx_spi_pmops = { 713 .suspend = s3c24xx_spi_suspend, 714 .resume = s3c24xx_spi_resume, 715}; 716 717#define S3C24XX_SPI_PMOPS &s3c24xx_spi_pmops 718#else 719#define S3C24XX_SPI_PMOPS NULL 720#endif /* CONFIG_PM */ 721 722MODULE_ALIAS("platform:s3c2410-spi"); 723static struct platform_driver s3c24xx_spi_driver = { 724 .probe = s3c24xx_spi_probe, 725 .remove = s3c24xx_spi_remove, 726 .driver = { 727 .name = "s3c2410-spi", 728 .owner = THIS_MODULE, 729 .pm = S3C24XX_SPI_PMOPS, 730 }, 731}; 732module_platform_driver(s3c24xx_spi_driver); 733 734MODULE_DESCRIPTION("S3C24XX SPI Driver"); 735MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 736MODULE_LICENSE("GPL");