linux/drivers/i2c/muxes/i2c-mux-pinctrl.c
<<
>>
Prefs
   1/*
   2 * I2C multiplexer using pinctrl API
   3 *
   4 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17 */
  18
  19#include <linux/i2c.h>
  20#include <linux/i2c-mux.h>
  21#include <linux/module.h>
  22#include <linux/pinctrl/consumer.h>
  23#include <linux/i2c-mux-pinctrl.h>
  24#include <linux/platform_device.h>
  25#include <linux/slab.h>
  26#include <linux/of.h>
  27#include "../../pinctrl/core.h"
  28
  29struct i2c_mux_pinctrl {
  30        struct i2c_mux_pinctrl_platform_data *pdata;
  31        struct pinctrl *pinctrl;
  32        struct pinctrl_state **states;
  33        struct pinctrl_state *state_idle;
  34};
  35
  36static int i2c_mux_pinctrl_select(struct i2c_mux_core *muxc, u32 chan)
  37{
  38        struct i2c_mux_pinctrl *mux = i2c_mux_priv(muxc);
  39
  40        return pinctrl_select_state(mux->pinctrl, mux->states[chan]);
  41}
  42
  43static int i2c_mux_pinctrl_deselect(struct i2c_mux_core *muxc, u32 chan)
  44{
  45        struct i2c_mux_pinctrl *mux = i2c_mux_priv(muxc);
  46
  47        return pinctrl_select_state(mux->pinctrl, mux->state_idle);
  48}
  49
  50#ifdef CONFIG_OF
  51static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux,
  52                                    struct platform_device *pdev)
  53{
  54        struct device_node *np = pdev->dev.of_node;
  55        int num_names, i, ret;
  56        struct device_node *adapter_np;
  57        struct i2c_adapter *adapter;
  58
  59        if (!np)
  60                return 0;
  61
  62        mux->pdata = devm_kzalloc(&pdev->dev, sizeof(*mux->pdata), GFP_KERNEL);
  63        if (!mux->pdata)
  64                return -ENOMEM;
  65
  66        num_names = of_property_count_strings(np, "pinctrl-names");
  67        if (num_names < 0) {
  68                dev_err(&pdev->dev, "Cannot parse pinctrl-names: %d\n",
  69                        num_names);
  70                return num_names;
  71        }
  72
  73        mux->pdata->pinctrl_states = devm_kzalloc(&pdev->dev,
  74                sizeof(*mux->pdata->pinctrl_states) * num_names,
  75                GFP_KERNEL);
  76        if (!mux->pdata->pinctrl_states)
  77                return -ENOMEM;
  78
  79        for (i = 0; i < num_names; i++) {
  80                ret = of_property_read_string_index(np, "pinctrl-names", i,
  81                        &mux->pdata->pinctrl_states[mux->pdata->bus_count]);
  82                if (ret < 0) {
  83                        dev_err(&pdev->dev, "Cannot parse pinctrl-names: %d\n",
  84                                ret);
  85                        return ret;
  86                }
  87                if (!strcmp(mux->pdata->pinctrl_states[mux->pdata->bus_count],
  88                            "idle")) {
  89                        if (i != num_names - 1) {
  90                                dev_err(&pdev->dev,
  91                                        "idle state must be last\n");
  92                                return -EINVAL;
  93                        }
  94                        mux->pdata->pinctrl_state_idle = "idle";
  95                } else {
  96                        mux->pdata->bus_count++;
  97                }
  98        }
  99
 100        adapter_np = of_parse_phandle(np, "i2c-parent", 0);
 101        if (!adapter_np) {
 102                dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
 103                return -ENODEV;
 104        }
 105        adapter = of_find_i2c_adapter_by_node(adapter_np);
 106        of_node_put(adapter_np);
 107        if (!adapter) {
 108                dev_err(&pdev->dev, "Cannot find parent bus\n");
 109                return -EPROBE_DEFER;
 110        }
 111        mux->pdata->parent_bus_num = i2c_adapter_id(adapter);
 112        put_device(&adapter->dev);
 113
 114        return 0;
 115}
 116#else
 117static inline int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux,
 118                                           struct platform_device *pdev)
 119{
 120        return 0;
 121}
 122#endif
 123
 124static struct i2c_adapter *i2c_mux_pinctrl_root_adapter(
 125        struct pinctrl_state *state)
 126{
 127        struct i2c_adapter *root = NULL;
 128        struct pinctrl_setting *setting;
 129        struct i2c_adapter *pin_root;
 130
 131        list_for_each_entry(setting, &state->settings, node) {
 132                pin_root = i2c_root_adapter(setting->pctldev->dev);
 133                if (!pin_root)
 134                        return NULL;
 135                if (!root)
 136                        root = pin_root;
 137                else if (root != pin_root)
 138                        return NULL;
 139        }
 140
 141        return root;
 142}
 143
 144static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 145{
 146        struct i2c_mux_core *muxc;
 147        struct i2c_mux_pinctrl *mux;
 148        struct i2c_adapter *root;
 149        int i, ret;
 150
 151        mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
 152        if (!mux) {
 153                ret = -ENOMEM;
 154                goto err;
 155        }
 156
 157        mux->pdata = dev_get_platdata(&pdev->dev);
 158        if (!mux->pdata) {
 159                ret = i2c_mux_pinctrl_parse_dt(mux, pdev);
 160                if (ret < 0)
 161                        goto err;
 162        }
 163        if (!mux->pdata) {
 164                dev_err(&pdev->dev, "Missing platform data\n");
 165                ret = -ENODEV;
 166                goto err;
 167        }
 168
 169        mux->states = devm_kzalloc(&pdev->dev,
 170                                   sizeof(*mux->states) * mux->pdata->bus_count,
 171                                   GFP_KERNEL);
 172        if (!mux->states) {
 173                dev_err(&pdev->dev, "Cannot allocate states\n");
 174                ret = -ENOMEM;
 175                goto err;
 176        }
 177
 178        muxc = i2c_mux_alloc(NULL, &pdev->dev, mux->pdata->bus_count, 0, 0,
 179                             i2c_mux_pinctrl_select, NULL);
 180        if (!muxc) {
 181                ret = -ENOMEM;
 182                goto err;
 183        }
 184        muxc->priv = mux;
 185
 186        platform_set_drvdata(pdev, muxc);
 187
 188        mux->pinctrl = devm_pinctrl_get(&pdev->dev);
 189        if (IS_ERR(mux->pinctrl)) {
 190                ret = PTR_ERR(mux->pinctrl);
 191                dev_err(&pdev->dev, "Cannot get pinctrl: %d\n", ret);
 192                goto err;
 193        }
 194        for (i = 0; i < mux->pdata->bus_count; i++) {
 195                mux->states[i] = pinctrl_lookup_state(mux->pinctrl,
 196                                                mux->pdata->pinctrl_states[i]);
 197                if (IS_ERR(mux->states[i])) {
 198                        ret = PTR_ERR(mux->states[i]);
 199                        dev_err(&pdev->dev,
 200                                "Cannot look up pinctrl state %s: %d\n",
 201                                mux->pdata->pinctrl_states[i], ret);
 202                        goto err;
 203                }
 204        }
 205        if (mux->pdata->pinctrl_state_idle) {
 206                mux->state_idle = pinctrl_lookup_state(mux->pinctrl,
 207                                                mux->pdata->pinctrl_state_idle);
 208                if (IS_ERR(mux->state_idle)) {
 209                        ret = PTR_ERR(mux->state_idle);
 210                        dev_err(&pdev->dev,
 211                                "Cannot look up pinctrl state %s: %d\n",
 212                                mux->pdata->pinctrl_state_idle, ret);
 213                        goto err;
 214                }
 215
 216                muxc->deselect = i2c_mux_pinctrl_deselect;
 217        }
 218
 219        muxc->parent = i2c_get_adapter(mux->pdata->parent_bus_num);
 220        if (!muxc->parent) {
 221                dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
 222                        mux->pdata->parent_bus_num);
 223                ret = -EPROBE_DEFER;
 224                goto err;
 225        }
 226
 227        root = i2c_root_adapter(&muxc->parent->dev);
 228
 229        muxc->mux_locked = true;
 230        for (i = 0; i < mux->pdata->bus_count; i++) {
 231                if (root != i2c_mux_pinctrl_root_adapter(mux->states[i])) {
 232                        muxc->mux_locked = false;
 233                        break;
 234                }
 235        }
 236        if (muxc->mux_locked && mux->pdata->pinctrl_state_idle &&
 237            root != i2c_mux_pinctrl_root_adapter(mux->state_idle))
 238                muxc->mux_locked = false;
 239
 240        if (muxc->mux_locked)
 241                dev_info(&pdev->dev, "mux-locked i2c mux\n");
 242
 243        for (i = 0; i < mux->pdata->bus_count; i++) {
 244                u32 bus = mux->pdata->base_bus_num ?
 245                                (mux->pdata->base_bus_num + i) : 0;
 246
 247                ret = i2c_mux_add_adapter(muxc, bus, i, 0);
 248                if (ret)
 249                        goto err_del_adapter;
 250        }
 251
 252        return 0;
 253
 254err_del_adapter:
 255        i2c_mux_del_adapters(muxc);
 256        i2c_put_adapter(muxc->parent);
 257err:
 258        return ret;
 259}
 260
 261static int i2c_mux_pinctrl_remove(struct platform_device *pdev)
 262{
 263        struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
 264
 265        i2c_mux_del_adapters(muxc);
 266        i2c_put_adapter(muxc->parent);
 267        return 0;
 268}
 269
 270#ifdef CONFIG_OF
 271static const struct of_device_id i2c_mux_pinctrl_of_match[] = {
 272        { .compatible = "i2c-mux-pinctrl", },
 273        {},
 274};
 275MODULE_DEVICE_TABLE(of, i2c_mux_pinctrl_of_match);
 276#endif
 277
 278static struct platform_driver i2c_mux_pinctrl_driver = {
 279        .driver = {
 280                .name   = "i2c-mux-pinctrl",
 281                .of_match_table = of_match_ptr(i2c_mux_pinctrl_of_match),
 282        },
 283        .probe  = i2c_mux_pinctrl_probe,
 284        .remove = i2c_mux_pinctrl_remove,
 285};
 286module_platform_driver(i2c_mux_pinctrl_driver);
 287
 288MODULE_DESCRIPTION("pinctrl-based I2C multiplexer driver");
 289MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
 290MODULE_LICENSE("GPL v2");
 291MODULE_ALIAS("platform:i2c-mux-pinctrl");
 292