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