123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #include <linux/err.h>
- #include <linux/i2c.h>
- #include <linux/i2c-mux.h>
- #include <linux/iio/iio.h>
- #include <linux/module.h>
- #include <linux/regmap.h>
- #include <linux/pm_runtime.h>
- #include "mpu3050.h"
- static const struct regmap_config mpu3050_i2c_regmap_config = {
- .reg_bits = 8,
- .val_bits = 8,
- };
- static int mpu3050_i2c_bypass_select(struct i2c_mux_core *mux, u32 chan_id)
- {
- struct mpu3050 *mpu3050 = i2c_mux_priv(mux);
- /* Just power up the device, that is all that is needed */
- pm_runtime_get_sync(mpu3050->dev);
- return 0;
- }
- static int mpu3050_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id)
- {
- struct mpu3050 *mpu3050 = i2c_mux_priv(mux);
- pm_runtime_mark_last_busy(mpu3050->dev);
- pm_runtime_put_autosuspend(mpu3050->dev);
- return 0;
- }
- static int mpu3050_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct regmap *regmap;
- const char *name;
- struct mpu3050 *mpu3050;
- int ret;
- if (!i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_I2C_BLOCK))
- return -EOPNOTSUPP;
- if (id)
- name = id->name;
- else
- return -ENODEV;
- regmap = devm_regmap_init_i2c(client, &mpu3050_i2c_regmap_config);
- if (IS_ERR(regmap)) {
- dev_err(&client->dev, "Failed to register i2c regmap %d\n",
- (int)PTR_ERR(regmap));
- return PTR_ERR(regmap);
- }
- ret = mpu3050_common_probe(&client->dev, regmap, client->irq, name);
- if (ret)
- return ret;
- /* The main driver is up, now register the I2C mux */
- mpu3050 = iio_priv(dev_get_drvdata(&client->dev));
- mpu3050->i2cmux = i2c_mux_alloc(client->adapter, &client->dev,
- 1, 0, I2C_MUX_LOCKED | I2C_MUX_GATE,
- mpu3050_i2c_bypass_select,
- mpu3050_i2c_bypass_deselect);
- /* Just fail the mux, there is no point in killing the driver */
- if (!mpu3050->i2cmux)
- dev_err(&client->dev, "failed to allocate I2C mux\n");
- else {
- mpu3050->i2cmux->priv = mpu3050;
- /* Ignore failure, not critical */
- i2c_mux_add_adapter(mpu3050->i2cmux, 0, 0, 0);
- }
- return 0;
- }
- static int mpu3050_i2c_remove(struct i2c_client *client)
- {
- struct iio_dev *indio_dev = dev_get_drvdata(&client->dev);
- struct mpu3050 *mpu3050 = iio_priv(indio_dev);
- if (mpu3050->i2cmux)
- i2c_mux_del_adapters(mpu3050->i2cmux);
- return mpu3050_common_remove(&client->dev);
- }
- /*
- * device id table is used to identify what device can be
- * supported by this driver
- */
- static const struct i2c_device_id mpu3050_i2c_id[] = {
- { "mpu3050" },
- {}
- };
- MODULE_DEVICE_TABLE(i2c, mpu3050_i2c_id);
- static const struct of_device_id mpu3050_i2c_of_match[] = {
- { .compatible = "invensense,mpu3050", .data = "mpu3050" },
- /* Deprecated vendor ID from the Input driver */
- { .compatible = "invn,mpu3050", .data = "mpu3050" },
- { },
- };
- MODULE_DEVICE_TABLE(of, mpu3050_i2c_of_match);
- static struct i2c_driver mpu3050_i2c_driver = {
- .probe = mpu3050_i2c_probe,
- .remove = mpu3050_i2c_remove,
- .id_table = mpu3050_i2c_id,
- .driver = {
- .of_match_table = mpu3050_i2c_of_match,
- .name = "mpu3050-i2c",
- .pm = &mpu3050_dev_pm_ops,
- },
- };
- module_i2c_driver(mpu3050_i2c_driver);
- MODULE_AUTHOR("Linus Walleij");
- MODULE_DESCRIPTION("Invensense MPU3050 gyroscope driver");
- MODULE_LICENSE("GPL");
|