Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: ds1307: factor out century bit handling

The driver has lots of places with chip-specific code what doesn't
necessarily facilitate maintenance.

Let's describe chip-specific differences in century bit handling
in struct chip_desc to improve this.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>

authored by

Heiner Kallweit and committed by
Alexandre Belloni
e48585de 078f3f64

+27 -46
+27 -46
drivers/rtc/rtc-ds1307.c
··· 136 136 unsigned alarm:1; 137 137 u16 nvram_offset; 138 138 u16 nvram_size; 139 + u8 century_reg; 140 + u8 century_enable_bit; 141 + u8 century_bit; 139 142 u16 trickle_charger_reg; 140 143 u8 trickle_charger_setup; 141 144 u8 (*do_trickle_setup)(struct ds1307 *, uint32_t, ··· 154 151 }, 155 152 [ds_1337] = { 156 153 .alarm = 1, 154 + .century_reg = DS1307_REG_MONTH, 155 + .century_bit = DS1337_BIT_CENTURY, 157 156 }, 158 157 [ds_1338] = { 159 158 .nvram_offset = 8, ··· 163 158 }, 164 159 [ds_1339] = { 165 160 .alarm = 1, 161 + .century_reg = DS1307_REG_MONTH, 162 + .century_bit = DS1337_BIT_CENTURY, 166 163 .trickle_charger_reg = 0x10, 167 164 .do_trickle_setup = &do_trickle_setup_ds1339, 168 165 }, 169 166 [ds_1340] = { 167 + .century_reg = DS1307_REG_HOUR, 168 + .century_enable_bit = DS1340_BIT_CENTURY_EN, 169 + .century_bit = DS1340_BIT_CENTURY, 170 170 .trickle_charger_reg = 0x08, 171 171 }, 172 172 [ds_1388] = { ··· 179 169 }, 180 170 [ds_3231] = { 181 171 .alarm = 1, 172 + .century_reg = DS1307_REG_MONTH, 173 + .century_bit = DS1337_BIT_CENTURY, 182 174 }, 183 175 [rx_8130] = { 184 176 .alarm = 1, ··· 340 328 { 341 329 struct ds1307 *ds1307 = dev_get_drvdata(dev); 342 330 int tmp, ret; 331 + const struct chip_desc *chip = &chips[ds1307->type]; 343 332 344 333 /* read the RTC date and time registers all at once */ 345 334 ret = regmap_bulk_read(ds1307->regmap, ds1307->offset, ds1307->regs, 7); ··· 368 355 t->tm_mon = bcd2bin(tmp) - 1; 369 356 t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100; 370 357 371 - #ifdef CONFIG_RTC_DRV_DS1307_CENTURY 372 - switch (ds1307->type) { 373 - case ds_1337: 374 - case ds_1339: 375 - case ds_3231: 376 - if (ds1307->regs[DS1307_REG_MONTH] & DS1337_BIT_CENTURY) 377 - t->tm_year += 100; 378 - break; 379 - case ds_1340: 380 - if (ds1307->regs[DS1307_REG_HOUR] & DS1340_BIT_CENTURY) 381 - t->tm_year += 100; 382 - break; 383 - default: 384 - break; 385 - } 386 - #endif 358 + if (ds1307->regs[chip->century_reg] & chip->century_bit && 359 + IS_ENABLED(CONFIG_RTC_DRV_DS1307_CENTURY)) 360 + t->tm_year += 100; 387 361 388 362 dev_dbg(dev, "%s secs=%d, mins=%d, " 389 363 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", ··· 385 385 static int ds1307_set_time(struct device *dev, struct rtc_time *t) 386 386 { 387 387 struct ds1307 *ds1307 = dev_get_drvdata(dev); 388 + const struct chip_desc *chip = &chips[ds1307->type]; 388 389 int result; 389 390 int tmp; 390 391 u8 *buf = ds1307->regs; ··· 396 395 t->tm_hour, t->tm_mday, 397 396 t->tm_mon, t->tm_year, t->tm_wday); 398 397 399 - #ifdef CONFIG_RTC_DRV_DS1307_CENTURY 400 398 if (t->tm_year < 100) 401 399 return -EINVAL; 402 400 403 - switch (ds1307->type) { 404 - case ds_1337: 405 - case ds_1339: 406 - case ds_3231: 407 - case ds_1340: 408 - if (t->tm_year > 299) 409 - return -EINVAL; 410 - default: 411 - if (t->tm_year > 199) 412 - return -EINVAL; 413 - break; 414 - } 401 + #ifdef CONFIG_RTC_DRV_DS1307_CENTURY 402 + if (t->tm_year > (chip->century_bit ? 299 : 199)) 403 + return -EINVAL; 415 404 #else 416 - if (t->tm_year < 100 || t->tm_year > 199) 405 + if (t->tm_year > 199) 417 406 return -EINVAL; 418 407 #endif 419 408 ··· 418 427 tmp = t->tm_year - 100; 419 428 buf[DS1307_REG_YEAR] = bin2bcd(tmp); 420 429 421 - switch (ds1307->type) { 422 - case ds_1337: 423 - case ds_1339: 424 - case ds_3231: 425 - if (t->tm_year > 199) 426 - buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY; 427 - break; 428 - case ds_1340: 429 - buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN; 430 - if (t->tm_year > 199) 431 - buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY; 432 - break; 433 - case mcp794xx: 430 + if (chip->century_enable_bit) 431 + buf[chip->century_reg] |= chip->century_enable_bit; 432 + if (t->tm_year > 199 && chip->century_bit) 433 + buf[chip->century_reg] |= chip->century_bit; 434 + 435 + if (ds1307->type == mcp794xx) { 434 436 /* 435 437 * these bits were cleared when preparing the date/time 436 438 * values and need to be set again before writing the ··· 431 447 */ 432 448 buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST; 433 449 buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN; 434 - break; 435 - default: 436 - break; 437 450 } 438 451 439 452 dev_dbg(dev, "%s: %7ph\n", "write", buf);