| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Seiko Instruments S-35390A RTC Driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (c) 2007 Byron Bradley |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or |
|---|
| 7 | | - * modify it under the terms of the GNU General Public License |
|---|
| 8 | | - * as published by the Free Software Foundation; either version |
|---|
| 9 | | - * 2 of the License, or (at your option) any later version. |
|---|
| 10 | 6 | */ |
|---|
| 11 | 7 | |
|---|
| 12 | 8 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 36 | 32 | #define S35390A_ALRM_BYTE_MINS 2 |
|---|
| 37 | 33 | |
|---|
| 38 | 34 | /* flags for STATUS1 */ |
|---|
| 39 | | -#define S35390A_FLAG_POC 0x01 |
|---|
| 40 | | -#define S35390A_FLAG_BLD 0x02 |
|---|
| 41 | | -#define S35390A_FLAG_INT2 0x04 |
|---|
| 42 | | -#define S35390A_FLAG_24H 0x40 |
|---|
| 43 | | -#define S35390A_FLAG_RESET 0x80 |
|---|
| 35 | +#define S35390A_FLAG_POC BIT(0) |
|---|
| 36 | +#define S35390A_FLAG_BLD BIT(1) |
|---|
| 37 | +#define S35390A_FLAG_INT2 BIT(2) |
|---|
| 38 | +#define S35390A_FLAG_24H BIT(6) |
|---|
| 39 | +#define S35390A_FLAG_RESET BIT(7) |
|---|
| 44 | 40 | |
|---|
| 45 | 41 | /* flag for STATUS2 */ |
|---|
| 46 | | -#define S35390A_FLAG_TEST 0x01 |
|---|
| 42 | +#define S35390A_FLAG_TEST BIT(0) |
|---|
| 47 | 43 | |
|---|
| 48 | | -#define S35390A_INT2_MODE_MASK 0xF0 |
|---|
| 49 | | - |
|---|
| 44 | +/* INT2 pin output mode */ |
|---|
| 45 | +#define S35390A_INT2_MODE_MASK 0x0E |
|---|
| 50 | 46 | #define S35390A_INT2_MODE_NOINTR 0x00 |
|---|
| 51 | | -#define S35390A_INT2_MODE_FREQ 0x10 |
|---|
| 52 | | -#define S35390A_INT2_MODE_ALARM 0x40 |
|---|
| 53 | | -#define S35390A_INT2_MODE_PMIN_EDG 0x20 |
|---|
| 47 | +#define S35390A_INT2_MODE_ALARM BIT(1) /* INT2AE */ |
|---|
| 48 | +#define S35390A_INT2_MODE_PMIN_EDG BIT(2) /* INT2ME */ |
|---|
| 49 | +#define S35390A_INT2_MODE_FREQ BIT(3) /* INT2FE */ |
|---|
| 50 | +#define S35390A_INT2_MODE_PMIN (BIT(3) | BIT(2)) /* INT2FE | INT2ME */ |
|---|
| 54 | 51 | |
|---|
| 55 | 52 | static const struct i2c_device_id s35390a_id[] = { |
|---|
| 56 | 53 | { "s35390a", 0 }, |
|---|
| .. | .. |
|---|
| 288 | 285 | alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, |
|---|
| 289 | 286 | alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); |
|---|
| 290 | 287 | |
|---|
| 288 | + if (alm->time.tm_sec != 0) |
|---|
| 289 | + dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n"); |
|---|
| 290 | + |
|---|
| 291 | 291 | /* disable interrupt (which deasserts the irq line) */ |
|---|
| 292 | 292 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); |
|---|
| 293 | 293 | if (err < 0) |
|---|
| .. | .. |
|---|
| 302 | 302 | sts = S35390A_INT2_MODE_ALARM; |
|---|
| 303 | 303 | else |
|---|
| 304 | 304 | sts = S35390A_INT2_MODE_NOINTR; |
|---|
| 305 | | - |
|---|
| 306 | | - /* This chip expects the bits of each byte to be in reverse order */ |
|---|
| 307 | | - sts = bitrev8(sts); |
|---|
| 308 | 305 | |
|---|
| 309 | 306 | /* set interupt mode*/ |
|---|
| 310 | 307 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); |
|---|
| .. | .. |
|---|
| 343 | 340 | if (err < 0) |
|---|
| 344 | 341 | return err; |
|---|
| 345 | 342 | |
|---|
| 346 | | - if ((bitrev8(sts) & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { |
|---|
| 343 | + if ((sts & S35390A_INT2_MODE_MASK) != S35390A_INT2_MODE_ALARM) { |
|---|
| 347 | 344 | /* |
|---|
| 348 | 345 | * When the alarm isn't enabled, the register to configure |
|---|
| 349 | 346 | * the alarm time isn't accessible. |
|---|
| .. | .. |
|---|
| 426 | 423 | .ioctl = s35390a_rtc_ioctl, |
|---|
| 427 | 424 | }; |
|---|
| 428 | 425 | |
|---|
| 429 | | -static struct i2c_driver s35390a_driver; |
|---|
| 430 | | - |
|---|
| 431 | 426 | static int s35390a_probe(struct i2c_client *client, |
|---|
| 432 | 427 | const struct i2c_device_id *id) |
|---|
| 433 | 428 | { |
|---|
| .. | .. |
|---|
| 435 | 430 | unsigned int i; |
|---|
| 436 | 431 | struct s35390a *s35390a; |
|---|
| 437 | 432 | char buf, status1; |
|---|
| 433 | + struct device *dev = &client->dev; |
|---|
| 438 | 434 | |
|---|
| 439 | | - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
|---|
| 440 | | - err = -ENODEV; |
|---|
| 441 | | - goto exit; |
|---|
| 442 | | - } |
|---|
| 435 | + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) |
|---|
| 436 | + return -ENODEV; |
|---|
| 443 | 437 | |
|---|
| 444 | | - s35390a = devm_kzalloc(&client->dev, sizeof(struct s35390a), |
|---|
| 445 | | - GFP_KERNEL); |
|---|
| 446 | | - if (!s35390a) { |
|---|
| 447 | | - err = -ENOMEM; |
|---|
| 448 | | - goto exit; |
|---|
| 449 | | - } |
|---|
| 438 | + s35390a = devm_kzalloc(dev, sizeof(struct s35390a), GFP_KERNEL); |
|---|
| 439 | + if (!s35390a) |
|---|
| 440 | + return -ENOMEM; |
|---|
| 450 | 441 | |
|---|
| 451 | 442 | s35390a->client[0] = client; |
|---|
| 452 | 443 | i2c_set_clientdata(client, s35390a); |
|---|
| 453 | 444 | |
|---|
| 454 | 445 | /* This chip uses multiple addresses, use dummy devices for them */ |
|---|
| 455 | 446 | for (i = 1; i < 8; ++i) { |
|---|
| 456 | | - s35390a->client[i] = i2c_new_dummy(client->adapter, |
|---|
| 457 | | - client->addr + i); |
|---|
| 458 | | - if (!s35390a->client[i]) { |
|---|
| 459 | | - dev_err(&client->dev, "Address %02x unavailable\n", |
|---|
| 460 | | - client->addr + i); |
|---|
| 461 | | - err = -EBUSY; |
|---|
| 462 | | - goto exit_dummy; |
|---|
| 447 | + s35390a->client[i] = devm_i2c_new_dummy_device(dev, |
|---|
| 448 | + client->adapter, |
|---|
| 449 | + client->addr + i); |
|---|
| 450 | + if (IS_ERR(s35390a->client[i])) { |
|---|
| 451 | + dev_err(dev, "Address %02x unavailable\n", |
|---|
| 452 | + client->addr + i); |
|---|
| 453 | + return PTR_ERR(s35390a->client[i]); |
|---|
| 463 | 454 | } |
|---|
| 464 | 455 | } |
|---|
| 465 | 456 | |
|---|
| 457 | + s35390a->rtc = devm_rtc_allocate_device(dev); |
|---|
| 458 | + if (IS_ERR(s35390a->rtc)) |
|---|
| 459 | + return PTR_ERR(s35390a->rtc); |
|---|
| 460 | + |
|---|
| 466 | 461 | err_read = s35390a_read_status(s35390a, &status1); |
|---|
| 467 | 462 | if (err_read < 0) { |
|---|
| 468 | | - err = err_read; |
|---|
| 469 | | - dev_err(&client->dev, "error resetting chip\n"); |
|---|
| 470 | | - goto exit_dummy; |
|---|
| 463 | + dev_err(dev, "error resetting chip\n"); |
|---|
| 464 | + return err_read; |
|---|
| 471 | 465 | } |
|---|
| 472 | 466 | |
|---|
| 473 | 467 | if (status1 & S35390A_FLAG_24H) |
|---|
| .. | .. |
|---|
| 480 | 474 | buf = 0; |
|---|
| 481 | 475 | err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &buf, 1); |
|---|
| 482 | 476 | if (err < 0) { |
|---|
| 483 | | - dev_err(&client->dev, "error disabling alarm"); |
|---|
| 484 | | - goto exit_dummy; |
|---|
| 477 | + dev_err(dev, "error disabling alarm"); |
|---|
| 478 | + return err; |
|---|
| 485 | 479 | } |
|---|
| 486 | 480 | } else { |
|---|
| 487 | 481 | err = s35390a_disable_test_mode(s35390a); |
|---|
| 488 | 482 | if (err < 0) { |
|---|
| 489 | | - dev_err(&client->dev, "error disabling test mode\n"); |
|---|
| 490 | | - goto exit_dummy; |
|---|
| 483 | + dev_err(dev, "error disabling test mode\n"); |
|---|
| 484 | + return err; |
|---|
| 491 | 485 | } |
|---|
| 492 | 486 | } |
|---|
| 493 | 487 | |
|---|
| 494 | | - device_set_wakeup_capable(&client->dev, 1); |
|---|
| 488 | + device_set_wakeup_capable(dev, 1); |
|---|
| 495 | 489 | |
|---|
| 496 | | - s35390a->rtc = devm_rtc_device_register(&client->dev, |
|---|
| 497 | | - s35390a_driver.driver.name, |
|---|
| 498 | | - &s35390a_rtc_ops, THIS_MODULE); |
|---|
| 490 | + s35390a->rtc->ops = &s35390a_rtc_ops; |
|---|
| 491 | + s35390a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; |
|---|
| 492 | + s35390a->rtc->range_max = RTC_TIMESTAMP_END_2099; |
|---|
| 499 | 493 | |
|---|
| 500 | | - if (IS_ERR(s35390a->rtc)) { |
|---|
| 501 | | - err = PTR_ERR(s35390a->rtc); |
|---|
| 502 | | - goto exit_dummy; |
|---|
| 503 | | - } |
|---|
| 494 | + /* supports per-minute alarms only, therefore set uie_unsupported */ |
|---|
| 495 | + s35390a->rtc->uie_unsupported = 1; |
|---|
| 504 | 496 | |
|---|
| 505 | 497 | if (status1 & S35390A_FLAG_INT2) |
|---|
| 506 | 498 | rtc_update_irq(s35390a->rtc, 1, RTC_AF); |
|---|
| 507 | 499 | |
|---|
| 508 | | - return 0; |
|---|
| 509 | | - |
|---|
| 510 | | -exit_dummy: |
|---|
| 511 | | - for (i = 1; i < 8; ++i) |
|---|
| 512 | | - if (s35390a->client[i]) |
|---|
| 513 | | - i2c_unregister_device(s35390a->client[i]); |
|---|
| 514 | | - |
|---|
| 515 | | -exit: |
|---|
| 516 | | - return err; |
|---|
| 517 | | -} |
|---|
| 518 | | - |
|---|
| 519 | | -static int s35390a_remove(struct i2c_client *client) |
|---|
| 520 | | -{ |
|---|
| 521 | | - unsigned int i; |
|---|
| 522 | | - struct s35390a *s35390a = i2c_get_clientdata(client); |
|---|
| 523 | | - |
|---|
| 524 | | - for (i = 1; i < 8; ++i) |
|---|
| 525 | | - if (s35390a->client[i]) |
|---|
| 526 | | - i2c_unregister_device(s35390a->client[i]); |
|---|
| 527 | | - |
|---|
| 528 | | - return 0; |
|---|
| 500 | + return rtc_register_device(s35390a->rtc); |
|---|
| 529 | 501 | } |
|---|
| 530 | 502 | |
|---|
| 531 | 503 | static struct i2c_driver s35390a_driver = { |
|---|
| .. | .. |
|---|
| 534 | 506 | .of_match_table = of_match_ptr(s35390a_of_match), |
|---|
| 535 | 507 | }, |
|---|
| 536 | 508 | .probe = s35390a_probe, |
|---|
| 537 | | - .remove = s35390a_remove, |
|---|
| 538 | 509 | .id_table = s35390a_id, |
|---|
| 539 | 510 | }; |
|---|
| 540 | 511 | |
|---|