Loading arch/arm/mach-sa1100/include/mach/mcp.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ struct mcp_plat_data { u32 mccr0; u32 mccr0; u32 mccr1; u32 mccr1; unsigned int sclk_rate; unsigned int sclk_rate; int gpio_base; }; }; #endif #endif drivers/mfd/mcp-sa11x0.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; mcp->gpio_base = data->gpio_base; platform_set_drvdata(pdev, mcp); platform_set_drvdata(pdev, mcp); Loading drivers/mfd/ucb1x00-core.c +85 −2 Original line number Original line Diff line number Diff line Loading @@ -26,11 +26,11 @@ #include <linux/device.h> #include <linux/device.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/mfd/ucb1x00.h> #include <linux/mfd/ucb1x00.h> #include <linux/gpio.h> #include <mach/dma.h> #include <mach/dma.h> #include <mach/hardware.h> #include <mach/hardware.h> static DEFINE_MUTEX(ucb1x00_mutex); static DEFINE_MUTEX(ucb1x00_mutex); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); static LIST_HEAD(ucb1x00_devices); Loading Loading @@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) return ucb1x00_reg_read(ucb, UCB_IO_DATA); return ucb1x00_reg_read(ucb, UCB_IO_DATA); } } static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); if (value) ucb->io_out |= 1 << offset; else ucb->io_out &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); } static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset); } static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); ucb->io_dir &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; } static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset , int value) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); ucb->io_dir |= (1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); if (value) ucb->io_out |= 1 << offset; else ucb->io_out &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; } /* /* * UCB1300 data sheet says we must: * UCB1300 data sheet says we must: * 1. enable ADC => 5us (including reference startup time) * 1. enable ADC => 5us (including reference startup time) Loading Loading @@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp) struct ucb1x00_driver *drv; struct ucb1x00_driver *drv; unsigned int id; unsigned int id; int ret = -ENODEV; int ret = -ENODEV; int temp; mcp_enable(mcp); mcp_enable(mcp); id = mcp_reg_read(mcp, UCB_ID); id = mcp_reg_read(mcp, UCB_ID); Loading Loading @@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp) goto err_free; goto err_free; } } ucb->gpio.base = -1; if (mcp->gpio_base != 0) { ucb->gpio.label = dev_name(&ucb->dev); ucb->gpio.base = mcp->gpio_base; ucb->gpio.ngpio = 10; ucb->gpio.set = ucb1x00_gpio_set; ucb->gpio.get = ucb1x00_gpio_get; ucb->gpio.direction_input = ucb1x00_gpio_direction_input; ucb->gpio.direction_output = ucb1x00_gpio_direction_output; ret = gpiochip_add(&ucb->gpio); if (ret) goto err_free; } else dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, "UCB1x00", ucb); "UCB1x00", ucb); if (ret) { if (ret) { printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", ucb->irq, ret); ucb->irq, ret); goto err_free; goto err_gpio; } } mcp_set_drvdata(mcp, ucb); mcp_set_drvdata(mcp, ucb); Loading @@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp) if (ret) if (ret) goto err_irq; goto err_irq; INIT_LIST_HEAD(&ucb->devs); INIT_LIST_HEAD(&ucb->devs); mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_add(&ucb->node, &ucb1x00_devices); list_add(&ucb->node, &ucb1x00_devices); Loading @@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp) ucb1x00_add_dev(ucb, drv); ucb1x00_add_dev(ucb, drv); } } mutex_unlock(&ucb1x00_mutex); mutex_unlock(&ucb1x00_mutex); goto out; goto out; err_irq: err_irq: free_irq(ucb->irq, ucb); free_irq(ucb->irq, ucb); err_gpio: if (ucb->gpio.base != -1) temp = gpiochip_remove(&ucb->gpio); err_free: err_free: kfree(ucb); kfree(ucb); err_disable: err_disable: Loading @@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp) { { struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct list_head *l, *n; struct list_head *l, *n; int ret; mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_del(&ucb->node); list_del(&ucb->node); Loading @@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp) } } mutex_unlock(&ucb1x00_mutex); mutex_unlock(&ucb1x00_mutex); if (ucb->gpio.base != -1) { ret = gpiochip_remove(&ucb->gpio); if (ret) dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); } free_irq(ucb->irq, ucb); free_irq(ucb->irq, ucb); device_unregister(&ucb->dev); device_unregister(&ucb->dev); } } Loading Loading @@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; struct ucb1x00_dev *dev; ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_for_each_entry(dev, &ucb->devs, dev_node) { list_for_each_entry(dev, &ucb->devs, dev_node) { if (dev->drv->resume) if (dev->drv->resume) Loading include/linux/mfd/mcp.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ struct mcp { dma_device_t dma_telco_rd; dma_device_t dma_telco_rd; dma_device_t dma_telco_wr; dma_device_t dma_telco_wr; struct device attached_device; struct device attached_device; int gpio_base; }; }; struct mcp_ops { struct mcp_ops { Loading include/linux/mfd/ucb1x00.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,8 @@ #define UCB1200_H #define UCB1200_H #include <linux/mfd/mcp.h> #include <linux/mfd/mcp.h> #include <linux/gpio.h> #define UCB_IO_DATA 0x00 #define UCB_IO_DATA 0x00 #define UCB_IO_DIR 0x01 #define UCB_IO_DIR 0x01 Loading Loading @@ -123,6 +125,7 @@ struct ucb1x00 { struct device dev; struct device dev; struct list_head node; struct list_head node; struct list_head devs; struct list_head devs; struct gpio_chip gpio; }; }; struct ucb1x00_driver; struct ucb1x00_driver; Loading Loading
arch/arm/mach-sa1100/include/mach/mcp.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ struct mcp_plat_data { u32 mccr0; u32 mccr0; u32 mccr1; u32 mccr1; unsigned int sclk_rate; unsigned int sclk_rate; int gpio_base; }; }; #endif #endif
drivers/mfd/mcp-sa11x0.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_audio_wr = DMA_Ser4MCP0Wr; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_rd = DMA_Ser4MCP1Rd; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; mcp->dma_telco_wr = DMA_Ser4MCP1Wr; mcp->gpio_base = data->gpio_base; platform_set_drvdata(pdev, mcp); platform_set_drvdata(pdev, mcp); Loading
drivers/mfd/ucb1x00-core.c +85 −2 Original line number Original line Diff line number Diff line Loading @@ -26,11 +26,11 @@ #include <linux/device.h> #include <linux/device.h> #include <linux/mutex.h> #include <linux/mutex.h> #include <linux/mfd/ucb1x00.h> #include <linux/mfd/ucb1x00.h> #include <linux/gpio.h> #include <mach/dma.h> #include <mach/dma.h> #include <mach/hardware.h> #include <mach/hardware.h> static DEFINE_MUTEX(ucb1x00_mutex); static DEFINE_MUTEX(ucb1x00_mutex); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_drivers); static LIST_HEAD(ucb1x00_devices); static LIST_HEAD(ucb1x00_devices); Loading Loading @@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb) return ucb1x00_reg_read(ucb, UCB_IO_DATA); return ucb1x00_reg_read(ucb, UCB_IO_DATA); } } static void ucb1x00_gpio_set(struct gpio_chip *chip, unsigned offset, int value) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); if (value) ucb->io_out |= 1 << offset; else ucb->io_out &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); } static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); return ucb1x00_reg_read(ucb, UCB_IO_DATA) & (1 << offset); } static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); ucb->io_dir &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; } static int ucb1x00_gpio_direction_output(struct gpio_chip *chip, unsigned offset , int value) { struct ucb1x00 *ucb = container_of(chip, struct ucb1x00, gpio); unsigned long flags; spin_lock_irqsave(&ucb->io_lock, flags); ucb->io_dir |= (1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); if (value) ucb->io_out |= 1 << offset; else ucb->io_out &= ~(1 << offset); ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out); spin_unlock_irqrestore(&ucb->io_lock, flags); return 0; } /* /* * UCB1300 data sheet says we must: * UCB1300 data sheet says we must: * 1. enable ADC => 5us (including reference startup time) * 1. enable ADC => 5us (including reference startup time) Loading Loading @@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp) struct ucb1x00_driver *drv; struct ucb1x00_driver *drv; unsigned int id; unsigned int id; int ret = -ENODEV; int ret = -ENODEV; int temp; mcp_enable(mcp); mcp_enable(mcp); id = mcp_reg_read(mcp, UCB_ID); id = mcp_reg_read(mcp, UCB_ID); Loading Loading @@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp) goto err_free; goto err_free; } } ucb->gpio.base = -1; if (mcp->gpio_base != 0) { ucb->gpio.label = dev_name(&ucb->dev); ucb->gpio.base = mcp->gpio_base; ucb->gpio.ngpio = 10; ucb->gpio.set = ucb1x00_gpio_set; ucb->gpio.get = ucb1x00_gpio_get; ucb->gpio.direction_input = ucb1x00_gpio_direction_input; ucb->gpio.direction_output = ucb1x00_gpio_direction_output; ret = gpiochip_add(&ucb->gpio); if (ret) goto err_free; } else dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, "UCB1x00", ucb); "UCB1x00", ucb); if (ret) { if (ret) { printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", ucb->irq, ret); ucb->irq, ret); goto err_free; goto err_gpio; } } mcp_set_drvdata(mcp, ucb); mcp_set_drvdata(mcp, ucb); Loading @@ -522,6 +592,7 @@ static int ucb1x00_probe(struct mcp *mcp) if (ret) if (ret) goto err_irq; goto err_irq; INIT_LIST_HEAD(&ucb->devs); INIT_LIST_HEAD(&ucb->devs); mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_add(&ucb->node, &ucb1x00_devices); list_add(&ucb->node, &ucb1x00_devices); Loading @@ -529,10 +600,14 @@ static int ucb1x00_probe(struct mcp *mcp) ucb1x00_add_dev(ucb, drv); ucb1x00_add_dev(ucb, drv); } } mutex_unlock(&ucb1x00_mutex); mutex_unlock(&ucb1x00_mutex); goto out; goto out; err_irq: err_irq: free_irq(ucb->irq, ucb); free_irq(ucb->irq, ucb); err_gpio: if (ucb->gpio.base != -1) temp = gpiochip_remove(&ucb->gpio); err_free: err_free: kfree(ucb); kfree(ucb); err_disable: err_disable: Loading @@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp) { { struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct list_head *l, *n; struct list_head *l, *n; int ret; mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_del(&ucb->node); list_del(&ucb->node); Loading @@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp) } } mutex_unlock(&ucb1x00_mutex); mutex_unlock(&ucb1x00_mutex); if (ucb->gpio.base != -1) { ret = gpiochip_remove(&ucb->gpio); if (ret) dev_err(&ucb->dev, "Can't remove gpio chip: %d\n", ret); } free_irq(ucb->irq, ucb); free_irq(ucb->irq, ucb); device_unregister(&ucb->dev); device_unregister(&ucb->dev); } } Loading Loading @@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp) struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00 *ucb = mcp_get_drvdata(mcp); struct ucb1x00_dev *dev; struct ucb1x00_dev *dev; ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir); mutex_lock(&ucb1x00_mutex); mutex_lock(&ucb1x00_mutex); list_for_each_entry(dev, &ucb->devs, dev_node) { list_for_each_entry(dev, &ucb->devs, dev_node) { if (dev->drv->resume) if (dev->drv->resume) Loading
include/linux/mfd/mcp.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ struct mcp { dma_device_t dma_telco_rd; dma_device_t dma_telco_rd; dma_device_t dma_telco_wr; dma_device_t dma_telco_wr; struct device attached_device; struct device attached_device; int gpio_base; }; }; struct mcp_ops { struct mcp_ops { Loading
include/linux/mfd/ucb1x00.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -11,6 +11,8 @@ #define UCB1200_H #define UCB1200_H #include <linux/mfd/mcp.h> #include <linux/mfd/mcp.h> #include <linux/gpio.h> #define UCB_IO_DATA 0x00 #define UCB_IO_DATA 0x00 #define UCB_IO_DIR 0x01 #define UCB_IO_DIR 0x01 Loading Loading @@ -123,6 +125,7 @@ struct ucb1x00 { struct device dev; struct device dev; struct list_head node; struct list_head node; struct list_head devs; struct list_head devs; struct gpio_chip gpio; }; }; struct ucb1x00_driver; struct ucb1x00_driver; Loading