max92xx加串解串示例代码[可读取四位寄存器地址]

版权声明:本文为博主原创文章,欢迎转载,转载请注明转载地址 https://blog.csdn.net/u012839187/article/details/85234972

主要逻辑函数就是max92xx_i2c_read/write

/*
 * Copyright 2005-2014 Freescale Semiconductor, Inc. All Rights Reserved.
 */

/*
 * The code contained herein is licensed under the GNU General Public
 * License. You may obtain a copy of the GNU General Public License
 * Version 2 or later at the following locations:
 *
 * http://www.opensource.org/licenses/gpl-license.html
 * http://www.gnu.org/copyleft/gpl.html
 */

/*!
 * @file max92xx.c
 *
 * @brief max92xx GMSL1 DSI Serializer/DESerializer driver
 *
 * @ingroup LCD
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
#include <linux/regulator/consumer.h>

static int max92xx_probe(struct i2c_client *adapter,
			 const struct i2c_device_id *id);
static int max92xx_remove(struct i2c_client *client);

static const struct i2c_device_id max92xx_id[] = {
	{"max9283", 0},
	{},
};

MODULE_DEVICE_TABLE(i2c, max92xx_id);

static int init_max92xx(void);

static struct i2c_driver max92xx_i2c_driver = {
	.driver = {
		   .owner = THIS_MODULE,
		   .name = "max9283",
		   },
	.probe = max92xx_probe,
	.remove = max92xx_remove,
	.id_table = max92xx_id,
};

static struct sensor {
	struct i2c_client *i2c_client;
} max92xx_data;

/***********************************************************************
 * I2C transfert.
 ***********************************************************************/

/*******************************************************
Function:
	Read data from the i2c slave device.
Input:
Output:
*********************************************************/
unsigned long max92xx_i2c_read(struct i2c_client *client, int address)
{
    unsigned long rxdata;
    u8 i2c_buf[8];
    u8 i2c_addr[8];
    struct i2c_adapter *adapter;
    adapter = to_i2c_adapter(client->dev.parent);
    i2c_addr[0] = (address & 0xff00)>>8;
    i2c_addr[1] = (address & 0xff);
	struct i2c_msg msgs[2] = {
		{
			.flags	= !I2C_M_RD,
			.addr	= client->addr,
			.len	= 2,
			.buf	= i2c_addr,
		},
		{
			.flags	= I2C_M_RD,
			.addr	= client->addr,
			.len	= 2,
			.buf	= i2c_buf,
		},
	};

		i2c_transfer(client->adapter, msgs, 2);
        //rxdata = (i2c_buf[0]<<8)|i2c_buf[1];
        rxdata = (i2c_buf[0]);
    return rxdata;
}

/*******************************************************
Function:
	Write data to the i2c slave device.
Input:
Output:
*********************************************************/
void max92xx_i2c_write(struct i2c_client *client, int address, int data)
{
    u8 i2c_buf[8]; 
    i2c_buf[0] = (address & 0xff00)>>8;
    i2c_buf[1] = (address & 0xff);
    i2c_buf[2] = data;
   // i2c_buf[3] = (data & 0xff00)>>8;
   // i2c_buf[4] = (data & 0xff);

	struct i2c_msg msg = {
		.flags = !I2C_M_RD,
		.addr = client->addr,
		.len = 3,
		.buf = i2c_buf,
	};

		i2c_transfer(client->adapter, &msg, 1);
	printk("write max92xx addr: 0x%4X  val:0x%4X\n", address, data);
}

/*! Read one register from a max92xx i2c slave device.
 *
 *	@param *reg		register in the device we wish to access.
 *
 *	@return			   0 if success, an error code otherwise.
 */
static inline int max92xx_read_reg(u8 reg)
{
	int val;
	val = i2c_smbus_read_byte_data(max92xx_data.i2c_client, reg);

	return val;

}

/*! Write one register of a max92xx i2c slave device.
 *
 *	@param *reg		register in the device we wish to access.
 *
 *	@return			   0 if success, an error code otherwise.
 */
static int max92xx_write_reg(u8 reg, u8 val)
{
	s32 ret;
	ret = i2c_smbus_write_byte_data(max92xx_data.i2c_client, reg, val);
	if (ret < 0) {
		pr_err("%s:write reg error:reg=%2x,val=%2x\n", __func__,
			reg, val);
	}
	return ret;
}

/*!
 * Maintains the information on the current state of the sensor.
 */
static int max92xx_int(void)
{
	int ret = 0;
    printk("max9283_init start \n");
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0010, 0x91);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0407, 0x20);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x044D, 0x80);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0330, 0x80);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0331, 0x33);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x005B, 0x10);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0053, 0x12);
//  max92xx_i2c_write(max92xx_data.i2c_client, 0x0308, 0x65);
//	max92xx_i2c_write(max92xx_data.i2c_client, 0x0332, 0x4E);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0333, 0xE4);
//  max92xx_i2c_write(max92xx_data.i2c_client, 0x0311, 0x50);
	max92xx_i2c_write(max92xx_data.i2c_client, 0x0415, 0x01);
    printk("max9283_init end \n");
	pr_debug("%s\n",__func__);
	return ret;
}

static int max92xx_pattern_init(void)
{
//test
	int ret = 0;
	pr_debug("%s\n",__func__);
	//ret |= max92xx_write_reg(0x09 ,0x00);
	return ret;
}

static int init_max92xx(void)
{
#if 1
	return max92xx_int();
#else
	return max92xx_pattern_init();
#endif
}

static bool check_chip_existence(void)
{
/*	if((max92xx_read_reg(0x0) == 0x35)&&
		(max92xx_read_reg(0x1) == 0x38)&&
		(max92xx_read_reg(0x2) == 0x49))
		return true;
	return false;
    */
		return true;
}

int max9283_enable(int enable)
{
	int ret = 0;
	if (enable)
	{
		pr_debug("%s enter enable %d \n", __func__,enable);
		ret |= max92xx_write_reg(0x09, 0x01);
		ret |= max92xx_write_reg(0x0D, 0x01);
		msleep(10);
		ret |= max92xx_write_reg(0xE5, 0xFF);
		ret |= max92xx_write_reg(0xE0, 0x01);
		ret |= max92xx_write_reg(0xE1, 0xFF);
	}
	else
	{
		pr_debug("%s enter disable %d \n", __func__,enable);
		ret |= max92xx_write_reg(0x0D, 0x00);
	}
	return ret;
}
EXPORT_SYMBOL(max9283_enable);

static ssize_t max92xx_reg_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int len;
	u16 i;
	len = sprintf(buf, "result\n");
	for(i = 0; i <= 0x4ff; i++){
		msleep(10);
		pr_err("runtime_max92xx: 0x%4X = 0x%2X\n", i, max92xx_i2c_read(max92xx_data.i2c_client,i));
	}

	return len;
}

static ssize_t max92xx_reg_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int len;
	int addr, val;
	len = sscanf(buf, "0x%x 0x%x", (unsigned int *)&addr ,(unsigned int *)&val);
	pr_info("write max92xx addr: 0x%2X\tval:0x%2X\n", addr, val);
	max92xx_write_reg(addr, val);
	return count;
}

static ssize_t max92xx_reg_single_store(struct device *dev,
				struct device_attribute *attr, const char *buf, size_t count)
{
	int len;
	int addr;
	len = sscanf(buf, "0x%x", (unsigned int *)&addr);
	pr_info("read max92xx addr: 0x%2X\tval:0x%2X\n", addr, max92xx_read_reg(addr));
	return count;
}

static ssize_t max92xx_i2c_read_store(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int len;
	int addr;
	len = sscanf(buf, "0x%x", (unsigned int *)&addr);
	printk("read max92xx addr: 0x%4X  val:0x%4X\n", addr, max92xx_i2c_read(max92xx_data.i2c_client, addr));
}

static ssize_t max92xx_i2c_write_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int len;
	int addr, val;
	len = sscanf(buf, "0x%x 0x%x", (unsigned int *)&addr ,(unsigned int *)&val);
	printk("write max92xx addr: 0x%4X  val:0x%4X\n", addr, val);
	max92xx_i2c_write(max92xx_data.i2c_client, addr, val);
	return count;
}

static DEVICE_ATTR(reg, (0644), max92xx_reg_show, max92xx_reg_store);
static DEVICE_ATTR(reg_single, (0644), NULL, max92xx_reg_single_store);
static DEVICE_ATTR(max92xx_read_reg, (0644), NULL, max92xx_i2c_read_store);
static DEVICE_ATTR(max92xx_write_reg, (0644), NULL, max92xx_i2c_write_store);

static struct attribute *max92xx_attributes[] = {
	&dev_attr_reg.attr,
	&dev_attr_reg_single.attr,
    &dev_attr_max92xx_read_reg.attr,
    &dev_attr_max92xx_write_reg.attr,
	NULL
};


static struct attribute_group max92xx_attr_group = {
	.attrs = max92xx_attributes,
};

static int max92xx_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int retval = 0;
    int enable_gpio;
	static struct kobject *max92xx_kobj;
	max92xx_data.i2c_client = client;
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "I2C not supported\n");
		return -ENODEV;
	}
	if(check_chip_existence() == false){
		pr_err("%s:no chip is found\n", __func__);
		return -EIO;
	}else{
		pr_info("%s:chip is found\n", __func__);
	}

    printk("max9283 enable gpio_requeset\n");
    enable_gpio = of_get_named_gpio(client->dev.of_node, "qcom,max9283_enable-gpio",0); 
    if (enable_gpio < 0)
        printk("max9283 enable gpio is not available \n");
    retval = gpio_request(enable_gpio,"max9283_enable");
    if(0 != retval) {
        printk("gpio request %d failed.\n",enable_gpio);
    }
    gpio_direction_output(enable_gpio,1);
    msleep(1000);

	retval = init_max92xx();
	if(retval != 0)
		return -EIO;

	max92xx_kobj = kobject_create_and_add("max9283", kernel_kobj);
	if(!max92xx_kobj)
		return -ENOMEM;

	retval = sysfs_create_group(max92xx_kobj, &max92xx_attr_group);
	if (retval) {
		kobject_put(max92xx_kobj);
	}

	return 0;
}

static int max92xx_remove(struct i2c_client *client)
{
	return 0;
}

/*!
 * max92xx init function.
 * Called on insmod.
 *
 * @return	  Error code indicating success or failure.
 */
static __init int max92xx_init(void)
{
	u8 err = 0;

	/* Tells the i2c driver what functions to call for this driver. */
	err = i2c_add_driver(&max92xx_i2c_driver);
	if (err != 0)
		pr_err("%s:driver registration failed, error=%d\n",
			__func__, err);

	return err;
}

/*!
 * max92xx cleanup function.
 * Called on rmmod.
 *
 * @return	 Error code indicating success or failure.
 */
static void __exit max92xx_clean(void)
{
	i2c_del_driver(&max92xx_i2c_driver);
}

module_init(max92xx_init);
module_exit(max92xx_clean);

MODULE_AUTHOR("PATEO maze");
MODULE_DESCRIPTION("max92xx GMSL1 DSI Serializer/DESerializer driver");
MODULE_LICENSE("GPL");

猜你喜欢

转载自blog.csdn.net/u012839187/article/details/85234972
今日推荐