summaryrefslogtreecommitdiffstats
path: root/drivers/atm/solos-pci.c
diff options
context:
space:
mode:
authorNathan Williams <nathan@traverse.com.au>2012-12-19 06:01:18 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-19 17:53:53 -0500
commitf9baad02e7411d9f38d5ebe1a1cdcde4ceec100d (patch)
tree298ecb3ed8aa77d1b7fb9b1a5677d675abb60fa9 /drivers/atm/solos-pci.c
parent83c34fd00d0c3989466e95808bf12af9bf87e383 (diff)
solos-pci: add GPIO support for newer versions on Geos board
dwmw2: Tidy up a little, simpler matching on which GPIO is being accessed, only register on newer boards, register under PCI device instead of duplicating them under each ATM device. Signed-off-by: Nathan Williams <nathan@traverse.com.au> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r--drivers/atm/solos-pci.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index c909b7b7d5f1..473d80878ec9 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -56,6 +56,7 @@
56#define FLASH_BUSY 0x60 56#define FLASH_BUSY 0x60
57#define FPGA_MODE 0x5C 57#define FPGA_MODE 0x5C
58#define FLASH_MODE 0x58 58#define FLASH_MODE 0x58
59#define GPIO_STATUS 0x54
59#define TX_DMA_ADDR(port) (0x40 + (4 * (port))) 60#define TX_DMA_ADDR(port) (0x40 + (4 * (port)))
60#define RX_DMA_ADDR(port) (0x30 + (4 * (port))) 61#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
61 62
@@ -498,6 +499,78 @@ static ssize_t console_store(struct device *dev, struct device_attribute *attr,
498 return err?:count; 499 return err?:count;
499} 500}
500 501
502struct geos_gpio_attr {
503 struct device_attribute attr;
504 int offset;
505};
506
507#define SOLOS_GPIO_ATTR(_name, _mode, _show, _store, _offset) \
508 struct geos_gpio_attr gpio_attr_##_name = { \
509 .attr = __ATTR(_name, _mode, _show, _store), \
510 .offset = _offset }
511
512static ssize_t geos_gpio_store(struct device *dev, struct device_attribute *attr,
513 const char *buf, size_t count)
514{
515 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
516 struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
517 struct solos_card *card = pci_get_drvdata(pdev);
518 uint32_t data32;
519
520 if (count != 1 && (count != 2 || buf[1] != '\n'))
521 return -EINVAL;
522
523 spin_lock_irq(&card->param_queue_lock);
524 data32 = ioread32(card->config_regs + GPIO_STATUS);
525 if (buf[0] == '1') {
526 data32 |= 1 << gattr->offset;
527 iowrite32(data32, card->config_regs + GPIO_STATUS);
528 } else if (buf[0] == '0') {
529 data32 &= ~(1 << gattr->offset);
530 iowrite32(data32, card->config_regs + GPIO_STATUS);
531 } else {
532 count = -EINVAL;
533 }
534 spin_lock_irq(&card->param_queue_lock);
535 return count;
536}
537
538static ssize_t geos_gpio_show(struct device *dev, struct device_attribute *attr,
539 char *buf)
540{
541 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
542 struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
543 struct solos_card *card = pci_get_drvdata(pdev);
544 uint32_t data32;
545
546 data32 = ioread32(card->config_regs + GPIO_STATUS);
547 data32 = (data32 >> gattr->offset) & 1;
548
549 return sprintf(buf, "%d\n", data32);
550}
551
552static ssize_t hardware_show(struct device *dev, struct device_attribute *attr,
553 char *buf)
554{
555 struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
556 struct geos_gpio_attr *gattr = container_of(attr, struct geos_gpio_attr, attr);
557 struct solos_card *card = pci_get_drvdata(pdev);
558 uint32_t data32;
559
560 data32 = ioread32(card->config_regs + GPIO_STATUS);
561 switch (gattr->offset) {
562 case 0:
563 /* HardwareVersion */
564 data32 = data32 & 0x1F;
565 break;
566 case 1:
567 /* HardwareVariant */
568 data32 = (data32 >> 5) & 0x0F;
569 break;
570 }
571 return sprintf(buf, "%d\n", data32);
572}
573
501static DEVICE_ATTR(console, 0644, console_show, console_store); 574static DEVICE_ATTR(console, 0644, console_show, console_store);
502 575
503 576
@@ -506,6 +579,14 @@ static DEVICE_ATTR(console, 0644, console_show, console_store);
506 579
507#include "solos-attrlist.c" 580#include "solos-attrlist.c"
508 581
582static SOLOS_GPIO_ATTR(GPIO1, 0644, geos_gpio_show, geos_gpio_store, 9);
583static SOLOS_GPIO_ATTR(GPIO2, 0644, geos_gpio_show, geos_gpio_store, 10);
584static SOLOS_GPIO_ATTR(GPIO3, 0644, geos_gpio_show, geos_gpio_store, 11);
585static SOLOS_GPIO_ATTR(GPIO4, 0644, geos_gpio_show, geos_gpio_store, 12);
586static SOLOS_GPIO_ATTR(GPIO5, 0644, geos_gpio_show, geos_gpio_store, 13);
587static SOLOS_GPIO_ATTR(PushButton, 0444, geos_gpio_show, NULL, 14);
588static SOLOS_GPIO_ATTR(HardwareVersion, 0444, hardware_show, NULL, 0);
589static SOLOS_GPIO_ATTR(HardwareVariant, 0444, hardware_show, NULL, 1);
509#undef SOLOS_ATTR_RO 590#undef SOLOS_ATTR_RO
510#undef SOLOS_ATTR_RW 591#undef SOLOS_ATTR_RW
511 592
@@ -522,6 +603,23 @@ static struct attribute_group solos_attr_group = {
522 .name = "parameters", 603 .name = "parameters",
523}; 604};
524 605
606static struct attribute *gpio_attrs[] = {
607 &gpio_attr_GPIO1.attr.attr,
608 &gpio_attr_GPIO2.attr.attr,
609 &gpio_attr_GPIO3.attr.attr,
610 &gpio_attr_GPIO4.attr.attr,
611 &gpio_attr_GPIO5.attr.attr,
612 &gpio_attr_PushButton.attr.attr,
613 &gpio_attr_HardwareVersion.attr.attr,
614 &gpio_attr_HardwareVariant.attr.attr,
615 NULL
616};
617
618static struct attribute_group gpio_attr_group = {
619 .attrs = gpio_attrs,
620 .name = "gpio",
621};
622
525static int flash_upgrade(struct solos_card *card, int chip) 623static int flash_upgrade(struct solos_card *card, int chip)
526{ 624{
527 const struct firmware *fw; 625 const struct firmware *fw;
@@ -1179,6 +1277,10 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
1179 if (err) 1277 if (err)
1180 goto out_free_irq; 1278 goto out_free_irq;
1181 1279
1280 if (card->fpga_version >= DMA_SUPPORTED &&
1281 sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
1282 dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
1283
1182 return 0; 1284 return 0;
1183 1285
1184 out_free_irq: 1286 out_free_irq:
@@ -1289,6 +1391,9 @@ static void fpga_remove(struct pci_dev *dev)
1289 iowrite32(1, card->config_regs + FPGA_MODE); 1391 iowrite32(1, card->config_regs + FPGA_MODE);
1290 (void)ioread32(card->config_regs + FPGA_MODE); 1392 (void)ioread32(card->config_regs + FPGA_MODE);
1291 1393
1394 if (card->fpga_version >= DMA_SUPPORTED)
1395 sysfs_remove_group(&card->dev->dev.kobj, &gpio_attr_group);
1396
1292 atm_remove(card); 1397 atm_remove(card);
1293 1398
1294 free_irq(dev->irq, card); 1399 free_irq(dev->irq, card);