brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · a000aed Raw
175 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * I2C driver for Marvell 88PM860x4 *5 * Copyright (C) 2009 Marvell International Ltd.6 *7 * Author: Haojian Zhuang <haojian.zhuang@marvell.com>8 */9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/i2c.h>12#include <linux/regmap.h>13#include <linux/mfd/88pm860x.h>14 15int pm860x_reg_read(struct i2c_client *i2c, int reg)16{17	struct pm860x_chip *chip = i2c_get_clientdata(i2c);18	struct regmap *map = (i2c == chip->client) ? chip->regmap19				: chip->regmap_companion;20	unsigned int data;21	int ret;22 23	ret = regmap_read(map, reg, &data);24	if (ret < 0)25		return ret;26	else27		return (int)data;28}29EXPORT_SYMBOL(pm860x_reg_read);30 31int pm860x_reg_write(struct i2c_client *i2c, int reg,32		     unsigned char data)33{34	struct pm860x_chip *chip = i2c_get_clientdata(i2c);35	struct regmap *map = (i2c == chip->client) ? chip->regmap36				: chip->regmap_companion;37	int ret;38 39	ret = regmap_write(map, reg, data);40	return ret;41}42EXPORT_SYMBOL(pm860x_reg_write);43 44int pm860x_bulk_read(struct i2c_client *i2c, int reg,45		     int count, unsigned char *buf)46{47	struct pm860x_chip *chip = i2c_get_clientdata(i2c);48	struct regmap *map = (i2c == chip->client) ? chip->regmap49				: chip->regmap_companion;50	int ret;51 52	ret = regmap_raw_read(map, reg, buf, count);53	return ret;54}55EXPORT_SYMBOL(pm860x_bulk_read);56 57int pm860x_bulk_write(struct i2c_client *i2c, int reg,58		      int count, unsigned char *buf)59{60	struct pm860x_chip *chip = i2c_get_clientdata(i2c);61	struct regmap *map = (i2c == chip->client) ? chip->regmap62				: chip->regmap_companion;63	int ret;64 65	ret = regmap_raw_write(map, reg, buf, count);66	return ret;67}68EXPORT_SYMBOL(pm860x_bulk_write);69 70int pm860x_set_bits(struct i2c_client *i2c, int reg,71		    unsigned char mask, unsigned char data)72{73	struct pm860x_chip *chip = i2c_get_clientdata(i2c);74	struct regmap *map = (i2c == chip->client) ? chip->regmap75				: chip->regmap_companion;76	int ret;77 78	ret = regmap_update_bits(map, reg, mask, data);79	return ret;80}81EXPORT_SYMBOL(pm860x_set_bits);82 83static int read_device(struct i2c_client *i2c, int reg,84		       int bytes, void *dest)85{86	unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3];87	unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2];88	struct i2c_adapter *adap = i2c->adapter;89	struct i2c_msg msg[2] = {90					{91						.addr = i2c->addr,92						.flags = 0,93						.len = 1,94						.buf = msgbuf095					},96					{	.addr = i2c->addr,97						.flags = I2C_M_RD,98						.len = 0,99						.buf = msgbuf1100					},101				};102	int num = 1, ret = 0;103 104	if (dest == NULL)105		return -EINVAL;106	msgbuf0[0] = (unsigned char)reg;	/* command */107	msg[1].len = bytes;108 109	/* if data needs to read back, num should be 2 */110	if (bytes > 0)111		num = 2;112	ret = adap->algo->master_xfer(adap, msg, num);113	memcpy(dest, msgbuf1, bytes);114	if (ret < 0)115		return ret;116	return 0;117}118 119static int write_device(struct i2c_client *i2c, int reg,120			int bytes, void *src)121{122	unsigned char buf[2];123	struct i2c_adapter *adap = i2c->adapter;124	struct i2c_msg msg;125	int ret;126 127	buf[0] = (unsigned char)reg;128	memcpy(&buf[1], src, bytes);129	msg.addr = i2c->addr;130	msg.flags = 0;131	msg.len = bytes + 1;132	msg.buf = buf;133 134	ret = adap->algo->master_xfer(adap, &msg, 1);135	if (ret < 0)136		return ret;137	return 0;138}139 140int pm860x_page_reg_write(struct i2c_client *i2c, int reg,141			  unsigned char data)142{143	unsigned char zero;144	int ret;145 146	i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT);147	read_device(i2c, 0xFA, 0, &zero);148	read_device(i2c, 0xFB, 0, &zero);149	read_device(i2c, 0xFF, 0, &zero);150	ret = write_device(i2c, reg, 1, &data);151	read_device(i2c, 0xFE, 0, &zero);152	read_device(i2c, 0xFC, 0, &zero);153	i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT);154	return ret;155}156EXPORT_SYMBOL(pm860x_page_reg_write);157 158int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,159			  int count, unsigned char *buf)160{161	unsigned char zero = 0;162	int ret;163 164	i2c_lock_bus(i2c->adapter, I2C_LOCK_SEGMENT);165	read_device(i2c, 0xfa, 0, &zero);166	read_device(i2c, 0xfb, 0, &zero);167	read_device(i2c, 0xff, 0, &zero);168	ret = read_device(i2c, reg, count, buf);169	read_device(i2c, 0xFE, 0, &zero);170	read_device(i2c, 0xFC, 0, &zero);171	i2c_unlock_bus(i2c->adapter, I2C_LOCK_SEGMENT);172	return ret;173}174EXPORT_SYMBOL(pm860x_page_bulk_read);175