cregit-Linux how code gets into the kernel

Release 4.11 drivers/staging/iio/trigger/iio-trig-bfin-timer.c

/*
 * Copyright 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>

#include <asm/gptimers.h>
#include <asm/portmux.h>

#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>

#include "iio-trig-bfin-timer.h"


struct bfin_timer {
	

unsigned short id, bit;
	
unsigned long irqbit;
	
int irq;
	
int pin;
};

/*
 * this covers all hardware timer configurations on
 * all Blackfin derivatives out there today
 */


static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = {
	{TIMER0_id,  TIMER0bit,  TIMER_STATUS_TIMIL0,  IRQ_TIMER0, P_TMR0},
	{TIMER1_id,  TIMER1bit,  TIMER_STATUS_TIMIL1,  IRQ_TIMER1, P_TMR1},
	{TIMER2_id,  TIMER2bit,  TIMER_STATUS_TIMIL2,  IRQ_TIMER2, P_TMR2},
#if (MAX_BLACKFIN_GPTIMERS > 3)
	{TIMER3_id,  TIMER3bit,  TIMER_STATUS_TIMIL3,  IRQ_TIMER3, P_TMR3},
	{TIMER4_id,  TIMER4bit,  TIMER_STATUS_TIMIL4,  IRQ_TIMER4, P_TMR4},
	{TIMER5_id,  TIMER5bit,  TIMER_STATUS_TIMIL5,  IRQ_TIMER5, P_TMR5},
	{TIMER6_id,  TIMER6bit,  TIMER_STATUS_TIMIL6,  IRQ_TIMER6, P_TMR6},
	{TIMER7_id,  TIMER7bit,  TIMER_STATUS_TIMIL7,  IRQ_TIMER7, P_TMR7},
#endif
#if (MAX_BLACKFIN_GPTIMERS > 8)
	{TIMER8_id,  TIMER8bit,  TIMER_STATUS_TIMIL8,  IRQ_TIMER8, P_TMR8},
	{TIMER9_id,  TIMER9bit,  TIMER_STATUS_TIMIL9,  IRQ_TIMER9, P_TMR9},
	{TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10, P_TMR10},
#if (MAX_BLACKFIN_GPTIMERS > 11)
	{TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11, P_TMR11},
#endif
#endif
};


struct bfin_tmr_state {
	
struct iio_trigger	*trig;
	
struct bfin_timer	*t;
	
unsigned int		timer_num;
	
bool			output_enable;
	
unsigned int		duty;
	
int			irq;
};


static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state) { struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); if (get_gptimer_period(st->t->id) == 0) return -EINVAL; if (state) enable_gptimers(st->t->bit); else disable_gptimers(st->t->bit); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Lars-Peter Clausen67100.00%2100.00%
Total67100.00%2100.00%


static ssize_t iio_bfin_tmr_frequency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); unsigned int val; bool enabled; int ret; ret = kstrtouint(buf, 10, &val); if (ret) return ret; if (val > 100000) return -EINVAL; enabled = get_enabled_gptimers() & st->t->bit; if (enabled) disable_gptimers(st->t->bit); if (!val) return count; val = get_sclk() / val; if (val <= 4 || val <= st->duty) return -EINVAL; set_gptimer_period(st->t->id, val); set_gptimer_pwidth(st->t->id, val - st->duty); if (enabled) enable_gptimers(st->t->bit); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich12971.67%114.29%
Lars-Peter Clausen3821.11%457.14%
Jingoo Han126.67%114.29%
Cristina Moraru10.56%114.29%
Total180100.00%7100.00%


static ssize_t iio_bfin_tmr_frequency_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_trigger *trig = to_iio_trigger(dev); struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig); unsigned int period = get_gptimer_period(st->t->id); unsigned long val; if (!period) val = 0; else val = get_sclk() / get_gptimer_period(st->t->id); return sprintf(buf, "%lu\n", val); }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich5054.95%120.00%
Lars-Peter Clausen4043.96%360.00%
Cristina Moraru11.10%120.00%
Total91100.00%5100.00%

static DEVICE_ATTR(frequency, 0644, iio_bfin_tmr_frequency_show, iio_bfin_tmr_frequency_store); static struct attribute *iio_bfin_tmr_trigger_attrs[] = { &dev_attr_frequency.attr, NULL, }; static const struct attribute_group iio_bfin_tmr_trigger_attr_group = { .attrs = iio_bfin_tmr_trigger_attrs, }; static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = { &iio_bfin_tmr_trigger_attr_group, NULL };
static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid) { struct bfin_tmr_state *st = devid; clear_gptimer_intr(st->t->id); iio_trigger_poll(st->trig); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich39100.00%1100.00%
Total39100.00%1100.00%


static int iio_bfin_tmr_get_number(int irq) { int i; for (i = 0; i < MAX_BLACKFIN_GPTIMERS; i++) if (iio_bfin_timer_code[i].irq == irq) return i; return -ENODEV; }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich43100.00%1100.00%
Total43100.00%1100.00%

static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { .owner = THIS_MODULE, .set_trigger_state = iio_bfin_tmr_set_state, };
static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { struct iio_bfin_timer_trigger_pdata *pdata; struct bfin_tmr_state *st; unsigned int config; int ret; st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; st->irq = platform_get_irq(pdev, 0); if (!st->irq) { dev_err(&pdev->dev, "No IRQs specified"); return -ENODEV; } ret = iio_bfin_tmr_get_number(st->irq); if (ret < 0) return ret; st->timer_num = ret; st->t = &iio_bfin_timer_code[st->timer_num]; st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num); if (!st->trig) return -ENOMEM; st->trig->ops = &iio_bfin_tmr_trigger_ops; st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; iio_trigger_set_drvdata(st->trig, st); ret = iio_trigger_register(st->trig); if (ret) goto out; ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr, 0, st->trig->name, st); if (ret) { dev_err(&pdev->dev, "request IRQ-%d failed", st->irq); goto out1; } config = PWM_OUT | PERIOD_CNT | IRQ_ENA; pdata = dev_get_platdata(&pdev->dev); if (pdata && pdata->output_enable) { unsigned long long val; st->output_enable = true; ret = peripheral_request(st->t->pin, st->trig->name); if (ret) goto out_free_irq; val = (unsigned long long)get_sclk() * pdata->duty_ns; do_div(val, NSEC_PER_SEC); st->duty = val; /** * The interrupt will be generated at the end of the period, * since we want the interrupt to be generated at end of the * pulse we invert both polarity and duty cycle, so that the * pulse will be generated directly before the interrupt. */ if (pdata->active_low) config |= PULSE_HI; } else { st->duty = 1; config |= OUT_DIS; } set_gptimer_config(st->t->id, config); dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d", st->timer_num, st->irq); platform_set_drvdata(pdev, st); return 0; out_free_irq: free_irq(st->irq, st); out1: iio_trigger_unregister(st->trig); out: iio_trigger_free(st->trig); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich24257.35%110.00%
Lars-Peter Clausen13531.99%330.00%
Himangi Saraogi194.50%110.00%
Jonathan Cameron143.32%220.00%
Alison Schofield112.61%220.00%
Somya Anand10.24%110.00%
Total422100.00%10100.00%


static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev) { struct bfin_tmr_state *st = platform_get_drvdata(pdev); disable_gptimers(st->t->bit); if (st->output_enable) peripheral_free(st->t->pin); free_irq(st->irq, st); iio_trigger_unregister(st->trig); iio_trigger_free(st->trig); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich5577.46%133.33%
Lars-Peter Clausen1521.13%133.33%
Alison Schofield11.41%133.33%
Total71100.00%3100.00%

static struct platform_driver iio_bfin_tmr_trigger_driver = { .driver = { .name = "iio_bfin_tmr_trigger", }, .probe = iio_bfin_tmr_trigger_probe, .remove = iio_bfin_tmr_trigger_remove, }; module_platform_driver(iio_bfin_tmr_trigger_driver); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("Blackfin system timer based trigger for the iio subsystem"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:iio-trig-bfin-timer");

Overall Contributors

PersonTokensPropCommitsCommitProp
Michael Hennerich87767.00%210.00%
Lars-Peter Clausen34126.05%735.00%
Jonathan Cameron433.28%315.00%
Himangi Saraogi191.45%15.00%
Alison Schofield130.99%315.00%
Jingoo Han120.92%15.00%
Cristina Moraru20.15%15.00%
Somya Anand10.08%15.00%
rishabh hardas10.08%15.00%
Total1309100.00%20100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.