From da3c535934bdb861d07ec69df0302f5073f94676 Mon Sep 17 00:00:00 2001 From: Damien Pageot Date: Wed, 30 Mar 2016 11:26:04 +0200 Subject: [PATCH 14/19] modified: pwm-sunxi.h add PRESCALE_DIV1 to enum sun4i_pwm_prescale --- drivers/misc/pwm-sunxi.h | 395 ++++++++++++++++++++++++----------------------- 1 file changed, 198 insertions(+), 197 deletions(-) diff --git a/drivers/misc/pwm-sunxi.h b/drivers/misc/pwm-sunxi.h index b712b7a..5bf9bdc 100644 --- a/drivers/misc/pwm-sunxi.h +++ b/drivers/misc/pwm-sunxi.h @@ -1,198 +1,199 @@ -/* - * pwm-sunxi.h - * - * (C) Copyright 2013 - * David H. Wilkins - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#define SUN4I_PWM_IOREG_MAX 10 -#define SUN4I_MAX_HARDWARE_PWM_CHANNELS 2 - -/* - * structure that defines the pwm control register - */ - -enum sun4i_pwm_prescale { - PRESCALE_DIV120 = 0x00, /* Divide 24mhz clock by 120 */ - PRESCALE_DIV180 = 0x01, - PRESCALE_DIV240 = 0x02, - PRESCALE_DIV360 = 0x03, - PRESCALE_DIV480 = 0x04, - PRESCALE_INVx05 = 0x05, - PRESCALE_INVx06 = 0x06, - PRESCALE_INVx07 = 0x07, - PRESCALE_DIV12k = 0x08, - PRESCALE_DIV24k = 0x09, - PRESCALE_DIV36k = 0x0a, - PRESCALE_DIV48k = 0x0b, - PRESCALE_DIV72k = 0x0c -}; - - - - -struct sun4i_pwm_ctrl { - enum sun4i_pwm_prescale ch0_prescaler:4; /* ch0 Prescale register - values above */ - unsigned int ch0_en:1; /* chan 0 enable */ - unsigned int ch0_act_state:1; /* chan 0 polarity 0=low, 1=high */ - unsigned int ch0_clk_gating:1; /* Allow clock to run for chan 0 */ - unsigned int ch0_mode:1; /* Mode - 0 = cycle(running), 1=only 1 pulse */ - unsigned int ch0_pulse_start:1; /* Write 1 for mode pulse above to start */ - unsigned int unused1:6; /* The bit skip count is 6 */ - enum sun4i_pwm_prescale ch1_prescaler:4; /* ch1 Prescale register - values above*/ - unsigned int ch1_en:1; /* chan 1 enable */ - unsigned int ch1_act_state:1; /* chan 1 polarity 0=low, 1=high */ - unsigned int ch1_clk_gating:1; /* Allow clock to run for chan 1 */ - unsigned int ch1_mode:1; /* Mode - 0 = cycle(running), 1=only 1 pulse */ - unsigned int ch1_pulse_start:1; /* Write 1 for mode pulse above to start */ - unsigned int unused2:6; /* The bit skip count is 6 */ -}; - - -#define A10CLK 24000000 /* Speed of the clock - 24mhz */ - -#define NO_ENABLE_CHANGE 2 /* Signal to set_pwm_mode to keep the same chan enable bit */ - -#define PWM_CTRL_ENABLE 1 -#define PWM_CTRL_DISABLE 0 - -#define MAX_CYCLES 0x0ffff /* max cycle count possible for period active and entire */ -struct sun4i_pwm_period { -#if MAX_CYCLES > 0x0ff - unsigned int pwm_active_cycles:16; /* duty cycle */ - unsigned int pwm_entire_cycles:16; /* period */ -#else - unsigned int pwm_active_cycles:8; /* duty cycle */ - unsigned int unused1:8; - unsigned int pwm_entire_cycles:8; /* period */ - unsigned int unused2:8; -#endif -}; - - -enum sun4i_ioreg_pin_select { - SELECT_INPUT = 0x00, /* bits for the config registers */ - SELECT_OUTPUT = 0x01, - SELECT_PWM = 0x02, - SELECT_SPI2_CLK = 0x02, - SELECT_I2S_LRCK = 0x02, - SELECT_I2S_BCLK = 0x02 -}; - - -struct sun4i_ioreg_cfg0 { - enum sun4i_ioreg_pin_select pin0_select:4; - enum sun4i_ioreg_pin_select pin1_select:4; - enum sun4i_ioreg_pin_select pin2_select:4; - enum sun4i_ioreg_pin_select pin3_select:4; - enum sun4i_ioreg_pin_select pin4_select:4; - enum sun4i_ioreg_pin_select pin5_select:4; - enum sun4i_ioreg_pin_select pin6_select:4; - enum sun4i_ioreg_pin_select pin7_select:4; -}; - -/* - * another duplicate struct to make the pin names - * look right - */ -struct sun4i_ioreg_cfg1 { - enum sun4i_ioreg_pin_select pin8_select:4; - enum sun4i_ioreg_pin_select pin9_select:4; - enum sun4i_ioreg_pin_select pin10_select:4; - enum sun4i_ioreg_pin_select pin11_select:4; - enum sun4i_ioreg_pin_select pin12_select:4; - enum sun4i_ioreg_pin_select pin13_select:4; - enum sun4i_ioreg_pin_select pin14_select:4; - enum sun4i_ioreg_pin_select pin15_select:4; -}; - - -struct ioreg_pull { - unsigned int pin0:2; - unsigned int pin1:2; - unsigned int pin2:2; - unsigned int pin3:2; - unsigned int pin4:2; - unsigned int pin5:2; - unsigned int pin6:2; - unsigned int pin7:2; - unsigned int pin8:2; - unsigned int pin9:2; - unsigned int pin10:2; - unsigned int pin11:2; - unsigned int pin12:2; - unsigned int pin13:2; - unsigned int pin14:2; - unsigned int pin15:2; -}; - -union ioreg_pull_u { - struct ioreg_pull s; - unsigned int initializer; -}; - - -union sun4i_pwm_ctrl_u { - struct sun4i_pwm_ctrl s; - unsigned int initializer; -}; - -union sun4i_pwm_period_u { - struct sun4i_pwm_period s; - unsigned int initializer; -}; - -union sun4i_ioreg_cfg_u { - struct sun4i_ioreg_cfg0 s0; /* io register config 0 */ - struct sun4i_ioreg_cfg1 s1; /* io register config 1 (just to make pin names look nice) */ - unsigned int initializer; -}; - - - -struct sun4i_pwm_available_channel{ - unsigned int use_count; - void *ctrl_addr; /* Address of the control register */ - void *pin_addr; /* Address of the pin register to change to PWM mode */ - void *period_reg_addr; /* Address of the period register for this chan */ - unsigned int channel; /* Channel number */ - unsigned long period; /* Period in microseconds */ - unsigned long duty; /* duty cycle in microseconds */ - unsigned int duty_percent; /* percentage (drives duty microseconds if set) */ - enum sun4i_pwm_prescale prescale; /* best prescale value computed for period */ - union sun4i_pwm_period_u period_reg; /* period register */ - union sun4i_pwm_ctrl_u ctrl_backup; /* control register backup at init */ - union sun4i_pwm_ctrl_u ctrl_mask; /* mask for ctrl register bit we can change */ - union sun4i_pwm_ctrl_u ctrl_current; /* current control register settings */ - union sun4i_ioreg_cfg_u pin_backup; /* pin backup at init */ - union sun4i_ioreg_cfg_u pin_mask; /* mask of pin settings we can change */ - union sun4i_ioreg_cfg_u pin_current; /* current pin register */ - const char *pin_name; /* name of the pin */ - const char *name; /* name of the pwm device from the pwm i/f */ -}; - -/* - * struct used to implement the hz/khz/ms/us etc for period and duty - */ -struct time_suffix { - char * suffix; /* text suffix */ - unsigned long multiplier; /* multiplier for the entered value */ - bool freq; /* true if a frequency, otherwise a time */ - /* T = 1/f and f = 1/T */ +/* + * pwm-sunxi.h + * + * (C) Copyright 2013 + * David H. Wilkins + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#define SUN4I_PWM_IOREG_MAX 10 +#define SUN4I_MAX_HARDWARE_PWM_CHANNELS 2 + +/* + * structure that defines the pwm control register + */ + +enum sun4i_pwm_prescale { + PRESCALE_DIV120 = 0x00, /* Divide 24mhz clock by 120 */ + PRESCALE_DIV180 = 0x01, + PRESCALE_DIV240 = 0x02, + PRESCALE_DIV360 = 0x03, + PRESCALE_DIV480 = 0x04, + PRESCALE_INVx05 = 0x05, + PRESCALE_INVx06 = 0x06, + PRESCALE_INVx07 = 0x07, + PRESCALE_DIV12k = 0x08, + PRESCALE_DIV24k = 0x09, + PRESCALE_DIV36k = 0x0a, + PRESCALE_DIV48k = 0x0b, + PRESCALE_DIV72k = 0x0c, + PRESCALE_DIV1 = 0x0f /* no prescale exit on A20 */ +}; + + + + +struct sun4i_pwm_ctrl { + enum sun4i_pwm_prescale ch0_prescaler:4; /* ch0 Prescale register - values above */ + unsigned int ch0_en:1; /* chan 0 enable */ + unsigned int ch0_act_state:1; /* chan 0 polarity 0=low, 1=high */ + unsigned int ch0_clk_gating:1; /* Allow clock to run for chan 0 */ + unsigned int ch0_mode:1; /* Mode - 0 = cycle(running), 1=only 1 pulse */ + unsigned int ch0_pulse_start:1; /* Write 1 for mode pulse above to start */ + unsigned int unused1:6; /* The bit skip count is 6 */ + enum sun4i_pwm_prescale ch1_prescaler:4; /* ch1 Prescale register - values above*/ + unsigned int ch1_en:1; /* chan 1 enable */ + unsigned int ch1_act_state:1; /* chan 1 polarity 0=low, 1=high */ + unsigned int ch1_clk_gating:1; /* Allow clock to run for chan 1 */ + unsigned int ch1_mode:1; /* Mode - 0 = cycle(running), 1=only 1 pulse */ + unsigned int ch1_pulse_start:1; /* Write 1 for mode pulse above to start */ + unsigned int unused2:6; /* The bit skip count is 6 */ +}; + + +#define A10CLK 24000000 /* Speed of the clock - 24mhz */ + +#define NO_ENABLE_CHANGE 2 /* Signal to set_pwm_mode to keep the same chan enable bit */ + +#define PWM_CTRL_ENABLE 1 +#define PWM_CTRL_DISABLE 0 + +#define MAX_CYCLES 0x0ffff /* max cycle count possible for period active and entire */ +struct sun4i_pwm_period { +#if MAX_CYCLES > 0x0ff + unsigned int pwm_active_cycles:16; /* duty cycle */ + unsigned int pwm_entire_cycles:16; /* period */ +#else + unsigned int pwm_active_cycles:8; /* duty cycle */ + unsigned int unused1:8; + unsigned int pwm_entire_cycles:8; /* period */ + unsigned int unused2:8; +#endif +}; + + +enum sun4i_ioreg_pin_select { + SELECT_INPUT = 0x00, /* bits for the config registers */ + SELECT_OUTPUT = 0x01, + SELECT_PWM = 0x02, + SELECT_SPI2_CLK = 0x02, + SELECT_I2S_LRCK = 0x02, + SELECT_I2S_BCLK = 0x02 +}; + + +struct sun4i_ioreg_cfg0 { + enum sun4i_ioreg_pin_select pin0_select:4; + enum sun4i_ioreg_pin_select pin1_select:4; + enum sun4i_ioreg_pin_select pin2_select:4; + enum sun4i_ioreg_pin_select pin3_select:4; + enum sun4i_ioreg_pin_select pin4_select:4; + enum sun4i_ioreg_pin_select pin5_select:4; + enum sun4i_ioreg_pin_select pin6_select:4; + enum sun4i_ioreg_pin_select pin7_select:4; +}; + +/* + * another duplicate struct to make the pin names + * look right + */ +struct sun4i_ioreg_cfg1 { + enum sun4i_ioreg_pin_select pin8_select:4; + enum sun4i_ioreg_pin_select pin9_select:4; + enum sun4i_ioreg_pin_select pin10_select:4; + enum sun4i_ioreg_pin_select pin11_select:4; + enum sun4i_ioreg_pin_select pin12_select:4; + enum sun4i_ioreg_pin_select pin13_select:4; + enum sun4i_ioreg_pin_select pin14_select:4; + enum sun4i_ioreg_pin_select pin15_select:4; +}; + + +struct ioreg_pull { + unsigned int pin0:2; + unsigned int pin1:2; + unsigned int pin2:2; + unsigned int pin3:2; + unsigned int pin4:2; + unsigned int pin5:2; + unsigned int pin6:2; + unsigned int pin7:2; + unsigned int pin8:2; + unsigned int pin9:2; + unsigned int pin10:2; + unsigned int pin11:2; + unsigned int pin12:2; + unsigned int pin13:2; + unsigned int pin14:2; + unsigned int pin15:2; +}; + +union ioreg_pull_u { + struct ioreg_pull s; + unsigned int initializer; +}; + + +union sun4i_pwm_ctrl_u { + struct sun4i_pwm_ctrl s; + unsigned int initializer; +}; + +union sun4i_pwm_period_u { + struct sun4i_pwm_period s; + unsigned int initializer; +}; + +union sun4i_ioreg_cfg_u { + struct sun4i_ioreg_cfg0 s0; /* io register config 0 */ + struct sun4i_ioreg_cfg1 s1; /* io register config 1 (just to make pin names look nice) */ + unsigned int initializer; +}; + + + +struct sun4i_pwm_available_channel{ + unsigned int use_count; + void *ctrl_addr; /* Address of the control register */ + void *pin_addr; /* Address of the pin register to change to PWM mode */ + void *period_reg_addr; /* Address of the period register for this chan */ + unsigned int channel; /* Channel number */ + unsigned long period; /* Period in microseconds */ + unsigned long duty; /* duty cycle in microseconds */ + unsigned int duty_percent; /* percentage (drives duty microseconds if set) */ + enum sun4i_pwm_prescale prescale; /* best prescale value computed for period */ + union sun4i_pwm_period_u period_reg; /* period register */ + union sun4i_pwm_ctrl_u ctrl_backup; /* control register backup at init */ + union sun4i_pwm_ctrl_u ctrl_mask; /* mask for ctrl register bit we can change */ + union sun4i_pwm_ctrl_u ctrl_current; /* current control register settings */ + union sun4i_ioreg_cfg_u pin_backup; /* pin backup at init */ + union sun4i_ioreg_cfg_u pin_mask; /* mask of pin settings we can change */ + union sun4i_ioreg_cfg_u pin_current; /* current pin register */ + const char *pin_name; /* name of the pin */ + const char *name; /* name of the pwm device from the pwm i/f */ +}; + +/* + * struct used to implement the hz/khz/ms/us etc for period and duty + */ +struct time_suffix { + char * suffix; /* text suffix */ + unsigned long multiplier; /* multiplier for the entered value */ + bool freq; /* true if a frequency, otherwise a time */ + /* T = 1/f and f = 1/T */ }; -- 1.9.1