コード例 #1
0
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;
}
コード例 #2
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,&reg,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");
}