Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 311858
b: refs/heads/master
c: ada72d0
h: refs/heads/master
v: v3
  • Loading branch information
Philippe Rétornaz authored and Samuel Ortiz committed Jul 8, 2012
1 parent c163e40 commit a0a0229
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 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: 44716ec2f423da1965d444cd349b14b994998299
refs/heads/master: ada72d0a9308105b535c8fc53ba5b33e9f076a1a
65 changes: 64 additions & 1 deletion trunk/drivers/mfd/mc13xxx-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,67 @@ static struct regmap_config mc13xxx_regmap_spi_config = {
.max_register = MC13XXX_NUMREGS,

.cache_type = REGCACHE_NONE,
.use_single_rw = 1,
};

static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size,
void *val, size_t val_size)
{
unsigned char w[4] = { *((unsigned char *) reg), 0, 0, 0};
unsigned char r[4];
unsigned char *p = val;
struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);
struct spi_transfer t = {
.tx_buf = w,
.rx_buf = r,
.len = 4,
};

struct spi_message m;
int ret;

if (val_size != 3 || reg_size != 1)
return -ENOTSUPP;

spi_message_init(&m);
spi_message_add_tail(&t, &m);
ret = spi_sync(spi, &m);

memcpy(p, &r[1], 3);

return ret;
}

static int mc13xxx_spi_write(void *context, const void *data, size_t count)
{
struct device *dev = context;
struct spi_device *spi = to_spi_device(dev);

if (count != 4)
return -ENOTSUPP;

return spi_write(spi, data, count);
}

/*
* We cannot use regmap-spi generic bus implementation here.
* The MC13783 chip will get corrupted if CS signal is deasserted
* and on i.Mx31 SoC (the target SoC for MC13783 PMIC) the SPI controller
* has the following errata (DSPhl22960):
* "The CSPI negates SS when the FIFO becomes empty with
* SSCTL= 0. Software cannot guarantee that the FIFO will not
* drain because of higher priority interrupts and the
* non-realtime characteristics of the operating system. As a
* result, the SS will negate before all of the data has been
* transferred to/from the peripheral."
* We workaround this by accessing the SPI controller with a
* single transfert.
*/

static struct regmap_bus regmap_mc13xxx_bus = {
.write = mc13xxx_spi_write,
.read = mc13xxx_spi_read,
};

static int mc13xxx_spi_probe(struct spi_device *spi)
Expand All @@ -78,7 +139,9 @@ static int mc13xxx_spi_probe(struct spi_device *spi)
mc13xxx->dev = &spi->dev;
mutex_init(&mc13xxx->lock);

mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config);
mc13xxx->regmap = regmap_init(&spi->dev, &regmap_mc13xxx_bus, &spi->dev,
&mc13xxx_regmap_spi_config);

if (IS_ERR(mc13xxx->regmap)) {
ret = PTR_ERR(mc13xxx->regmap);
dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n",
Expand Down

0 comments on commit a0a0229

Please sign in to comment.