Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 172657
b: refs/heads/master
c: 9ca3dc8
h: refs/heads/master
i:
  172655: 92645ea
v: v3
  • Loading branch information
Thomas Kunze authored and Thomas Kunze committed Nov 27, 2009
1 parent 946c625 commit 4784a81
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cc647172795713e013f8de4bcdf91860e9e87bff
refs/heads/master: 9ca3dc805cd0d89c44f88b9a399061946781323a
1 change: 1 addition & 0 deletions trunk/arch/arm/mach-sa1100/include/mach/mcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct mcp_plat_data {
u32 mccr0;
u32 mccr1;
unsigned int sclk_rate;
int gpio_base;
};

#endif
1 change: 1 addition & 0 deletions trunk/drivers/mfd/mcp-sa11x0.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
mcp->gpio_base = data->gpio_base;

platform_set_drvdata(pdev, mcp);

Expand Down
87 changes: 85 additions & 2 deletions trunk/drivers/mfd/ucb1x00-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/mfd/ucb1x00.h>
#include <linux/gpio.h>

#include <mach/dma.h>
#include <mach/hardware.h>


static DEFINE_MUTEX(ucb1x00_mutex);
static LIST_HEAD(ucb1x00_drivers);
static LIST_HEAD(ucb1x00_devices);
Expand Down Expand Up @@ -108,6 +108,60 @@ unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
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:
* 1. enable ADC => 5us (including reference startup time)
Expand Down Expand Up @@ -476,6 +530,7 @@ static int ucb1x00_probe(struct mcp *mcp)
struct ucb1x00_driver *drv;
unsigned int id;
int ret = -ENODEV;
int temp;

mcp_enable(mcp);
id = mcp_reg_read(mcp, UCB_ID);
Expand Down Expand Up @@ -508,12 +563,27 @@ static int ucb1x00_probe(struct mcp *mcp)
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,
"UCB1x00", ucb);
if (ret) {
printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
ucb->irq, ret);
goto err_free;
goto err_gpio;
}

mcp_set_drvdata(mcp, ucb);
Expand All @@ -522,17 +592,22 @@ static int ucb1x00_probe(struct mcp *mcp)
if (ret)
goto err_irq;


INIT_LIST_HEAD(&ucb->devs);
mutex_lock(&ucb1x00_mutex);
list_add(&ucb->node, &ucb1x00_devices);
list_for_each_entry(drv, &ucb1x00_drivers, node) {
ucb1x00_add_dev(ucb, drv);
}
mutex_unlock(&ucb1x00_mutex);

goto out;

err_irq:
free_irq(ucb->irq, ucb);
err_gpio:
if (ucb->gpio.base != -1)
temp = gpiochip_remove(&ucb->gpio);
err_free:
kfree(ucb);
err_disable:
Expand All @@ -545,6 +620,7 @@ static void ucb1x00_remove(struct mcp *mcp)
{
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct list_head *l, *n;
int ret;

mutex_lock(&ucb1x00_mutex);
list_del(&ucb->node);
Expand All @@ -554,6 +630,12 @@ static void ucb1x00_remove(struct mcp *mcp)
}
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);
device_unregister(&ucb->dev);
}
Expand Down Expand Up @@ -604,6 +686,7 @@ static int ucb1x00_resume(struct mcp *mcp)
struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
struct ucb1x00_dev *dev;

ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
mutex_lock(&ucb1x00_mutex);
list_for_each_entry(dev, &ucb->devs, dev_node) {
if (dev->drv->resume)
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/mfd/mcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct mcp {
dma_device_t dma_telco_rd;
dma_device_t dma_telco_wr;
struct device attached_device;
int gpio_base;
};

struct mcp_ops {
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/mfd/ucb1x00.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#define UCB1200_H

#include <linux/mfd/mcp.h>
#include <linux/gpio.h>

#define UCB_IO_DATA 0x00
#define UCB_IO_DIR 0x01

Expand Down Expand Up @@ -123,6 +125,7 @@ struct ucb1x00 {
struct device dev;
struct list_head node;
struct list_head devs;
struct gpio_chip gpio;
};

struct ucb1x00_driver;
Expand Down

0 comments on commit 4784a81

Please sign in to comment.