static u8 w1_gpio_set_pullup(void *data, int duration) { struct w1_gpio_msm_platform_data *pdata = data; unsigned long irq_flags; if (pdata->enable_external_pullup) pdata->enable_external_pullup(1); else { spin_lock_irqsave(&w1_gpio_msm_lock, irq_flags); gpio_direction_output(pdata->pin, 1); gpio_set_value_msm(pdata->pin, 1); spin_unlock_irqrestore(&w1_gpio_msm_lock, irq_flags); } return 0; }
static int w1_gpio_msm_remove(struct platform_device *pdev) { struct w1_bus_master *master = platform_get_drvdata(pdev); struct w1_gpio_msm_platform_data *pdata = pdev->dev.platform_data; if (pdata->enable_external_pullup) pdata->enable_external_pullup(0); if (gpio_is_valid(pdata->ext_pullup_enable_pin)) gpio_set_value_msm(pdata->ext_pullup_enable_pin, 0); w1_remove_master_device(master); gpio_free(pdata->pin); kfree(master); return 0; }
static void w1_gpio_write_bit_val(void *data, u8 bit) { struct w1_gpio_msm_platform_data *pdata = data; gpio_set_value_msm(pdata->pin, bit); }
static int w1_gpio_msm_probe(struct platform_device *pdev) { struct w1_bus_master *master; struct w1_gpio_msm_platform_data *pdata; int err; printk(KERN_ERR "\nw1_gpio_msm_probe start\n"); if (of_have_populated_dt()) { err = w1_gpio_msm_probe_dt(pdev); if (err < 0) { dev_err(&pdev->dev, "Failed to parse DT\n"); return err; } } pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No configuration data\n"); return -ENXIO; } master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); if (!master) { dev_err(&pdev->dev, "Out of memory\n"); return -ENOMEM; } spin_lock_init(&w1_gpio_msm_lock); err = gpio_request(pdata->pin, "w1"); if (err) { dev_err(&pdev->dev, "gpio_request (pin) failed\n"); goto free_master; } if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { err = gpio_request_one(pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW, "w1 pullup"); if (err < 0) { dev_err(&pdev->dev, "gpio_request_one " "(ext_pullup_enable_pin) failed\n"); goto free_gpio; } } master->data = pdata; master->read_bit = w1_gpio_read_bit_val; master->touch_bit = w1_gpio_touch_bit; master->read_byte = w1_gpio_read_8; master->write_byte = w1_gpio_write_8; master->read_block = w1_gpio_read_block; master->write_block = w1_gpio_write_block; master->triplet = w1_gpio_triplet; master->reset_bus = w1_gpio_reset_bus; master->set_pullup = w1_gpio_set_pullup; if (pdata->is_open_drain) { gpio_direction_output(pdata->pin, 1); master->write_bit = w1_gpio_write_bit_val; } else { gpio_direction_input(pdata->pin); master->write_bit = w1_gpio_write_bit_dir; } err = w1_add_master_device(master); if (err) { dev_err(&pdev->dev, "w1_add_master device failed\n"); goto free_gpio_ext_pu; } if (pdata->enable_external_pullup) pdata->enable_external_pullup(1); if (gpio_is_valid(pdata->ext_pullup_enable_pin)) gpio_set_value_msm(pdata->ext_pullup_enable_pin, 1); platform_set_drvdata(pdev, master); return 0; free_gpio_ext_pu: if (gpio_is_valid(pdata->ext_pullup_enable_pin)) gpio_free(pdata->ext_pullup_enable_pin); free_gpio: gpio_free(pdata->pin); free_master: kfree(master); return err; }
static int w1_gpio_msm_probe(struct platform_device *pdev) { struct w1_bus_master *master; struct w1_gpio_msm_platform_data *pdata; struct input_dev *input; int err; int ret, irq; int temp_irq; printk(KERN_ERR "\nw1_gpio_msm_probe start\n"); if (of_have_populated_dt()) { err = w1_gpio_msm_probe_dt(pdev); if (err < 0) { dev_err(&pdev->dev, "Failed to parse DT\n"); return err; } } pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "No configuration data\n"); return -ENXIO; } master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); if (!master) { dev_err(&pdev->dev, "Out of memory\n"); return -ENOMEM; } temp_irq = pdata->irq_gpio; if (temp_irq >= 0) { pr_info("%s: IRQ mode is enabled\n", __func__); irq = gpio_to_irq(pdata->irq_gpio); INIT_DELAYED_WORK(&master->w1_irqwork, w1_irqwork); schedule_delayed_work(&master->w1_irqwork, 10); master->irq_mode=true; } /* add for sending uevent */ input = input_allocate_device(); if (!input) { err = -ENODEV; goto free_master; /* need to change*/ } master->input = input; input_set_drvdata(input, master); input->name = "w1"; input->phys = "w1"; input->dev.parent = &pdev->dev; input->evbit[0] |= BIT_MASK(EV_SW); input_set_capability(input, EV_SW, SW_W1); input->open = hall_open; input->close = hall_close; /* Enable auto repeat feature of Linux input subsystem */ __set_bit(EV_REP, input->evbit); err = input_register_device(input); if(err) { dev_err(&pdev->dev, "input_register_device failed!\n"); goto free_input; } spin_lock_init(&w1_gpio_msm_lock); err = gpio_request(pdata->pin, "w1"); if (err) { dev_err(&pdev->dev, "gpio_request (pin) failed\n"); goto free_input; } if (gpio_is_valid(pdata->ext_pullup_enable_pin)) { err = gpio_request_one(pdata->ext_pullup_enable_pin, GPIOF_INIT_LOW, "w1 pullup"); if (err < 0) { dev_err(&pdev->dev, "gpio_request_one " "(ext_pullup_enable_pin) failed\n"); goto free_gpio; } } master->data = pdata; master->read_bit = w1_gpio_read_bit_val; master->touch_bit = w1_gpio_touch_bit; master->read_byte = w1_gpio_read_8; master->write_byte = w1_gpio_write_8; master->read_block = w1_gpio_read_block; master->write_block = w1_gpio_write_block; master->triplet = w1_gpio_triplet; master->reset_bus = w1_gpio_reset_bus; master->set_pullup = w1_gpio_set_pullup; if (pdata->is_open_drain) { gpio_direction_output(pdata->pin, 1); master->write_bit = w1_gpio_write_bit_val; } else { gpio_direction_input(pdata->pin); master->write_bit = w1_gpio_write_bit_dir; } err = w1_add_master_device(master); if (err) { dev_err(&pdev->dev, "w1_add_master device failed\n"); goto free_gpio_ext_pu; } if (master->irq_mode) { REQUEST_IRQ(irq, "w1-detect"); enable_irq_wake(irq); } if (pdata->enable_external_pullup) pdata->enable_external_pullup(1); if (gpio_is_valid(pdata->ext_pullup_enable_pin)) gpio_set_value_msm(pdata->ext_pullup_enable_pin, 1); platform_set_drvdata(pdev, master); return 0; free_gpio_ext_pu: if (gpio_is_valid(pdata->ext_pullup_enable_pin)) gpio_free(pdata->ext_pullup_enable_pin); free_gpio: gpio_free(pdata->pin); free_input: kfree(input); free_master: kfree(master); return err; }