static int hym8563_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct hym8563 *hym8563; int ret; hym8563 = devm_kzalloc(&client->dev, sizeof(*hym8563), GFP_KERNEL); if (!hym8563) return -ENOMEM; hym8563->client = client; i2c_set_clientdata(client, hym8563); device_set_wakeup_capable(&client->dev, true); ret = hym8563_init_device(client); if (ret) { dev_err(&client->dev, "could not init device, %d\n", ret); return ret; } ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, hym8563_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, hym8563); if (ret < 0) { dev_err(&client->dev, "irq %d request failed, %d\n", client->irq, ret); return ret; } /* check state of calendar information */ ret = i2c_smbus_read_byte_data(client, HYM8563_SEC); if (ret < 0) return ret; hym8563->valid = !(ret & HYM8563_SEC_VL); dev_dbg(&client->dev, "rtc information is %s\n", hym8563->valid ? "valid" : "invalid"); hym8563->rtc = devm_rtc_device_register(&client->dev, client->name, &hym8563_rtc_ops, THIS_MODULE); if (IS_ERR(hym8563->rtc)) return PTR_ERR(hym8563->rtc); /* the hym8563 alarm only supports a minute accuracy */ hym8563->rtc->uie_unsupported = 1; #ifdef CONFIG_COMMON_CLK hym8563_clkout_register_clk(hym8563); #endif return 0; }
static int __devinit hym8563_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rc = 0; u8 reg = 0; struct hym8563 *hym8563; struct rtc_device *rtc = NULL; struct rtc_time tm_read, tm = { .tm_wday = 6, .tm_year = 111, .tm_mon = 0, .tm_mday = 1, .tm_hour = 12, .tm_min = 0, .tm_sec = 0, }; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; hym8563 = kzalloc(sizeof(struct hym8563), GFP_KERNEL); if (!hym8563) { return -ENOMEM; } gClient = client; hym8563->client = client; hym8563->alarm.enabled = 0; mutex_init(&hym8563->mutex); wake_lock_init(&hym8563->wake_lock, WAKE_LOCK_SUSPEND, "rtc_hym8563"); i2c_set_clientdata(client, hym8563); hym8563_init_device(client); hym8563_enable_count(client, 0); // check power down hym8563_i2c_read_regs(client,RTC_SEC,®,1); if (reg&0x80) { dev_info(&client->dev, "clock/calendar information is no longer guaranteed\n"); hym8563_set_time(client, &tm); } hym8563_read_datetime(client, &tm_read); //read time from hym8563 if(((tm_read.tm_year < 70) | (tm_read.tm_year > 137 )) | (tm_read.tm_mon == -1) | (rtc_valid_tm(&tm_read) != 0)) //if the hym8563 haven't initialized { hym8563_set_time(client, &tm); //initialize the hym8563 } if(gpio_request(client->irq, "rtc gpio")) { dev_err(&client->dev, "gpio request fail\n"); gpio_free(client->irq); goto exit; } hym8563->irq = gpio_to_irq(client->irq); gpio_pull_updown(client->irq,GPIOPullUp); if (request_threaded_irq(hym8563->irq, NULL, hym8563_wakeup_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->dev.driver->name, hym8563) < 0) { printk("unable to request rtc irq\n"); goto exit; } enable_irq_wake(hym8563->irq); rtc = rtc_device_register(client->name, &client->dev, &hym8563_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) { rc = PTR_ERR(rtc); rtc = NULL; goto exit; } hym8563->rtc = rtc; return 0; exit: if (rtc) rtc_device_unregister(rtc); if (hym8563) { wake_lock_destroy(&hym8563->wake_lock); kfree(hym8563); } return rc; } static int __devexit hym8563_remove(struct i2c_client *client) { struct hym8563 *hym8563 = i2c_get_clientdata(client); if (hym8563->irq > 0) { mutex_lock(&hym8563->mutex); hym8563->exiting = 1; mutex_unlock(&hym8563->mutex); free_irq(hym8563->irq, hym8563); cancel_work_sync(&hym8563->work); } rtc_device_unregister(hym8563->rtc); wake_lock_destroy(&hym8563->wake_lock); kfree(hym8563); hym8563 = NULL; return 0; } void hym8563_shutdown(struct i2c_client * client) { u8 regs[2]; int ret; //disable clkout regs[0] = 0x00; ret=hym8563_i2c_set_regs(client, RTC_CLKOUT, regs, 1); if(ret<0) printk("rtc shutdown is error\n"); }