diff options
Diffstat (limited to 'drivers/mfd/tps65912-debugfs.c')
| -rw-r--r-- | drivers/mfd/tps65912-debugfs.c | 213 | 
1 files changed, 213 insertions, 0 deletions
| diff --git a/drivers/mfd/tps65912-debugfs.c b/drivers/mfd/tps65912-debugfs.c new file mode 100644 index 00000000000..2a7d870aa8e --- /dev/null +++ b/drivers/mfd/tps65912-debugfs.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2013 Motorola Mobility LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include <linux/debugfs.h> +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/stat.h> +#include <linux/mfd/tps65912.h> + + +struct  tps65912_debugfs_reg_descr { +	char *name;	/* Debugfs file name */ +	u8 reg;		/* Register address */ +}; + +/* Registers exposed in debugfs */ +static const struct tps65912_debugfs_reg_descr debugfs_regs[] = { +	{ "DCDC1_CTRL",		0x00 }, +	{ "DCDC2_CTRL",		0x01 }, +	{ "DCDC3_CTRL",		0x02 }, +	{ "DCDC4_CTRL",		0x03 }, +	{ "DCDC1_OP",		0x04 }, +	{ "DCDC1_AVS",		0x05 }, +	{ "DCDC1_LIMIT",	0x06 }, +	{ "DCDC2_OP",		0x07 }, +	{ "DCDC2_AVS",		0x08 }, +	{ "DCDC2_LIMIT",	0x09 }, +	{ "DCDC3_OP",		0x0A }, +	{ "DCDC3_AVS",		0x0B }, +	{ "DCDC3_LIMIT",	0x0C }, +	{ "DCDC4_OP",		0x0D }, +	{ "DCDC4_AVS",		0x0E }, +	{ "DCDC4_LIMIT",	0x0F }, +	{ "LDO1_OP",		0x10 }, +	{ "LDO1_AVS",		0x11 }, +	{ "LDO1_LIMIT",		0x12 }, +	{ "LDO2_OP",		0x13 }, +	{ "LDO2_AVS",		0x14 }, +	{ "LDO2_LIMIT",		0x15 }, +	{ "LDO3_OP",		0x16 }, +	{ "LDO3_AVS",		0x17 }, +	{ "LDO3_LIMIT",		0x18 }, +	{ "LDO4_OP",		0x19 }, +	{ "LDO4_AVS",		0x1A }, +	{ "LDO4_LIMIT",		0x1B }, +	{ "LDO5",		0x1C }, +	{ "LDO6",		0x1D }, +	{ "LDO7",		0x1E }, +	{ "LDO8",		0x1F }, +	{ "LDO9",		0x20 }, +	{ "LDO10",		0x21 }, +	{ "THRM",		0x22 }, +	{ "CLK32OUT",		0x23 }, +	{ "DEVCTRL",		0x24 }, +	{ "DEVCTRL2",		0x25 }, +	{ "I2C_SPI_CFG",	0x26 }, +	{ "KEEP_ON",		0x27 }, +	{ "KEEP_ON2",		0x28 }, +	{ "SET_OFF1",		0x29 }, +	{ "SET_OFF2",		0x2A }, +	{ "DEF_VOLT",		0x2B }, +	{ "DEF_VOLT_MAPPING",	0x2C }, +	{ "DISCHARGE",		0x2D }, +	{ "DISCHARGE2",		0x2E }, +	{ "EN1_SET1",		0x2F }, +	{ "EN1_SET2",		0x30 }, +	{ "EN2_SET1",		0x31 }, +	{ "EN2_SET2",		0x32 }, +	{ "EN3_SET1",		0x33 }, +	{ "EN3_SET2",		0x34 }, +	{ "EN4_SET1",		0x35 }, +	{ "EN4_SET2",		0x36 }, +	{ "PGOOD",		0x37 }, +	{ "PGOOD2",		0x38 }, +	{ "INT_STS",		0x39 }, +	{ "INT_MSK",		0x3A }, +	{ "INT_STS2",		0x3B }, +	{ "INT_MSK2",		0x3C }, +	{ "INT_STS3",		0x3D }, +	{ "INT_MSK3",		0x3E }, +	{ "INT_STS4",		0x3F }, +	{ "INT_MSK4",		0x40 }, +	{ "GPIO1",		0x41 }, +	{ "GPIO2",		0x42 }, +	{ "GPIO3",		0x43 }, +	{ "GPIO4",		0x44 }, +	{ "GPIO5",		0x45 }, +	{ "VMON",		0x46 }, +	{ "LEDA_CTRL1",		0x47 }, +	{ "LEDA_CTRL2",		0x48 }, +	{ "LEDA_CTRL3",		0x49 }, +	{ "LEDA_CTRL4",		0x4A }, +	{ "LEDA_CTRL5",		0x4B }, +	{ "LEDA_CTRL6",		0x4C }, +	{ "LEDA_CTRL7",		0x4D }, +	{ "LEDA_CTRL8",		0x4E }, +	{ "LEDB_CTRL1",		0x4F }, +	{ "LEDB_CTRL2",		0x50 }, +	{ "LEDB_CTRL3",		0x51 }, +	{ "LEDB_CTRL4",		0x52 }, +	{ "LEDB_CTRL5",		0x53 }, +	{ "LEDB_CTRL6",		0x54 }, +	{ "LEDB_CTRL7",		0x55 }, +	{ "LEDB_CTRL8",		0x56 }, +	{ "LEDC_CTRL1",		0x57 }, +	{ "LEDC_CTRL2",		0x58 }, +	{ "LEDC_CTRL3",		0x59 }, +	{ "LEDC_CTRL4",		0x5A }, +	{ "LEDC_CTRL5",		0x5B }, +	{ "LEDC_CTRL6",		0x5C }, +	{ "LEDC_CTRL7",		0x5D }, +	{ "LEDC_CTRL8",		0x5E }, +	{ "LED_RAMP_UP_TIME",	0x5F }, +	{ "LED_RAMP_DOWN_TIME",	0x60 }, +	{ "LED_SEQ_EN",		0x61 }, +	{ "LOADSWITCH",		0x62 }, +	{ "SPARE",		0x63 }, +	{ "VERNUM",		0x64 }, +}; + +struct tps65912_debugfs_reg_data { +	struct tps65912 *tps65912;	/* Device */ +	u8 reg;				/* Register address */ +}; + +struct tps65912_debugfs_data { +	struct dentry *root;	/* Debugfs directory of the device */ +	struct tps65912_debugfs_reg_data reg_data[ARRAY_SIZE(debugfs_regs)]; +}; + +static int reg_read(void *data, u64 *val) +{ +	struct tps65912_debugfs_reg_data *reg_data; + +	reg_data = (struct tps65912_debugfs_reg_data *) data; +	*val = tps65912_reg_read(reg_data->tps65912, reg_data->reg); +	return 0; +} + +static int reg_write(void *data, u64 val) +{ +	struct tps65912_debugfs_reg_data *reg_data; + +	reg_data = (struct tps65912_debugfs_reg_data *) data; +	return tps65912_reg_write(reg_data->tps65912, reg_data->reg, val); +} + +DEFINE_SIMPLE_ATTRIBUTE(reg_fops, reg_read, reg_write, "0x%02llx\n"); + +int tps65912_debugfs_create(struct tps65912 *tps65912) +{ +	int i; +	struct tps65912_debugfs_data *debugfs_data; + +	debugfs_data = kzalloc(sizeof(struct tps65912_debugfs_data), +			       GFP_KERNEL); +	if (!debugfs_data) +		goto err_data; + +	debugfs_data->root = debugfs_create_dir(dev_name(tps65912->dev), NULL); +	if (!debugfs_data->root) +		goto err_root; + +	for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) { +		debugfs_data->reg_data[i].tps65912 = tps65912; +		debugfs_data->reg_data[i].reg = debugfs_regs[i].reg; +		if (!debugfs_create_file(debugfs_regs[i].name, +					S_IRUGO | S_IWUSR, debugfs_data->root, +					debugfs_data->reg_data + i, ®_fops)) +			goto err_file; +	} + +	tps65912->debugfs_data = debugfs_data; +	return 0; + +err_file: +	debugfs_remove_recursive(debugfs_data->root); +err_root: +	kfree(debugfs_data); +err_data: +	tps65912->debugfs_data = NULL; +	return -ENOMEM; +} + +void tps65912_debugfs_remove(struct tps65912 *tps65912) +{ +	struct tps65912_debugfs_data *debugfs_data; + +	debugfs_data = (struct tps65912_debugfs_data *) tps65912->debugfs_data; +	if (debugfs_data) { +		debugfs_remove_recursive(debugfs_data->root); +		kfree(debugfs_data); +	} +} |