238 lines · 5.4 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0//// Register map access API - W1 (1-Wire) support//// Copyright (c) 2017 Radioavionica Corporation// Author: Alex A. Mihaylov <minimumlaw@rambler.ru> #include <linux/regmap.h>#include <linux/module.h>#include <linux/w1.h> #include "internal.h" #define W1_CMD_READ_DATA	0x69#define W1_CMD_WRITE_DATA	0x6C /* * 1-Wire slaves registers with addess 8 bit and data 8 bit */ static int w1_reg_a8_v8_read(void *context, unsigned int reg, unsigned int *val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 255)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_READ_DATA);		w1_write_8(sl->master, reg);		*val = w1_read_8(sl->master);	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} static int w1_reg_a8_v8_write(void *context, unsigned int reg, unsigned int val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 255)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_WRITE_DATA);		w1_write_8(sl->master, reg);		w1_write_8(sl->master, val);	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} /* * 1-Wire slaves registers with addess 8 bit and data 16 bit */ static int w1_reg_a8_v16_read(void *context, unsigned int reg,				unsigned int *val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 255)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_READ_DATA);		w1_write_8(sl->master, reg);		*val = w1_read_8(sl->master);		*val |= w1_read_8(sl->master)<<8;	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} static int w1_reg_a8_v16_write(void *context, unsigned int reg,				unsigned int val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 255)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_WRITE_DATA);		w1_write_8(sl->master, reg);		w1_write_8(sl->master, val & 0x00FF);		w1_write_8(sl->master, val>>8 & 0x00FF);	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} /* * 1-Wire slaves registers with addess 16 bit and data 16 bit */ static int w1_reg_a16_v16_read(void *context, unsigned int reg,				unsigned int *val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 65535)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_READ_DATA);		w1_write_8(sl->master, reg & 0x00FF);		w1_write_8(sl->master, reg>>8 & 0x00FF);		*val = w1_read_8(sl->master);		*val |= w1_read_8(sl->master)<<8;	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} static int w1_reg_a16_v16_write(void *context, unsigned int reg,				unsigned int val){	struct device *dev = context;	struct w1_slave *sl = container_of(dev, struct w1_slave, dev);	int ret = 0; 	if (reg > 65535)		return -EINVAL; 	mutex_lock(&sl->master->bus_mutex);	if (!w1_reset_select_slave(sl)) {		w1_write_8(sl->master, W1_CMD_WRITE_DATA);		w1_write_8(sl->master, reg & 0x00FF);		w1_write_8(sl->master, reg>>8 & 0x00FF);		w1_write_8(sl->master, val & 0x00FF);		w1_write_8(sl->master, val>>8 & 0x00FF);	} else {		ret = -ENODEV;	}	mutex_unlock(&sl->master->bus_mutex); 	return ret;} /* * Various types of supported bus addressing */ static const struct regmap_bus regmap_w1_bus_a8_v8 = {	.reg_read = w1_reg_a8_v8_read,	.reg_write = w1_reg_a8_v8_write,}; static const struct regmap_bus regmap_w1_bus_a8_v16 = {	.reg_read = w1_reg_a8_v16_read,	.reg_write = w1_reg_a8_v16_write,}; static const struct regmap_bus regmap_w1_bus_a16_v16 = {	.reg_read = w1_reg_a16_v16_read,	.reg_write = w1_reg_a16_v16_write,}; static const struct regmap_bus *regmap_get_w1_bus(struct device *w1_dev,					const struct regmap_config *config){	if (config->reg_bits == 8 && config->val_bits == 8)		return &regmap_w1_bus_a8_v8; 	if (config->reg_bits == 8 && config->val_bits == 16)		return &regmap_w1_bus_a8_v16; 	if (config->reg_bits == 16 && config->val_bits == 16)		return &regmap_w1_bus_a16_v16; 	return ERR_PTR(-ENOTSUPP);} struct regmap *__regmap_init_w1(struct device *w1_dev,				 const struct regmap_config *config,				 struct lock_class_key *lock_key,				 const char *lock_name){ 	const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config); 	if (IS_ERR(bus))		return ERR_CAST(bus); 	return __regmap_init(w1_dev, bus, w1_dev, config,			 lock_key, lock_name);}EXPORT_SYMBOL_GPL(__regmap_init_w1); struct regmap *__devm_regmap_init_w1(struct device *w1_dev,				 const struct regmap_config *config,				 struct lock_class_key *lock_key,				 const char *lock_name){ 	const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config); 	if (IS_ERR(bus))		return ERR_CAST(bus); 	return __devm_regmap_init(w1_dev, bus, w1_dev, config,				 lock_key, lock_name);}EXPORT_SYMBOL_GPL(__devm_regmap_init_w1); MODULE_DESCRIPTION("Register map access API - W1 (1-Wire) support");MODULE_LICENSE("GPL");

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t