brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 3b11bf8 Raw
113 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *  Driver for the NXP SAA7164 PCIe bridge4 *5 *  Copyright (c) 2010-2015 Steven Toth <stoth@kernellabs.com>6 */7 8#include <linux/module.h>9#include <linux/moduleparam.h>10#include <linux/init.h>11#include <linux/delay.h>12#include <linux/io.h>13 14#include "saa7164.h"15 16static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)17{18	struct saa7164_i2c *bus = i2c_adap->algo_data;19	struct saa7164_dev *dev = bus->dev;20	int i, retval = 0;21 22	dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);23 24	for (i = 0 ; i < num; i++) {25		dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x  len = 0x%x\n",26			__func__, num, msgs[i].addr, msgs[i].len);27		if (msgs[i].flags & I2C_M_RD) {28			retval = saa7164_api_i2c_read(bus,29				msgs[i].addr,30				0 /* reglen */,31				NULL /* reg */, msgs[i].len, msgs[i].buf);32		} else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&33			   msgs[i].addr == msgs[i + 1].addr) {34			/* write then read from same address */35 36			retval = saa7164_api_i2c_read(bus, msgs[i].addr,37				msgs[i].len, msgs[i].buf,38				msgs[i+1].len, msgs[i+1].buf39				);40 41			i++;42 43			if (retval < 0)44				goto err;45		} else {46			/* write */47			retval = saa7164_api_i2c_write(bus, msgs[i].addr,48				msgs[i].len, msgs[i].buf);49		}50		if (retval < 0)51			goto err;52	}53	return num;54 55err:56	return retval;57}58 59static u32 saa7164_functionality(struct i2c_adapter *adap)60{61	return I2C_FUNC_I2C;62}63 64static const struct i2c_algorithm saa7164_i2c_algo_template = {65	.master_xfer	= i2c_xfer,66	.functionality	= saa7164_functionality,67};68 69/* ----------------------------------------------------------------------- */70 71static const struct i2c_adapter saa7164_i2c_adap_template = {72	.name              = "saa7164",73	.owner             = THIS_MODULE,74	.algo              = &saa7164_i2c_algo_template,75};76 77static const struct i2c_client saa7164_i2c_client_template = {78	.name	= "saa7164 internal",79};80 81int saa7164_i2c_register(struct saa7164_i2c *bus)82{83	struct saa7164_dev *dev = bus->dev;84 85	dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);86 87	bus->i2c_adap = saa7164_i2c_adap_template;88	bus->i2c_client = saa7164_i2c_client_template;89 90	bus->i2c_adap.dev.parent = &dev->pci->dev;91 92	strscpy(bus->i2c_adap.name, bus->dev->name,93		sizeof(bus->i2c_adap.name));94 95	bus->i2c_adap.algo_data = bus;96	i2c_set_adapdata(&bus->i2c_adap, bus);97	i2c_add_adapter(&bus->i2c_adap);98 99	bus->i2c_client.adapter = &bus->i2c_adap;100 101	if (0 != bus->i2c_rc)102		printk(KERN_ERR "%s: i2c bus %d register FAILED\n",103			dev->name, bus->nr);104 105	return bus->i2c_rc;106}107 108int saa7164_i2c_unregister(struct saa7164_i2c *bus)109{110	i2c_del_adapter(&bus->i2c_adap);111	return 0;112}113