@@ -55,6 +55,7 @@ struct atmel_tcb_pwm_chip {
5555 u8 width ;
5656 struct regmap * regmap ;
5757 struct clk * clk ;
58+ struct clk * gclk ;
5859 struct clk * slow_clk ;
5960 struct atmel_tcb_pwm_device * pwms [NPWM ];
6061 struct atmel_tcb_channel bkup ;
@@ -292,7 +293,7 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
292293 struct atmel_tcb_pwm_chip * tcbpwmc = to_tcb_chip (chip );
293294 struct atmel_tcb_pwm_device * tcbpwm = pwm_get_chip_data (pwm );
294295 struct atmel_tcb_pwm_device * atcbpwm = NULL ;
295- int i ;
296+ int i = 0 ;
296297 int slowclk = 0 ;
297298 unsigned period ;
298299 unsigned duty ;
@@ -303,8 +304,11 @@ static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
303304 /*
304305 * Find best clk divisor:
305306 * the smallest divisor which can fulfill the period_ns requirements.
307+ * If there is a gclk, the first divisor is actuallly the gclk selector
306308 */
307- for (i = 0 ; i < ARRAY_SIZE (atmel_tcb_divisors ); ++ i ) {
309+ if (tcbpwmc -> gclk )
310+ i = 1 ;
311+ for (; i < ARRAY_SIZE (atmel_tcb_divisors ); ++ i ) {
308312 if (atmel_tcb_divisors [i ] == 0 ) {
309313 slowclk = i ;
310314 continue ;
@@ -383,9 +387,15 @@ static struct atmel_tcb_config tcb_sam9x5_config = {
383387 .counter_width = 32 ,
384388};
385389
390+ static struct atmel_tcb_config tcb_sama5d2_config = {
391+ .counter_width = 32 ,
392+ .has_gclk = 1 ,
393+ };
394+
386395static const struct of_device_id atmel_tcb_of_match [] = {
387396 { .compatible = "atmel,at91rm9200-tcb" , .data = & tcb_rm9200_config , },
388397 { .compatible = "atmel,at91sam9x5-tcb" , .data = & tcb_sam9x5_config , },
398+ { .compatible = "atmel,sama5d2-tcb" , .data = & tcb_sama5d2_config , },
389399 { /* sentinel */ }
390400};
391401
@@ -396,7 +406,7 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
396406 const struct atmel_tcb_config * config ;
397407 struct device_node * np = pdev -> dev .of_node ;
398408 struct regmap * regmap ;
399- struct clk * clk ;
409+ struct clk * clk , * gclk = NULL ;
400410 struct clk * slow_clk ;
401411 char clk_name [] = "t0_clk" ;
402412 int err ;
@@ -428,6 +438,12 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
428438 match = of_match_node (atmel_tcb_of_match , np -> parent );
429439 config = match -> data ;
430440
441+ if (config -> has_gclk ) {
442+ gclk = of_clk_get_by_name (np -> parent , "gclk" );
443+ if (IS_ERR (gclk ))
444+ return PTR_ERR (gclk );
445+ }
446+
431447 tcbpwm = devm_kzalloc (& pdev -> dev , sizeof (* tcbpwm ), GFP_KERNEL );
432448 if (tcbpwm == NULL ) {
433449 err = - ENOMEM ;
@@ -443,6 +459,7 @@ static int atmel_tcb_pwm_probe(struct platform_device *pdev)
443459 tcbpwm -> channel = channel ;
444460 tcbpwm -> regmap = regmap ;
445461 tcbpwm -> clk = clk ;
462+ tcbpwm -> gclk = gclk ;
446463 tcbpwm -> slow_clk = slow_clk ;
447464 tcbpwm -> width = config -> counter_width ;
448465
0 commit comments