cregit-Linux how code gets into the kernel

Release 4.11 drivers/media/rc/gpio-ir-recv.c

Directory: drivers/media/rc
/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/irq.h>
#include <media/rc-core.h>
#include <linux/platform_data/media/gpio-ir-recv.h>


#define GPIO_IR_DRIVER_NAME	"gpio-rc-recv"

#define GPIO_IR_DEVICE_NAME	"gpio_ir_recv"


struct gpio_rc_dev {
	
struct rc_dev *rcdev;
	
int gpio_nr;
	
bool active_low;
	
struct timer_list flush_timer;
};

#ifdef CONFIG_OF
/*
 * Translate OpenFirmware node properties into platform_data
 */

static int gpio_ir_recv_get_devtree_pdata(struct device *dev, struct gpio_ir_recv_platform_data *pdata) { struct device_node *np = dev->of_node; enum of_gpio_flags flags; int gpio; gpio = of_get_gpio_flags(np, 0, &flags); if (gpio < 0) { if (gpio != -EPROBE_DEFER) dev_err(dev, "Failed to get gpio flags (%d)\n", gpio); return gpio; } pdata->gpio_nr = gpio; pdata->active_low = (flags & OF_GPIO_ACTIVE_LOW); /* probe() takes care of map_name == NULL or allowed_protos == 0 */ pdata->map_name = of_get_property(np, "linux,rc-map-name", NULL); pdata->allowed_protos = 0; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Sebastian Hesselbarth110100.00%1100.00%
Total110100.00%1100.00%

static const struct of_device_id gpio_ir_recv_of_match[] = { { .compatible = "gpio-ir-receiver", }, { }, }; MODULE_DEVICE_TABLE(of, gpio_ir_recv_of_match); #else /* !CONFIG_OF */ #define gpio_ir_recv_get_devtree_pdata(dev, pdata) (-ENOSYS) #endif
static irqreturn_t gpio_ir_recv_irq(int irq, void *dev_id) { struct gpio_rc_dev *gpio_dev = dev_id; int gval; int rc = 0; enum raw_event_type type = IR_SPACE; gval = gpio_get_value(gpio_dev->gpio_nr); if (gval < 0) goto err_get_value; if (gpio_dev->active_low) gval = !gval; if (gval == 1) type = IR_PULSE; rc = ir_raw_event_store_edge(gpio_dev->rcdev, type); if (rc < 0) goto err_get_value; mod_timer(&gpio_dev->flush_timer, jiffies + nsecs_to_jiffies(gpio_dev->rcdev->timeout)); ir_raw_event_handle(gpio_dev->rcdev); err_get_value: return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V10483.87%133.33%
Eric Nelson1915.32%133.33%
Heiko Stübner10.81%133.33%
Total124100.00%3100.00%


static void flush_timer(unsigned long arg) { struct gpio_rc_dev *gpio_dev = (struct gpio_rc_dev *)arg; DEFINE_IR_RAW_EVENT(ev); ev.timeout = true; ev.duration = gpio_dev->rcdev->timeout; ir_raw_event_store(gpio_dev->rcdev, &ev); ir_raw_event_handle(gpio_dev->rcdev); }

Contributors

PersonTokensPropCommitsCommitProp
Eric Nelson60100.00%1100.00%
Total60100.00%1100.00%


static int gpio_ir_recv_probe(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev; struct rc_dev *rcdev; const struct gpio_ir_recv_platform_data *pdata = pdev->dev.platform_data; int rc; if (pdev->dev.of_node) { struct gpio_ir_recv_platform_data *dtpdata = devm_kzalloc(&pdev->dev, sizeof(*dtpdata), GFP_KERNEL); if (!dtpdata) return -ENOMEM; rc = gpio_ir_recv_get_devtree_pdata(&pdev->dev, dtpdata); if (rc) return rc; pdata = dtpdata; } if (!pdata) return -EINVAL; if (pdata->gpio_nr < 0) return -EINVAL; gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL); if (!gpio_dev) return -ENOMEM; rcdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rcdev) { rc = -ENOMEM; goto err_allocate_device; } rcdev->priv = gpio_dev; rcdev->input_name = GPIO_IR_DEVICE_NAME; rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0"; rcdev->input_id.bustype = BUS_HOST; rcdev->input_id.vendor = 0x0001; rcdev->input_id.product = 0x0001; rcdev->input_id.version = 0x0100; rcdev->dev.parent = &pdev->dev; rcdev->driver_name = GPIO_IR_DRIVER_NAME; rcdev->min_timeout = 0; rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT; if (pdata->allowed_protos) rcdev->allowed_protocols = pdata->allowed_protos; else rcdev->allowed_protocols = RC_BIT_ALL_IR_DECODER; rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY; gpio_dev->rcdev = rcdev; gpio_dev->gpio_nr = pdata->gpio_nr; gpio_dev->active_low = pdata->active_low; setup_timer(&gpio_dev->flush_timer, flush_timer, (unsigned long)gpio_dev); rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); if (rc < 0) goto err_gpio_request; rc = gpio_direction_input(pdata->gpio_nr); if (rc < 0) goto err_gpio_direction_input; rc = rc_register_device(rcdev); if (rc < 0) { dev_err(&pdev->dev, "failed to register rc device\n"); goto err_register_rc_device; } platform_set_drvdata(pdev, gpio_dev); rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr), gpio_ir_recv_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "gpio-ir-recv-irq", gpio_dev); if (rc < 0) goto err_request_irq; return 0; err_request_irq: rc_unregister_device(rcdev); rcdev = NULL; err_register_rc_device: err_gpio_direction_input: gpio_free(pdata->gpio_nr); err_gpio_request: rc_free_device(rcdev); err_allocate_device: kfree(gpio_dev); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V28861.54%110.00%
Sebastian Hesselbarth6313.46%110.00%
Benoît Thébaudeau5311.32%220.00%
Eric Nelson367.69%110.00%
Changbin Du142.99%110.00%
David Härdeman61.28%110.00%
Jesper Juhl40.85%110.00%
Andi Shyti30.64%110.00%
Sean Young10.21%110.00%
Total468100.00%10100.00%


static int gpio_ir_recv_remove(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); free_irq(gpio_to_irq(gpio_dev->gpio_nr), gpio_dev); del_timer_sync(&gpio_dev->flush_timer); rc_unregister_device(gpio_dev->rcdev); gpio_free(gpio_dev->gpio_nr); kfree(gpio_dev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V5587.30%150.00%
Eric Nelson812.70%150.00%
Total63100.00%2100.00%

#ifdef CONFIG_PM
static int gpio_ir_recv_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); if (device_may_wakeup(dev)) enable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); else disable_irq(gpio_to_irq(gpio_dev->gpio_nr)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V62100.00%1100.00%
Total62100.00%1100.00%


static int gpio_ir_recv_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct gpio_rc_dev *gpio_dev = platform_get_drvdata(pdev); if (device_may_wakeup(dev)) disable_irq_wake(gpio_to_irq(gpio_dev->gpio_nr)); else enable_irq(gpio_to_irq(gpio_dev->gpio_nr)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V62100.00%1100.00%
Total62100.00%1100.00%

static const struct dev_pm_ops gpio_ir_recv_pm_ops = { .suspend = gpio_ir_recv_suspend, .resume = gpio_ir_recv_resume, }; #endif static struct platform_driver gpio_ir_recv_driver = { .probe = gpio_ir_recv_probe, .remove = gpio_ir_recv_remove, .driver = { .name = GPIO_IR_DRIVER_NAME, .of_match_table = of_match_ptr(gpio_ir_recv_of_match), #ifdef CONFIG_PM .pm = &gpio_ir_recv_pm_ops, #endif }, }; module_platform_driver(gpio_ir_recv_driver); MODULE_DESCRIPTION("GPIO IR Receiver driver"); MODULE_LICENSE("GPL v2");

Overall Contributors

PersonTokensPropCommitsCommitProp
Ravi Kumar V70261.47%16.67%
Sebastian Hesselbarth22519.70%16.67%
Eric Nelson12711.12%16.67%
Benoît Thébaudeau544.73%320.00%
Changbin Du141.23%16.67%
David Härdeman60.53%16.67%
Jesper Juhl40.35%16.67%
Andi Shyti30.26%16.67%
Sachin Kamat30.26%16.67%
Heiko Stübner10.09%16.67%
Sean Young10.09%16.67%
Fabian Frederick10.09%16.67%
Mauro Carvalho Chehab10.09%16.67%
Total1142100.00%15100.00%
Directory: drivers/media/rc
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.