栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Hub 驱动

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Hub 驱动

Makefile

KERNEL_DIR=/home/xxx/workspace/RK3399/soap/new_pro/P88/kernel
CURDIR=`pwd`

ARCH=arm64
CROSS_COMPILE=/home/xxx/workspace/RK3399/soap/new_pro/P88/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
export  ARCH  CROSS_COMPILE

obj-m := husb_ala.o
all:
	make -C $(KERNEL_DIR) M=$(CURDIR) modules

.PHONE:clean cp

clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean	

cp:
	sudo  cp  *.ko /home/nfs -rf

 

创建

husb_ala.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define I2C_RETRY_NUMBER        1

struct husb311_ctrl
{
	int gpio;
	int irq;
	struct i2c_client * client;
};

static struct husb311_ctrl * g_husb311_ctrl = NULL;
static DEFINE_MUTEX(i2c_rw_access);




int husb311_i2c_read(struct i2c_client *client, char *writebuf, int writelen, char *readbuf, int readlen)
{
    int ret = 0;
    int i = 0;

    mutex_lock(&i2c_rw_access);

    if (readlen > 0) {
        if (writelen > 0) {
            struct i2c_msg msgs[] = {
                {
                    .addr = client->addr,
                    .flags = 0,
                    .len = writelen,
                    .buf = writebuf,
                },
                {
                    .addr = client->addr,
                    .flags = I2C_M_RD,
                    .len = readlen,
                    .buf = readbuf,
                },
            };
            for (i = 0; i < I2C_RETRY_NUMBER; i++) {
                ret = i2c_transfer(client->adapter, msgs, 2);
                if (ret < 0) {
                    printk(KERN_ERR "[IIC]: i2c_transfer(write) error, ret=%d ,client->addr=0x%x!!", ret,client->addr);
                } else
                    break;
            }
        } else {
            struct i2c_msg msgs[] = {
                {
                    .addr = client->addr,
                    .flags = I2C_M_RD,
                    .len = readlen,
                    .buf = readbuf,
                },
            };
            for (i = 0; i < I2C_RETRY_NUMBER; i++) {
                ret = i2c_transfer(client->adapter, msgs, 1);
                if (ret < 0) {
                    printk(KERN_ERR "[IIC]: i2c_transfer(read) error, ret=%d!!", ret);
                } else
                    break;
            }
        }
    }

    mutex_unlock(&i2c_rw_access);
    return ret;
}

int husb311_i2c_write(struct i2c_client *client, char *writebuf, int writelen)
{
    int ret = 0;
    int i = 0;

    mutex_lock(&i2c_rw_access);
    if (writelen > 0) {
        struct i2c_msg msgs[] = {
            {
                .addr = client->addr,
                .flags = 0,
                .len = writelen,
                .buf = writebuf,
            },
        };
        for (i = 0; i < I2C_RETRY_NUMBER; i++) {
            ret = i2c_transfer(client->adapter, msgs, 1);
            if (ret < 0) {
                printk(KERN_ERR "%s: i2c_transfer(write) error, ret=%d", __func__, ret);
            } else
                break;
        }
    }
    mutex_unlock(&i2c_rw_access);

    return ret;
}

int husb311_i2c_write_reg(struct i2c_client *client, unsigned char regaddr, unsigned char regvalue)
{
    unsigned char buf[2] = {0};
    buf[0] = regaddr;
    buf[1] = regvalue;
    return husb311_i2c_write(client, buf, sizeof(buf));
}

int husb311_i2c_read_reg(struct i2c_client *client, unsigned char regaddr, unsigned char *regvalue)
{
    return husb311_i2c_read(client, ®addr, 1, regvalue, 1);
}






static int husb311_i2c_read_regs(struct i2c_client *client, unsigned char cmd, unsigned char *data, unsigned char data_len)
{
	struct i2c_msg msgs[2];
	int ret = -1;
	unsigned char * buffer = NULL;
	buffer = kzalloc(data_len, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;
	msgs[0].addr = client->addr;
	msgs[0].flags = client->flags;
	msgs[0].len = 1;
	msgs[0].buf = &cmd;

	msgs[1].addr = client->addr;
	msgs[1].flags = client->flags | I2C_M_RD;
	msgs[1].len = data_len;
	msgs[1].buf = buffer;
	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret < 0)
		dev_err(&client->adapter->dev, "i2c read failedn");
	else
		memcpy(data, buffer, data_len);

	kfree(buffer);
	return ret;
}

static int husb311_i2c_write_regs(struct i2c_client *client, unsigned char cmd, unsigned char *data, unsigned char data_len)
{
	struct i2c_msg msgs[1];
	unsigned char *buffer;
	int ret = 0;
	buffer = kzalloc(data_len + 1, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;
	buffer[0] = cmd;
	memcpy(buffer + 1, data, data_len);
	msgs[0].addr = client->addr;
	msgs[0].flags = client->flags;
	msgs[0].len = data_len + 1;
	msgs[0].buf = buffer;
	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
	if (ret < 0)
		dev_err(&client->adapter->dev, "i2c write failedn");

	kfree(buffer);
	return ret;
}

static int husb311_i2c_write_reg(struct i2c_client *client, unsigned char reg, unsigned char value)
{
	unsigned char buf[2] = {''};
	buf[0] = value;
	buf[1] = '';
	return husb311_i2c_write_regs(client, reg, buf, 1);
}

static unsigned char husb311_i2c_read_reg(struct i2c_client *client, unsigned char reg)
{
	int ret = -1;
	unsigned char buf[2] = {''};
	ret = husb311_i2c_read_regs(client, reg, buf, 1);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_read_regs 0x%x failn", reg);
		return -1;
	}
	return buf[0];
}


static int husb311_init(struct i2c_client * client)
{
	int ret = -1;
	//unsigned char value = 0;
	//unsigned char i = 0;
	ret = husb311_i2c_write_reg(client, 0xA0, 0x1);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0xA0 failn");
		return -1;
	}

	for (;;)
	{
		ret = husb311_i2c_read_reg(client, 0x1E, &value);
		if (ret)
		{
			printk(KERN_ERR "time out!!!n");
			return -1;
		}
		if (!(value & (1 << 6)) || (i > 20))
		{
			break;
		}
		msleep(100);
		i++;
	}
	if (i > 20)
	{
		printk(KERN_ERR "time out!!!n");
		return -1;
	}
	ret = husb311_i2c_write_reg(client, 0x10, 0xff);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x10 failn");
		return -1;
	}
	ret = husb311_i2c_write_reg(client, 0x11, 0xff);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x11 failn");
		return -1;
	}
	ret = husb311_i2c_write_reg(client, 0x12, 0x1);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x12 failn");
		return -1;
	}	
	ret = husb311_i2c_write_reg(client, 0x13, 0x0);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x13 failn");
		return -1;
	}	
	ret = husb311_i2c_write_reg(client, 0x14, 0x0);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x14 failn");
		return -1;
	}	
	ret = husb311_i2c_write_reg(client, 0x90, 0x2);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x90 failn");
		return -1;
	}	
	ret = husb311_i2c_write_reg(client, 0x9f, 0x0);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x9f failn");
		return -1;
	}
	ret = husb311_i2c_write_reg(client, 0x1a, 0xa);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x1a failn");
		return -1;
	}

	return 0;
}

static void husb311_func(struct work_struct * work)
{
	unsigned char value = 0;
	int ret = husb311_i2c_read_reg(g_husb311_ctrl->client, 0x10, &value);
	if (ret)
	{
		printk(KERN_ERR "husb311_i2c_write_reg 0x10 failn");
		return;
	}
	if (value &(1 << 0))
	{
		ret = husb311_i2c_read_reg(g_husb311_ctrl->client, 0x1d, &value);
		if (ret)
		{
			printk(KERN_ERR "husb311_i2c_write_reg 0x1d failn");
			return;
		}
		if ((value & (0x3 << 2)) && ((value & (0x3 << 0))==0x0))
		{
			printk(KERN_ERR "CC2 is connect!!!");
		}
		if ((value & (0x3 << 0)) && ((value & (0x3 << 2))==0x0))
		{
			printk(KERN_ERR "CC1 is connect!!!");

		}
		husb311_i2c_write_reg(g_husb311_ctrl->client, 0x10, 0xff);
		husb311_i2c_write_reg(g_husb311_ctrl->client, 0x11, 0xff);
	}
	enable_irq(g_husb311_ctrl->irq);
}
static DECLARE_WORK(husb311_work, husb311_func);

static irqreturn_t husb311_irq_handler(int irq, void *dev_id)
{
	printk(KERN_ERR "------------husb311_irq_handler-------------n");
	schedule_work(&husb311_work);
	disable_irq(g_husb311_ctrl->irq);
	return IRQ_HANDLED;
}

static int husb311_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int ret = -1;
	enum of_gpio_flags irq_flags;
	struct device_node * np = client->dev.of_node;
	printk(KERN_ERR "------------enter probe function-------------n");
	g_husb311_ctrl = kzalloc(sizeof(struct husb311_ctrl), GFP_KERNEL);
	if (!g_husb311_ctrl)
	{
		printk(KERN_ERR "kzalloc failn");
		return -ENOMEM;
	}
	g_husb311_ctrl->client = client;
	g_husb311_ctrl->gpio = of_get_named_gpio_flags(np, "int-n-gpios", 0, (enum of_gpio_flags*)&irq_flags);
	if (g_husb311_ctrl->gpio < 0)
	{
		printk(KERN_ERR "of_get_named_gpio_flags failn");
		goto gpio_err;
	}

	printk(KERN_ERR "gpio:%dn", g_husb311_ctrl->gpio);

	ret = gpio_request(g_husb311_ctrl->gpio, "husb311 irq gpio");
	if (ret < 0)
	{
		printk(KERN_ERR "gpio_request failn");
		goto gpio_request_err;
	}
	g_husb311_ctrl->irq = gpio_to_irq(g_husb311_ctrl->gpio);
	if (g_husb311_ctrl->irq < 0)
	{
		printk(KERN_ERR "gpio_to_irq failn");
		goto to_irq_err;
	}

	printk(KERN_ERR "irq:%dn", g_husb311_ctrl->irq);

	ret = request_irq(g_husb311_ctrl->irq, husb311_irq_handler, irq_flags,
	"husb311_irq", NULL);

	printk(KERN_ERR "request_irq return:%dn", ret);
	if (ret != 0)
	{
		printk(KERN_ERR "request_irq failn");
		goto request_irq_err;
	}

	
	ret = husb311_init(client);
	if (ret < 0)
	{
		printk(KERN_ERR "husb311_init failn");
		goto husb311_init_err;
	}
	return 0;

husb311_init_err:
	free_irq(g_husb311_ctrl->irq, NULL);
request_irq_err:
to_irq_err:
	gpio_free(g_husb311_ctrl->gpio);
gpio_request_err:
gpio_err:
	return -1;
}

static int husb311_remove(struct i2c_client *client)
{
	free_irq(g_husb311_ctrl->irq, NULL);
	gpio_free(g_husb311_ctrl->gpio);
	return 0;
}

static const struct of_device_id husb311_of_match[] = {
	{ .compatible = "husb311" },
	{ },
};

static const struct i2c_device_id husb30x[] = {
	{ "husb311", 0 },
	{}
};
MODULE_DEVICE_TABLE(i2c, husb30x);

static struct i2c_driver husb311_i2c_driver = {
	.driver = {
		.name = "husb311",
		.of_match_table = husb311_of_match,
	},
	.probe    = husb311_probe,
	.remove   = husb311_remove,
	.id_table = husb30x,
};

module_i2c_driver(husb311_i2c_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("linqi");
MODULE_DEscriptION("husb311 usb cc driver");

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/678785.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号