Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2 * TI SMSC MFD Driver
  3 *
  4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
  5 *
  6 * Author: Sourav Poddar <sourav.poddar@ti.com>
  7 *
  8 *  This program is free software; you can redistribute it and/or modify it
  9 *  under  the terms of the GNU General  Public License as published by the
 10 *  Free Software Foundation;  GPL v2.
 11 *
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/moduleparam.h>
 16#include <linux/slab.h>
 17#include <linux/i2c.h>
 18#include <linux/gpio.h>
 19#include <linux/workqueue.h>
 20#include <linux/irq.h>
 21#include <linux/regmap.h>
 22#include <linux/err.h>
 23#include <linux/mfd/core.h>
 24#include <linux/mfd/smsc.h>
 25#include <linux/of_platform.h>
 26
 27static const struct regmap_config smsc_regmap_config = {
 28		.reg_bits = 8,
 29		.val_bits = 8,
 30		.max_register = SMSC_VEN_ID_H,
 31		.cache_type = REGCACHE_RBTREE,
 32};
 33
 34static int smsc_i2c_probe(struct i2c_client *i2c,
 35			const struct i2c_device_id *id)
 36{
 37	struct smsc *smsc;
 38	int devid, rev, venid_l, venid_h;
 39	int ret = 0;
 40
 41	smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
 42				GFP_KERNEL);
 43	if (!smsc) {
 44		dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
 45		return -ENOMEM;
 46	}
 47
 48	smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
 49	if (IS_ERR(smsc->regmap)) {
 50		ret = PTR_ERR(smsc->regmap);
 51		goto err;
 52	}
 53
 54	i2c_set_clientdata(i2c, smsc);
 55	smsc->dev = &i2c->dev;
 56
 57#ifdef CONFIG_OF
 58	of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk);
 59#endif
 60
 61	regmap_read(smsc->regmap, SMSC_DEV_ID, &devid);
 62	regmap_read(smsc->regmap, SMSC_DEV_REV, &rev);
 63	regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l);
 64	regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h);
 65
 66	dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n",
 67		devid, rev, (venid_h << 8) | venid_l);
 68
 69	ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
 70	if (ret)
 71		goto err;
 72
 73#ifdef CONFIG_OF
 74	if (i2c->dev.of_node)
 75		ret = of_platform_populate(i2c->dev.of_node,
 76					   NULL, NULL, &i2c->dev);
 77#endif
 78
 79err:
 80	return ret;
 81}
 82
 83static int smsc_i2c_remove(struct i2c_client *i2c)
 84{
 85	struct smsc *smsc = i2c_get_clientdata(i2c);
 86
 87	mfd_remove_devices(smsc->dev);
 88
 89	return 0;
 90}
 91
 92static const struct i2c_device_id smsc_i2c_id[] = {
 93	{ "smscece1099", 0},
 94	{},
 95};
 96MODULE_DEVICE_TABLE(i2c, smsc_i2c_id);
 97
 98static struct i2c_driver smsc_i2c_driver = {
 99	.driver = {
100		   .name = "smsc",
101	},
102	.probe = smsc_i2c_probe,
103	.remove = smsc_i2c_remove,
104	.id_table = smsc_i2c_id,
105};
106
107module_i2c_driver(smsc_i2c_driver);
108
109MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
110MODULE_DESCRIPTION("SMSC chip multi-function driver");
111MODULE_LICENSE("GPL v2");