1.kernel/msm-5.4/drivers/gpio/gpio-ctl-tmp.c
1.先定义gpio
int gpio_ctl_power;
2.在gpio_probe方法里获取gpio_ctl_power信息
ret = of_get_named_gpio_flags(np, "gpio-ctl-power", 0, &flags); //该函数返回一个gpio编号。
if (ret < 0) {
printk("%s() Can not read property gpio-ctl-power\n", __FUNCTION__);
} else {
gpio_ctl_power = ret;
ret = devm_gpio_request(&pdev->dev, gpio_ctl_power, "gpio_ctl_power");//申请一个gpio口
if(ret < 0){
printk("%s() devm_gpio_request ggpio-ctl-power request ERROR\n", __FUNCTION__);
}
ret = gpio_direction_output(gpio_ctl_power,0); //在某个GPIO口写上某个值之后,还会把这个端口设置为输出模式
if(ret < 0){
printk("%s() gpio_direction_input gpio-ctl-power set ERROR\n", __FUNCTION__);
}
}
3.定义gpio的操作函数
static long gpio_ctl_tmp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long ret = 0;
return ret;
}
static ssize_t gpio_ctl_tmp_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
//s32 ret = 0;
//s8 cmd[3];
//int write_value1 = 0;
//int write_value2 =0;
//int write_value =0;
//memset(cmd,0,sizeof(cmd));
//ret = copy_from_user(cmd, buf, 2);
printk("gpio_ctl_tmp_write \n");
//if (ret) {
// printk("copy_from_user failed.");
// return -EPERM;
//}
gpio_set_value(gpio_ctl_power,1);
return count;
}
static ssize_t gpio_ctl_tmp_read(struct file *filp, char *buff,
size_t count, loff_t *ppos){
printk(". gpio_eintdemo_read ppos:%d \n", (int)*ppos);
return 0;
}
static const struct file_operations gpio_ctl_tmp_fops = {
.owner= THIS_MODULE,
.write = gpio_ctl_tmp_write,
.read = gpio_ctl_tmp_read,
.unlocked_ioctl = gpio_ctl_tmp_ioctl,
};
static struct miscdevice gpio_ctl_tmp_device =
{
.minor = MISC_DYNAMIC_MINOR,
.name = "gpio-ctl-tmp",
.fops = &gpio_ctl_tmp_fops,
};
4.在module_init对应的方法里注册gpio
ret = misc_register(&gpio_ctl_tmp_device);//注册misc设备,会在/dev下生成相应节点,/dev/gpio-eintdemo
if(ret)
{
printk("you init the driver failed!!");
}
2.修改dts
vendor/qcom/proprietary/devicetree/qcom/yupik-idp-pm7250b.dtsi
tmp_gpios: tmp-gpios{
compatible = "qcom,gpio-ctl-tmp";
gpio-com1-enable = <&tlmm 57 0>;
gpio-msr-enable = <&tlmm 94 0>;
gpio-3V3-enable = <&tlmm 32 0>;
gpio-ctl-power = <&tlmm 33 0>;
status = "okay";
};
3.在rc文件里配置权限
device/qcom/common/rootdir/etc/ueventd.qcom.rc
/dev/gpio-ctl-tmp 0666 system system
device/qcom/lahaina/init.target.rc
chown system system /dev/gpio-ctl-tmp
chmod 0666 /dev/gpio-ctl-tmp
4.配置selinux
device/qcom/sepolicy/generic/private/file_contexts
/dev/gpio-ctl-tmp u:object_r:gpiocontrol_device:s0
5.java层操作gpio
private static final String TMP_GPIO_PATH = "/dev/gpio-ctl-tmp";
private void setTmpGpioCtl(){
writeFileNode("00",TMP_GPIO_PATH);
}
public void shutdown(){
setTmpGpioCtl();
}
private void writeFileNode(String cmd, String filePath){
try {
BufferedWriter bufWriter = null;
bufWriter = new BufferedWriter(new FileWriter(filePath));
bufWriter.write(cmd);
bufWriter.close();
Slog.d("","wtrieValue = "+cmd);
Slog.d("","filePath = "+filePath);
} catch (IOException e) {
e.printStackTrace();
Slog.e("","can't write the " + filePath);
}
}
private void Write2File(File file, String mode) {
//if (!checkFile() || (mode == null))
// return;
Slog.d("", "Write2File,write mode = " + mode);
try {
FileOutputStream fout = new FileOutputStream(file);
PrintWriter pWriter = new PrintWriter(fout);
pWriter.println(mode);
pWriter.flush();
pWriter.close();
fout.close();
} catch (IOException re) {
}
}
private String readFileNode(String filePath){
int size = 0;
String line;
try {
BufferedReader bufReader = null;
bufReader = new BufferedReader(new FileReader(filePath));
while((line=bufReader.readLine())!=null) {
Slog.e("","read line = " + line);
break;
}
bufReader.close();
return line;
}catch (IOException e) {
e.printStackTrace();
Slog.e("","can't read the " + filePath);
}
return "open";
}