@@ -38,6 +38,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
+#include <linux/of_address.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_data/i2c-imx.h>
#include <linux/platform_device.h>
@@ -156,6 +157,44 @@ static struct imx_i2c_clk_pair vf610_i2c_clk_div[] = {
{ 3840, 0x3F }, { 4096, 0x7B }, { 5120, 0x7D }, { 6144, 0x7E },
};
+static struct imx_i2c_clk_pair mul2_i2c_clk_div[] = {
+ { 40, 0x40 }, { 44, 0x41 }, { 48, 0x42 }, { 52, 0x43 },
+ { 56, 0x44 }, { 60, 0x45 }, { 68, 0x46 }, { 80, 0x47 },
+ { 56, 0x48 }, { 64, 0x49 }, { 72, 0x4A }, { 80, 0x4B },
+ { 88, 0x4C }, { 96, 0x4D }, { 112, 0x4E }, { 136, 0x4F },
+ { 96, 0x50 }, { 112, 0x51 }, { 128, 0x52 }, { 144, 0x53 },
+ { 160, 0x54 }, { 176, 0x55 }, { 208, 0x56 }, { 256, 0x57 },
+ { 160, 0x58 }, { 192, 0x59 }, { 224, 0x5A }, { 256, 0x5B },
+ { 288, 0x5C }, { 320, 0x5D }, { 384, 0x5E }, { 480, 0x5F },
+ { 320, 0x60 }, { 384, 0x61 }, { 448, 0x62 }, { 512, 0x63 },
+ { 576, 0x64 }, { 640, 0x65 }, { 768, 0x66 }, { 960, 0x67 },
+ { 640, 0x68 }, { 768, 0x69 }, { 896, 0x6A }, { 1024, 0x6B },
+ { 1152, 0x6C }, { 1280, 0x6D }, { 1536, 0x6E }, { 1920, 0x6F },
+ { 1280, 0x70 }, { 1536, 0x71 }, { 1792, 0x72 }, { 2048, 0x73 },
+ { 2304, 0x74 }, { 2560, 0x75 }, { 3072, 0x76 }, { 3840, 0x77 },
+ { 2560, 0x78 }, { 3072, 0x79 }, { 3584, 0x7A }, { 4096, 0x7B },
+ { 4608, 0x7C }, { 5120, 0x7D }, { 6144, 0x7E }, { 7680, 0x7F },
+};
+
+static struct imx_i2c_clk_pair mul4_i2c_clk_div[] = {
+ { 80, 0x80 }, { 88, 0x81 }, { 96, 0x82 }, { 104, 0x83 },
+ { 112, 0x84 }, { 120, 0x85 }, { 136, 0x86 }, { 160, 0x87 },
+ { 112, 0x88 }, { 128, 0x89 }, { 144, 0x8A }, { 160, 0x8B },
+ { 176, 0x8C }, { 192, 0x8D }, { 224, 0x8E }, { 272, 0x8F },
+ { 192, 0x90 }, { 224, 0x91 }, { 256, 0x92 }, { 288, 0x93 },
+ { 320, 0x94 }, { 352, 0x95 }, { 416, 0x96 }, { 512, 0x97 },
+ { 320, 0x98 }, { 384, 0x99 }, { 448, 0x9A }, { 512, 0x9B },
+ { 576, 0x9C }, { 640, 0x9D }, { 768, 0x9E }, { 960, 0x9F },
+ { 640, 0xA0 }, { 768, 0xA1 }, { 896, 0xA2 }, { 1024, 0xA3 },
+ { 1152, 0xA4 }, { 1280, 0xA5 }, { 1536, 0xA6 }, { 1792, 0xAA },
+ { 1280, 0xA8 }, { 1536, 0xA9 }, { 1920, 0xA7 }, { 2048, 0xAB },
+ { 2304, 0xAC }, { 2560, 0xAD }, { 3072, 0xAE }, { 3584, 0xB2 },
+ { 2560, 0xB0 }, { 3072, 0xB1 }, { 3820, 0xAF }, { 4096, 0xB3 },
+ { 4608, 0xB4 }, { 5120, 0xB5 }, { 6144, 0xB6 }, { 7680, 0xB7 },
+ { 5120, 0xB8 }, { 6144, 0xB9 }, { 7168, 0xBA }, { 8192, 0xBB },
+ { 9216, 0xBC }, { 10240, 0xBD }, { 12288, 0xBE }, { 15360, 0xBF },
+};
+
enum imx_i2c_type {
IMX1_I2C,
IMX21_I2C,
@@ -234,6 +273,24 @@ static struct imx_i2c_hwdata vf610_i2c_hwdata = {
};
+static struct imx_i2c_hwdata mul2_i2c_hwdata = {
+ .devtype = VF610_I2C,
+ .regshift = VF610_I2C_REGSHIFT,
+ .clk_div = mul2_i2c_clk_div,
+ .ndivs = ARRAY_SIZE(mul2_i2c_clk_div),
+ .i2sr_clr_opcode = I2SR_CLR_OPCODE_W1C,
+ .i2cr_ien_opcode = I2CR_IEN_OPCODE_0,
+};
+
+static struct imx_i2c_hwdata mul4_i2c_hwdata = {
+ .devtype = VF610_I2C,
+ .regshift = VF610_I2C_REGSHIFT,
+ .clk_div = mul4_i2c_clk_div,
+ .ndivs = ARRAY_SIZE(mul4_i2c_clk_div),
+ .i2sr_clr_opcode = I2SR_CLR_OPCODE_W1C,
+ .i2cr_ien_opcode = I2CR_IEN_OPCODE_0,
+};
+
static const struct platform_device_id imx_i2c_devtype[] = {
{
.name = "imx1-i2c",
@@ -1058,6 +1115,7 @@ static int i2c_imx_probe(struct platform_device *pdev)
void __iomem *base;
int irq, ret;
dma_addr_t phy_addr;
+ u32 mul_value;
dev_dbg(&pdev->dev, "<%s>\n", __func__);
@@ -1077,11 +1135,20 @@ static int i2c_imx_probe(struct platform_device *pdev)
if (!i2c_imx)
return -ENOMEM;
- if (of_id)
+ if (of_id) {
i2c_imx->hwdata = of_id->data;
- else
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "mul-value", &mul_value);
+ if (!ret) {
+ if (mul_value == 2)
+ i2c_imx->hwdata = &mul2_i2c_hwdata;
+ else if (mul_value == 4)
+ i2c_imx->hwdata = &mul4_i2c_hwdata;
+ }
+ } else {
i2c_imx->hwdata = (struct imx_i2c_hwdata *)
platform_get_device_id(pdev)->driver_data;
+ }
/* Setup i2c_imx driver structure */
strlcpy(i2c_imx->adapter.name, pdev->name, sizeof(i2c_imx->adapter.name));