1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Helper module for board specific I2C bus registration 4 * 5 * Copyright (C) 2009 Nokia Corporation. 6 */ 7 8 #include <linux/i2c.h> 9 #include <linux/platform_data/i2c-omap.h> 10 #include <mach/mux.h> 11 #include "soc.h" 12 13 #define OMAP_I2C_SIZE 0x3f 14 #define OMAP1_I2C_BASE 0xfffb3800 15 16 static const char name[] = "omap_i2c"; 17 18 static struct resource i2c_resources[2] = { 19 }; 20 21 static struct platform_device omap_i2c_devices[1] = { 22 }; 23 24 static void __init omap1_i2c_mux_pins(int bus_id) 25 { 26 if (cpu_is_omap7xx()) { 27 omap_cfg_reg(I2C_7XX_SDA); 28 omap_cfg_reg(I2C_7XX_SCL); 29 } else { 30 omap_cfg_reg(I2C_SDA); 31 omap_cfg_reg(I2C_SCL); 32 } 33 } 34 35 int __init omap_i2c_add_bus(struct omap_i2c_bus_platform_data *pdata, 36 int bus_id) 37 { 38 struct platform_device *pdev; 39 struct resource *res; 40 41 if (bus_id > 1) 42 return -EINVAL; 43 44 omap1_i2c_mux_pins(bus_id); 45 46 pdev = &omap_i2c_devices[bus_id - 1]; 47 pdev->id = bus_id; 48 pdev->name = name; 49 pdev->num_resources = ARRAY_SIZE(i2c_resources); 50 res = i2c_resources; 51 res[0].start = OMAP1_I2C_BASE; 52 res[0].end = res[0].start + OMAP_I2C_SIZE; 53 res[0].flags = IORESOURCE_MEM; 54 res[1].start = INT_I2C; 55 res[1].flags = IORESOURCE_IRQ; 56 pdev->resource = res; 57 58 /* all OMAP1 have IP version 1 register set */ 59 pdata->rev = OMAP_I2C_IP_VERSION_1; 60 61 /* all OMAP1 I2C are implemented like this */ 62 pdata->flags = OMAP_I2C_FLAG_NO_FIFO | 63 OMAP_I2C_FLAG_SIMPLE_CLOCK | 64 OMAP_I2C_FLAG_16BIT_DATA_REG | 65 OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK; 66 67 /* how the cpu bus is wired up differs for 7xx only */ 68 69 if (cpu_is_omap7xx()) 70 pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_1; 71 else 72 pdata->flags |= OMAP_I2C_FLAG_BUS_SHIFT_2; 73 74 pdev->dev.platform_data = pdata; 75 76 return platform_device_register(pdev); 77 } 78 79 #define OMAP_I2C_MAX_CONTROLLERS 4 80 static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS]; 81 82 #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) 83 84 /** 85 * omap_i2c_bus_setup - Process command line options for the I2C bus speed 86 * @str: String of options 87 * 88 * This function allow to override the default I2C bus speed for given I2C 89 * bus with a command line option. 90 * 91 * Format: i2c_bus=bus_id,clkrate (in kHz) 92 * 93 * Returns 1 on success, 0 otherwise. 94 */ 95 static int __init omap_i2c_bus_setup(char *str) 96 { 97 int ints[3]; 98 99 get_options(str, 3, ints); 100 if (ints[0] < 2 || ints[1] < 1 || 101 ints[1] > OMAP_I2C_MAX_CONTROLLERS) 102 return 0; 103 i2c_pdata[ints[1] - 1].clkrate = ints[2]; 104 i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP; 105 106 return 1; 107 } 108 __setup("i2c_bus=", omap_i2c_bus_setup); 109 110 /* 111 * Register busses defined in command line but that are not registered with 112 * omap_register_i2c_bus from board initialization code. 113 */ 114 int __init omap_register_i2c_bus_cmdline(void) 115 { 116 int i, err = 0; 117 118 for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++) 119 if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) { 120 i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; 121 err = omap_i2c_add_bus(&i2c_pdata[i], i + 1); 122 if (err) 123 goto out; 124 } 125 126 out: 127 return err; 128 } 129 130 /** 131 * omap_register_i2c_bus - register I2C bus with device descriptors 132 * @bus_id: bus id counting from number 1 133 * @clkrate: clock rate of the bus in kHz 134 * @info: pointer into I2C device descriptor table or NULL 135 * @len: number of descriptors in the table 136 * 137 * Returns 0 on success or an error code. 138 */ 139 int __init omap_register_i2c_bus(int bus_id, u32 clkrate, 140 struct i2c_board_info const *info, 141 unsigned len) 142 { 143 int err; 144 145 BUG_ON(bus_id < 1 || bus_id > OMAP_I2C_MAX_CONTROLLERS); 146 147 if (info) { 148 err = i2c_register_board_info(bus_id, info, len); 149 if (err) 150 return err; 151 } 152 153 if (!i2c_pdata[bus_id - 1].clkrate) 154 i2c_pdata[bus_id - 1].clkrate = clkrate; 155 156 i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; 157 158 return omap_i2c_add_bus(&i2c_pdata[bus_id - 1], bus_id); 159 } 160 161 static int __init omap_i2c_cmdline(void) 162 { 163 return omap_register_i2c_bus_cmdline(); 164 } 165 subsys_initcall(omap_i2c_cmdline); 166