Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c33a004c authored by Linus Walleij's avatar Linus Walleij Committed by Wolfram Sang
Browse files

i2c: nomadik: factor platform data into state container



Move the former platform data struct nmk_i2c_controller into the
per-device state container struct i2c_nmk_client, and remove all
the platform data probe path hacks.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
[wsa: use 100kHz as default]
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent e8936455
Loading
Loading
Loading
Loading
+42 −73
Original line number Original line Diff line number Diff line
@@ -110,22 +110,6 @@ enum i2c_freq_mode {
	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */
	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */
};
};


/**
 * struct nmk_i2c_controller - client specific controller configuration
 * @clk_freq:	clock frequency for the operation mode
 * @tft:	Tx FIFO Threshold in bytes
 * @rft:	Rx FIFO Threshold in bytes
 * @timeout	Slave response timeout(ms)
 * @sm:		speed mode
 */
struct nmk_i2c_controller {
	u32             clk_freq;
	unsigned char	tft;
	unsigned char	rft;
	int timeout;
	enum i2c_freq_mode	sm;
};

/**
/**
 * struct i2c_vendor_data - per-vendor variations
 * struct i2c_vendor_data - per-vendor variations
 * @has_mtdws: variant has the MTDWS bit
 * @has_mtdws: variant has the MTDWS bit
@@ -174,8 +158,12 @@ struct i2c_nmk_client {
 * @irq: interrupt line for the controller.
 * @irq: interrupt line for the controller.
 * @virtbase: virtual io memory area.
 * @virtbase: virtual io memory area.
 * @clk: hardware i2c block clock.
 * @clk: hardware i2c block clock.
 * @cfg: machine provided controller configuration.
 * @cli: holder of client specific data.
 * @cli: holder of client specific data.
 * @clk_freq: clock frequency for the operation mode
 * @tft: Tx FIFO Threshold in bytes
 * @rft: Rx FIFO Threshold in bytes
 * @timeout Slave response timeout (ms)
 * @sm: speed mode
 * @stop: stop condition.
 * @stop: stop condition.
 * @xfer_complete: acknowledge completion for a I2C message.
 * @xfer_complete: acknowledge completion for a I2C message.
 * @result: controller propogated result.
 * @result: controller propogated result.
@@ -188,8 +176,12 @@ struct nmk_i2c_dev {
	int				irq;
	int				irq;
	void __iomem			*virtbase;
	void __iomem			*virtbase;
	struct clk			*clk;
	struct clk			*clk;
	struct nmk_i2c_controller	cfg;
	struct i2c_nmk_client		cli;
	struct i2c_nmk_client		cli;
	u32				clk_freq;
	unsigned char			tft;
	unsigned char			rft;
	int				timeout;
	enum i2c_freq_mode		sm;
	int				stop;
	int				stop;
	struct completion		xfer_complete;
	struct completion		xfer_complete;
	int				result;
	int				result;
@@ -386,7 +378,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
	 * slsu = cycles / (1000000000 / f) + 1
	 * slsu = cycles / (1000000000 / f) + 1
	 */
	 */
	ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk);
	ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk);
	switch (dev->cfg.sm) {
	switch (dev->sm) {
	case I2C_FREQ_MODE_FAST:
	case I2C_FREQ_MODE_FAST:
	case I2C_FREQ_MODE_FAST_PLUS:
	case I2C_FREQ_MODE_FAST_PLUS:
		slsu = DIV_ROUND_UP(100, ns); /* Fast */
		slsu = DIV_ROUND_UP(100, ns); /* Fast */
@@ -409,7 +401,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
	 * 2 whereas it is 3 for fast and fastplus mode of
	 * 2 whereas it is 3 for fast and fastplus mode of
	 * operation. TODO - high speed support.
	 * operation. TODO - high speed support.
	 */
	 */
	div = (dev->cfg.clk_freq > 100000) ? 3 : 2;
	div = (dev->clk_freq > 100000) ? 3 : 2;


	/*
	/*
	 * generate the mask for baud rate counters. The controller
	 * generate the mask for baud rate counters. The controller
@@ -419,7 +411,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
	 * so set brcr1 to 0.
	 * so set brcr1 to 0.
	 */
	 */
	brcr1 = 0 << 16;
	brcr1 = 0 << 16;
	brcr2 = (i2c_clk/(dev->cfg.clk_freq * div)) & 0xffff;
	brcr2 = (i2c_clk/(dev->clk_freq * div)) & 0xffff;


	/* set the baud rate counter register */
	/* set the baud rate counter register */
	writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
	writel((brcr1 | brcr2), dev->virtbase + I2C_BRCR);
@@ -430,7 +422,7 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
	 * TODO - support for fast mode plus (up to 1Mb/s)
	 * TODO - support for fast mode plus (up to 1Mb/s)
	 * and high speed (up to 3.4 Mb/s)
	 * and high speed (up to 3.4 Mb/s)
	 */
	 */
	if (dev->cfg.sm > I2C_FREQ_MODE_FAST) {
	if (dev->sm > I2C_FREQ_MODE_FAST) {
		dev_err(&dev->adev->dev,
		dev_err(&dev->adev->dev,
			"do not support this mode defaulting to std. mode\n");
			"do not support this mode defaulting to std. mode\n");
		brcr2 = i2c_clk/(100000 * 2) & 0xffff;
		brcr2 = i2c_clk/(100000 * 2) & 0xffff;
@@ -438,11 +430,11 @@ static void setup_i2c_controller(struct nmk_i2c_dev *dev)
		writel(I2C_FREQ_MODE_STANDARD << 4,
		writel(I2C_FREQ_MODE_STANDARD << 4,
				dev->virtbase + I2C_CR);
				dev->virtbase + I2C_CR);
	}
	}
	writel(dev->cfg.sm << 4, dev->virtbase + I2C_CR);
	writel(dev->sm << 4, dev->virtbase + I2C_CR);


	/* set the Tx and Rx FIFO threshold */
	/* set the Tx and Rx FIFO threshold */
	writel(dev->cfg.tft, dev->virtbase + I2C_TFTR);
	writel(dev->tft, dev->virtbase + I2C_TFTR);
	writel(dev->cfg.rft, dev->virtbase + I2C_RFTR);
	writel(dev->rft, dev->virtbase + I2C_RFTR);
}
}


/**
/**
@@ -958,72 +950,55 @@ static const struct i2c_algorithm nmk_i2c_algo = {
	.functionality	= nmk_i2c_functionality
	.functionality	= nmk_i2c_functionality
};
};


static struct nmk_i2c_controller u8500_i2c = {
	.tft            = 1,      /* Tx FIFO threshold */
	.rft            = 8,      /* Rx FIFO threshold */
	.clk_freq       = 400000, /* fast mode operation */
	.timeout        = 200,    /* Slave response timeout(ms) */
	.sm             = I2C_FREQ_MODE_FAST,
};

static void nmk_i2c_of_probe(struct device_node *np,
static void nmk_i2c_of_probe(struct device_node *np,
			struct nmk_i2c_controller *pdata)
			     struct nmk_i2c_dev *nmk)
{
{
	of_property_read_u32(np, "clock-frequency", &pdata->clk_freq);
	/* Default to 100 kHz if no frequency is given in the node */
	if (of_property_read_u32(np, "clock-frequency", &nmk->clk_freq))
		nmk->clk_freq = 100000;


	/* This driver only supports 'standard' and 'fast' modes of operation. */
	/* This driver only supports 'standard' and 'fast' modes of operation. */
	if (pdata->clk_freq <= 100000)
	if (nmk->clk_freq <= 100000)
		pdata->sm = I2C_FREQ_MODE_STANDARD;
		nmk->sm = I2C_FREQ_MODE_STANDARD;
	else
	else
		pdata->sm = I2C_FREQ_MODE_FAST;
		nmk->sm = I2C_FREQ_MODE_FAST;
	nmk->tft = 1; /* Tx FIFO threshold */
	nmk->rft = 8; /* Rx FIFO threshold */
	nmk->timeout = 200; /* Slave response timeout(ms) */
}
}


static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
{
{
	int ret = 0;
	int ret = 0;
	struct nmk_i2c_controller *pdata = dev_get_platdata(&adev->dev);
	struct device_node *np = adev->dev.of_node;
	struct device_node *np = adev->dev.of_node;
	struct nmk_i2c_dev	*dev;
	struct nmk_i2c_dev	*dev;
	struct i2c_adapter *adap;
	struct i2c_adapter *adap;
	struct i2c_vendor_data *vendor = id->data;
	struct i2c_vendor_data *vendor = id->data;
	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
	u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;


	if (!pdata) {
	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
		if (np) {
	if (!dev) {
			pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL);
		dev_err(&adev->dev, "cannot allocate memory\n");
			if (!pdata) {
		ret = -ENOMEM;
		ret = -ENOMEM;
		goto err_no_mem;
		goto err_no_mem;
	}
	}
			/* Provide the default configuration as a base. */
	dev->vendor = vendor;
			memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller));
	dev->busy = false;
			nmk_i2c_of_probe(np, pdata);
	dev->adev = adev;
		} else
	nmk_i2c_of_probe(np, dev);
			/* No i2c configuration found, using the default. */
			pdata = &u8500_i2c;
	}


	if (pdata->tft > max_fifo_threshold) {
	if (dev->tft > max_fifo_threshold) {
		dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
		dev_warn(&adev->dev, "requested TX FIFO threshold %u, adjusted down to %u\n",
			pdata->tft, max_fifo_threshold);
			 dev->tft, max_fifo_threshold);
		pdata->tft = max_fifo_threshold;
		dev->tft = max_fifo_threshold;
	}
	}


	if (pdata->rft > max_fifo_threshold) {
	if (dev->rft > max_fifo_threshold) {
		dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
		dev_warn(&adev->dev, "requested RX FIFO threshold %u, adjusted down to %u\n",
			pdata->rft, max_fifo_threshold);
			dev->rft, max_fifo_threshold);
		pdata->rft = max_fifo_threshold;
		dev->rft = max_fifo_threshold;
	}
	}


	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&adev->dev, "cannot allocate memory\n");
		ret = -ENOMEM;
		goto err_no_mem;
	}
	dev->vendor = vendor;
	dev->busy = false;
	dev->adev = adev;
	amba_set_drvdata(adev, dev);
	amba_set_drvdata(adev, dev);


	/* Select default pin state */
	/* Select default pin state */
@@ -1060,16 +1035,10 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
	adap->owner	= THIS_MODULE;
	adap->owner	= THIS_MODULE;
	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
	adap->algo	= &nmk_i2c_algo;
	adap->algo	= &nmk_i2c_algo;
	adap->timeout	= msecs_to_jiffies(pdata->timeout);
	adap->timeout	= msecs_to_jiffies(dev->timeout);
	snprintf(adap->name, sizeof(adap->name),
	snprintf(adap->name, sizeof(adap->name),
		 "Nomadik I2C at %pR", &adev->res);
		 "Nomadik I2C at %pR", &adev->res);


	/* fetch the controller configuration from machine */
	dev->cfg.clk_freq = pdata->clk_freq;
	dev->cfg.tft	= pdata->tft;
	dev->cfg.rft	= pdata->rft;
	dev->cfg.sm	= pdata->sm;

	i2c_set_adapdata(adap, dev);
	i2c_set_adapdata(adap, dev);


	dev_info(&adev->dev,
	dev_info(&adev->dev,