static void pwm_set_speed(struct omap_dm_timer *gpt, int frequency, int duty_cycle) { u32 val; u32 period; struct clk *timer_fclk; /* and you will have an overflow in 1 sec */ /* so, */ /* freq_timer -> 1s */ /* carrier_period -> 1/carrier_freq */ /* => carrier_period = freq_timer/carrier_freq */ timer_fclk = omap_dm_timer_get_fclk(gpt); period = clk_get_rate(timer_fclk) / frequency; val = 0xFFFFFFFF+1-period; omap_dm_timer_set_load(gpt, 1, val); val = 0xFFFFFFFF+1-(period*duty_cycle/256); omap_dm_timer_set_match(gpt, 1, val); /* assume overflow first: no toogle if first trig is match */ omap_dm_timer_write_counter(gpt, 0xFFFFFFFE); }
static void omap_pwm_led_power_on(struct omap_pwm_led *led) { if (led->powered) return; led->powered = 1; /* Select clock */ omap_dm_timer_enable(led->intensity_timer); omap_dm_timer_set_source(led->intensity_timer, OMAP_TIMER_SRC_32_KHZ); /* Turn voltage on */ if (led->pdata->set_power != NULL) led->pdata->set_power(led->pdata, 1); /* Enable PWM timers */ if (led->blink_timer != NULL) { omap_dm_timer_enable(led->blink_timer); omap_dm_timer_set_source(led->blink_timer, OMAP_TIMER_SRC_32_KHZ); omap_pwm_led_set_blink(led); } omap_dm_timer_write_counter(led->intensity_timer, 0xffffffff); omap_dm_timer_set_load(led->intensity_timer, 1, 0xffffff00); }
static void omap_pwm_led_power_on(struct omap_pwm_led *led) { pr_debug("%s%s: \n", PASS1,__func__); printk("!!!!!!!!!!%s the brightness is %d \n",__func__, led->brightness); if (led->powered){ printk("!!!!!!!!!!LED powered, returning \n"); return; } led->powered = 1; /* Select clock */ omap_dm_timer_enable(led->intensity_timer); omap_dm_timer_set_source(led->intensity_timer, OMAP_TIMER_SRC_SYS_CLK); omap_dm_timer_set_prescaler(led->intensity_timer, 0); /* Turn voltage on */ if (led->pdata->set_power != NULL) { printk("!!!!!!!!!!Turn voltage on \n"); led->pdata->set_power(led->pdata, 1); } /* Enable PWM timers */ if (led->blink_timer != NULL) { printk("!!!!!!!!!!Enable PWM timers \n"); omap_dm_timer_enable(led->blink_timer); omap_dm_timer_set_source(led->blink_timer, OMAP_TIMER_SRC_32_KHZ); omap_pwm_led_set_blink(led); } omap_dm_timer_set_load(led->intensity_timer, 1, 0xffffff00); }
static void omap_pwm_led_set_blink(struct omap_pwm_led *led) { pr_debug("%s%s: \n", PASS1,__func__); if (!led->powered) return; if (led->on_period != 0 && led->off_period != 0) { unsigned long load_reg, cmp_reg; load_reg = 32768 * (led->on_period + led->off_period) / 1000; cmp_reg = 32768 * led->on_period / 1000; omap_dm_timer_stop(led->blink_timer); omap_dm_timer_set_load(led->blink_timer, 1, -load_reg); omap_dm_timer_set_match(led->blink_timer, 1, -cmp_reg); omap_dm_timer_set_pwm(led->blink_timer, 1, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); omap_dm_timer_write_counter(led->blink_timer, -2); omap_dm_timer_start(led->blink_timer); } else { omap_dm_timer_set_pwm(led->blink_timer, 1, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); omap_dm_timer_stop(led->blink_timer); } }
static inline int omap_rproc_start(struct rproc *rproc, u64 bootaddr) { struct device *dev = rproc->dev; struct platform_device *pdev = to_platform_device(dev); struct omap_rproc_pdata *pdata = dev->platform_data; struct omap_rproc_timers_info *timers = pdata->timers; struct omap_rproc_priv *rpp = rproc->priv; int i; int ret = 0; if (rproc->secure_mode) { rproc->secure_reset = true; ret = rproc_drm_invoke_service(rproc->secure_mode); if (ret) { dev_err(rproc->dev, "rproc_drm_invoke_service failed " "for secure_enable ret = 0x%x\n", ret); return -ENXIO; } } #ifdef CONFIG_REMOTE_PROC_AUTOSUSPEND ret = _init_pm_flags(rproc); if (ret) return ret; #endif for (i = 0; i < pdata->timers_cnt; i++) { timers[i].odt = omap_dm_timer_request_specific(timers[i].id); if (!timers[i].odt) { ret = -EBUSY; goto out; } omap_dm_timer_set_source(timers[i].odt, OMAP_TIMER_SRC_SYS_CLK); #ifdef CONFIG_REMOTEPROC_WATCHDOG /* GPT 9 & 11 (ipu); GPT 6 (dsp) are used as watchdog timers */ if ((!strcmp(rproc->name, "dsp") && timers[i].id == 6) || (!strcmp(rproc->name, "ipu") && (timers[i].id == DUCATI_WDT_TIMER_1 || timers[i].id == DUCATI_WDT_TIMER_2))) { ret = request_irq(omap_dm_timer_get_irq(timers[i].odt), omap_rproc_watchdog_isr, IRQF_DISABLED, "rproc-wdt", rproc); /* Clean counter, remoteproc proc will set the value */ omap_dm_timer_set_load(timers[i].odt, 0, 0); } #endif } rpp->bootaddr = bootaddr; ret = omap_device_enable(pdev); out: if (ret) { while (i--) { omap_dm_timer_free(timers[i].odt); timers[i].odt = NULL; } } return ret; }
// Initialize the kernel module static int __init gptimer_test_init(void) { int ret = 0; struct clk *gt_fclk; uint32_t gt_rate; printk("gptimer test: starting moudle init\n"); // request a timer (we are asking for ANY open timer, see dmtimer.c for details on how this works) timer_ptr = omap_dm_timer_request(); if(timer_ptr == NULL){ // oops, no timers available printk("gptimer test: No more gp timers available, bailing out\n"); return -1; } // set the clock source to system clock omap_dm_timer_set_source(timer_ptr, OMAP_TIMER_SRC_SYS_CLK); // set prescalar to 1:1 omap_dm_timer_set_prescaler(timer_ptr, 32); // figure out what IRQ our timer triggers timer_irq = omap_dm_timer_get_irq(timer_ptr); // install our IRQ handler for our timer ret = request_irq(timer_irq, timer_irq_handler, IRQF_DISABLED | IRQF_TIMER , "gptimer test", timer_irq_handler); if(ret){ printk("gptimer test: request_irq failed (on irq %d), bailing out\n", timer_irq); return ret; } // get clock rate in Hz gt_fclk = omap_dm_timer_get_fclk(timer_ptr); gt_rate = clk_get_rate(gt_fclk); // set preload, and autoreload // we set it to the clock rate in order to get 1 overflow every second omap_dm_timer_set_load(timer_ptr, 1, 0xFFFFFFFF - gt_rate); // setup timer to trigger our IRQ on the overflow event omap_dm_timer_set_int_enable(timer_ptr, OMAP_TIMER_INT_OVERFLOW); // start the timer! omap_dm_timer_start(timer_ptr); // done! printk("gptimer test: GP Timer initialized and started (%lu Hz, IRQ %d)\n", (long unsigned)gt_rate, timer_irq); // return sucsess return 0; }
// set the pwm frequency static int set_pwm_freq(int freq) { // set preload, and autoreload of the timer // uint32_t period = pwm_data_ptr.timer_rate / (4*freq); uint32_t load = TIMER_MAX+1 - period; omap_dm_timer_set_load(timer_ptr, 1,load); //store the new frequency pwm_data_ptr.frequency = freq; pwm_data_ptr.load = load; return 0; }
/* * For setting the values in registers for varying the duty cycle and time period */ static void vibtonz_GPTimerSetValue(unsigned long load,unsigned long cmp) { unsigned long load_reg, cmp_reg; // printk("[VIBRATOR] %s \n",__func__); load_reg = load; /* For setting the frequency=22.2Khz */ cmp_reg = cmp; /* For varying the duty cycle */ omap_dm_timer_enable(gptimer); omap_dm_timer_set_load(gptimer, 1, -load_reg); omap_dm_timer_set_match(gptimer, 1, -cmp_reg); omap_dm_timer_set_pwm(gptimer, 0, 1,OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); omap_dm_timer_write_counter(gptimer, -2); omap_dm_timer_save_context(gptimer); }
static void backlight_gptimer_update(struct omap_dss_device *dssdev) { struct ltn101al03 *lcd = dev_get_drvdata(&dssdev->dev); omap_dm_timer_set_load(lcd->gptimer, 1, -PWM_DUTY_MAX); omap_dm_timer_set_match(lcd->gptimer, 1, /* 0~25 */ -PWM_DUTY_MAX + lcd->current_brightness); omap_dm_timer_set_pwm(lcd->gptimer, 0, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); omap_dm_timer_enable(lcd->gptimer); omap_dm_timer_write_counter(lcd->gptimer, -2); omap_dm_timer_disable(lcd->gptimer); omap_dm_timer_start(lcd->gptimer); }
static int init_timing_params(struct lirc_rx51 *lirc_rx51) { u32 load, match; load = -(lirc_rx51->fclk_khz * 1000 / lirc_rx51->freq); match = -(lirc_rx51->duty_cycle * -load / 100); omap_dm_timer_set_load(lirc_rx51->pwm_timer, 1, load); omap_dm_timer_set_match(lirc_rx51->pwm_timer, 1, match); omap_dm_timer_write_counter(lirc_rx51->pwm_timer, TIMER_MAX_VALUE - 2); omap_dm_timer_start(lirc_rx51->pwm_timer); omap_dm_timer_set_int_enable(lirc_rx51->pulse_timer, 0); omap_dm_timer_start(lirc_rx51->pulse_timer); lirc_rx51->match = 0; return 0; }
static int sholest_lvibrator_initialization(void) { unsigned long load_reg, cmp_reg; uint32_t timer_rate = 0; int ret = 0; vib_pwm_timer = omap_dm_timer_request_specific(11); if (vib_pwm_timer == NULL) ret = -ENODEV; timer_rate = clk_get_rate(omap_dm_timer_get_fclk(vib_pwm_timer)); load_reg = timer_rate * SHOLEST_LVIBRATOR_PERIOD / 1000000; cmp_reg = timer_rate * (SHOLEST_LVIBRATOR_PERIOD - SHOLEST_LVIBRATOR_DUTY) / 1000000; omap_dm_timer_set_source(vib_pwm_timer, OMAP_TIMER_SRC_32_KHZ); omap_dm_timer_set_load(vib_pwm_timer, 1, -load_reg); omap_dm_timer_set_match(vib_pwm_timer, 1, -cmp_reg); omap_dm_timer_set_pwm(vib_pwm_timer, 0, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE); omap_dm_timer_write_counter(vib_pwm_timer, -2); return 0; }
static void _set_innotech_speed(int id, int frequency, int duty_cycle) { u32 val; u32 period; /* and you will have an overflow in 1 sec */ /* so, */ /* freq_timer -> 1s */ /* carrier_period -> 1/carrier_freq */ /* => carrier_period = freq_timer/carrier_freq */ period = _get_innotech_period(gpt_pwm_list[id].rate, frequency); gpt_pwm_list[id].period = period; val = 0xFFFFFFFF+1-period; omap_dm_timer_set_load(gpt_pwm_list[id].timer, 1, val); val = 0xFFFFFFFF+1-(period*duty_cycle/256); omap_dm_timer_set_match(gpt_pwm_list[id].timer, 1, val); /* set overflow first: pwm will not toggle if first trig is match */ omap_dm_timer_write_counter(gpt_pwm_list[id].timer,0xFFFFFFFE); }
static inline void omap2_gp_timer_start(unsigned long load_val) { omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val); omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW); omap_dm_timer_start(gptimer); }
static void gp_irblaster_init(int carrier_frequency, int no_carrier, unsigned short *pt_cycles_list) { u32 val; u32 period; int min_cycle=0x70000000; /* this min cycle can be set to another minimum: but which value ? */ unsigned short *pt = pt_cycles_list; irb_over = 0; //_select_irb_config(); /* find min cycle */ while ( *pt != 0) { if ( *pt < min_cycle ) min_cycle = *pt; pt++; } /* enable timer clock */ omap_dm_timer_enable(gpt_pwm_list[IRBLASTER_PWM].timer); omap_dm_timer_enable(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer); irq_irblaster_cycles = pt_cycles_list; if ( no_carrier ) { /* set the callback irq function */ _callback_irblaster_timer_interrupt = omap2_irblaster_timer_interrupt_no_carrier; /* set IRBLASTER TIMER PWM */ /* default output is 0 */ /* toogle */ /* trigger on overflow */ omap_dm_timer_set_pwm(gpt_pwm_list[IRBLASTER_PWM].timer,0,1,1); /* set frequency */ period = _get_innotech_period(gpt_pwm_list[IRBLASTER_PWM].rate,carrier_frequency); gpt_pwm_list[IRBLASTER_PWM].period = period; /* at init, nothing to do during few cycles */ /* and let say, during min cycle */ val = 0xFFFFFFFF+1-(period*min_cycle); omap_dm_timer_set_load(gpt_pwm_list[IRBLASTER_PWM].timer, 1, val); /* set IRBLASTER TIMER CTRL */ /* timer freq is the same as the carrier */ period = _get_innotech_period(gpt_pwm_list[IRBLASTER_TIMER_CTRL].rate,carrier_frequency); gpt_pwm_list[IRBLASTER_TIMER_CTRL].period = period; /* at init, nothing to do during few cycles */ /* and let say, during min cycle */ val = 0xFFFFFFFF+1-(period*min_cycle); omap_dm_timer_set_load(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, 1, val); /* prepare the irblaster match condition */ /* irblaster timer run twice time faster than the pwm */ /* so this match is set on the middle of the min cycle time */ val = 0xFFFFFFFF+1-(period*min_cycle/2); omap_dm_timer_set_match(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, 1, val); } else { /* set the callback irq function */ _callback_irblaster_timer_interrupt = omap2_irblaster_timer_interrupt_carrier; /* set IRBLASTER TIMER PWM */ /* default output is 0 */ /* toogle */ /* trigger on match and overflow */ omap_dm_timer_set_pwm(gpt_pwm_list[IRBLASTER_PWM].timer,0,1,2); /* set waveform frequency and duty cycle 1/2 = 128/256 */ _set_innotech_speed(IRBLASTER_PWM,carrier_frequency,128); /* at init, no trigger = default output on pin */ irq_irblaster_pwm_ctrl_reg = omap_dm_timer_read_reg(gpt_pwm_list[IRBLASTER_PWM].timer, OMAP_TIMER_CTRL_REG); irq_irblaster_pwm_ctrl_reg &= ~(3<<10); omap_dm_timer_write_reg(gpt_pwm_list[IRBLASTER_PWM].timer, OMAP_TIMER_CTRL_REG, irq_irblaster_pwm_ctrl_reg); /* make the start readuy */ irq_irblaster_pwm_ctrl_reg |= OMAP_TIMER_CTRL_ST; /* set IRBLASTER TIMER CTRL */ /* timer freq is the same as the carrier */ period = _get_innotech_period(gpt_pwm_list[IRBLASTER_TIMER_CTRL].rate,carrier_frequency); gpt_pwm_list[IRBLASTER_TIMER_CTRL].period = period; /* at init, nothing to do during few cycles */ /* and let say, during min cycle */ val = 0xFFFFFFFF+1-(period*(*irq_irblaster_cycles)); omap_dm_timer_set_load(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, 1, val); /* set the irblaster ctrl timer match condition */ /* to the middle of min cycle */ /* from (end_of_cycle - min_cycle/2) to end_of_cycle, */ /* the timer ctrl irq will pool ...*/ // val = 0xFFFFFFFF+1-(period*min_cycle/2); val = 0xFFFFFFFF+1-_get_best_match_timing_int(min_cycle,gpt_pwm_list[IRBLASTER_TIMER_CTRL].period,gpt_pwm_list[IRBLASTER_TIMER_CTRL].rate); omap_dm_timer_set_match(gpt_pwm_list[IRBLASTER_TIMER_CTRL].timer, 1,val ); } omap_dm_timer_start(gpt_pwm_list[ IRBLASTER_TIMER_CTRL].timer); omap_dm_timer_start(gpt_pwm_list[ IRBLASTER_PWM].timer); }