xs508.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. #include<linux/miscdevice.h>
  2. #include<linux/fs.h>
  3. #include<linux/file.h>
  4. #include<linux/cdev.h>
  5. #include<linux/slab.h>
  6. #include<linux/module.h>
  7. #include<linux/delay.h>
  8. #include<linux/device.h>
  9. #include<linux/platform_device.h>
  10. #include<asm/uaccess.h>
  11. #include<asm/mach-types.h>
  12. #include<linux/regmap.h>
  13. #include<linux/i2c.h>
  14. #include<linux/mutex.h>
  15. #include<linux/i2c.h>
  16. #include<linux/random.h>
  17. #include <linux/uaccess.h>
  18. #include"xs508.h"
  19. #define XS508_SLEEP
  20. //#define XS508_TEST //if open it, you should compile X508_IicTestDrv.c file so that supported XS508_I2C_Handshake()
  21. //extern int XS508_I2C_Handshake(unsigned char *XS508_16B_Ukey,unsigned char *XS508_16B_ID);
  22. extern int XS508_Handshake(unsigned char *XS508_16B_Ukey,unsigned char *XS508_16B_ID);
  23. static struct xs508_private_data *xs508_priv_data;
  24. #ifdef XS508_SLEEP
  25. static bool xs508_sleep = true;
  26. #endif
  27. static int xs508_i2c_write(uint8_t *buf, uint8_t len)
  28. {
  29. struct i2c_msg msg;
  30. struct i2c_client *client = xs508_priv_data->client;
  31. int32_t ret = -1;
  32. int8_t retries = 0;
  33. msg.flags = !I2C_M_RD;
  34. msg.addr = client->addr;
  35. msg.len = len;
  36. msg.buf = buf;
  37. do
  38. {
  39. ret = i2c_transfer(client->adapter, &msg, 1);
  40. if(ret == 1)
  41. {
  42. return 0;
  43. }
  44. retries++;
  45. }while(retries < XS508_I2C_RETRY_COUNT);
  46. //printk(KERN_ALERT "%s timeout\n", __FUNCTION__);
  47. return -1;
  48. }
  49. static int xs508_i2c_read(unsigned char addr, unsigned char *buf, unsigned int len)
  50. {
  51. struct i2c_msg msgs[2];
  52. struct i2c_client *client = xs508_priv_data->client;
  53. int8_t retries = 0;
  54. int32_t ret = -1;
  55. msgs[0].flags = !I2C_M_RD;
  56. msgs[0].addr = client->addr;
  57. msgs[0].len = 1;
  58. msgs[0].buf = &addr;
  59. msgs[1].flags = I2C_M_RD;
  60. msgs[1].addr = client->addr;
  61. msgs[1].len = len;
  62. msgs[1].buf = buf;
  63. do
  64. {
  65. ret = i2c_transfer(client->adapter, msgs, 2);
  66. if(ret == 2)
  67. {
  68. return 0;
  69. }
  70. retries++;
  71. }while(retries < XS508_I2C_RETRY_COUNT);
  72. //printk(KERN_ALERT "%s timeout\n", __FUNCTION__);
  73. return -1;
  74. }
  75. /*********************************************
  76. * return value: 0: write pass
  77. * -1: write error
  78. *********************************************/
  79. int HI2C_write25Byte( unsigned char *buffer)
  80. {
  81. unsigned char buf[26];
  82. buf[0] = 0x07;
  83. memcpy(&buf[1], buffer, 25);
  84. return xs508_i2c_write(buf, 26);
  85. }
  86. /*********************************************
  87. * return value: 0 : write pass
  88. * -1 : write error
  89. *********************************************/
  90. int HI2C_read32Byte(unsigned char *buffer)
  91. {
  92. return xs508_i2c_read(0, buffer, 32);
  93. }
  94. /*********************************************
  95. * Delay ms
  96. *********************************************/
  97. void XS508_delay_ms(int D_TIME)
  98. {
  99. msleep(D_TIME);
  100. }
  101. /*********************************************
  102. * description : get Random
  103. * return value : random value
  104. *********************************************/
  105. int get_xs_srand(void)
  106. {
  107. int rand_num[1];
  108. get_random_bytes(rand_num, sizeof(int));
  109. return rand_num[0];
  110. }
  111. /*********************************************
  112. * XS508G -> stop XS508: release i2c bus, avoid have an effect on other i2c device
  113. * IN: null
  114. * OUT: 0->ok
  115. * -1->I2C WRITE OR READ ERROR
  116. * -2->other error
  117. *********************************************/
  118. #if 0 //if stop, xs508 will not work at next time, so, do not stop
  119. static int xs508_stop_handshake(void)
  120. {
  121. unsigned char wr_data_25_byte[25];
  122. unsigned char rd_data_32_byte[32] = {0};
  123. int i,retry;
  124. wr_data_25_byte[0] = 0xF2;
  125. for(i=1; i<22; i++)
  126. wr_data_25_byte[i] = (char)get_xs_srand();
  127. wr_data_25_byte[22] = 0x5A; //stop cmd: 3 byte 0x5A
  128. wr_data_25_byte[23] = 0x5A;
  129. wr_data_25_byte[24] = 0x5A;
  130. retry = 0;
  131. while(HI2C_write25Byte(wr_data_25_byte))
  132. {
  133. XS508_delay_ms(1);
  134. retry ++;
  135. if(retry > 100)
  136. {
  137. return -1;
  138. }
  139. }
  140. XS508_delay_ms(10);
  141. retry = 0;
  142. while(HI2C_read32Byte(rd_data_32_byte))
  143. {
  144. XS508_delay_ms(1);
  145. retry++;
  146. if (retry > 5)
  147. {
  148. return 0;
  149. }
  150. }
  151. return -2;
  152. }
  153. #endif
  154. #ifdef XS508_SLEEP
  155. /*********************************************
  156. // XS508G -> sleep : when xs508 is sleeping, it will not pass while handshake again, need one more time(twice).
  157. // IN: null
  158. // OUT: 0-> sleep
  159. // -1->I2C WRITE OR READ ERROR
  160. *********************************************/
  161. static int xs508_sleep_handshake(void)
  162. {
  163. unsigned char wr_data_25_byte[25];
  164. int i,retry;
  165. wr_data_25_byte[0] = 0xF2;
  166. for(i=1; i<22; i++)
  167. wr_data_25_byte[i] = (char)get_xs_srand();
  168. wr_data_25_byte[22] = 0xA5; //sleep cmd: 3 byte 0x5A
  169. wr_data_25_byte[23] = 0xA5;
  170. wr_data_25_byte[24] = 0xA5;
  171. retry = 0;
  172. while(HI2C_write25Byte(wr_data_25_byte))
  173. {
  174. XS508_delay_ms(1);
  175. retry ++;
  176. if(retry > 100)
  177. {
  178. return -1;
  179. }
  180. }
  181. return 0;
  182. }
  183. #endif
  184. /******************************************************************************************
  185. *
  186. * return value :
  187. * success : 0
  188. * fail : <0
  189. *
  190. *****************************************************************************************/
  191. #if 0
  192. static int xs508_handshake(void)
  193. {
  194. unsigned char XS508_DAT[16] = {0};
  195. int i1, i2,t1_cnt;
  196. for(t1_cnt=0; t1_cnt<2; t1_cnt++)//retry 2 times if exception
  197. {
  198. #ifdef XS508_TEST
  199. i1=XS508_I2C_Handshake(XS508_KEY, XS508_DAT);
  200. if(i1 != 0)
  201. {
  202. i1 = -1;
  203. continue;
  204. }
  205. XS508_delay_ms(10);
  206. #endif
  207. i1=XS508_Handshake(XS508_KEY, XS508_DAT);
  208. if(i1 == 0)
  209. {
  210. //printk(KERN_ALERT "XS508_Handshake() Pass,ID=" );
  211. for(i2=0; i2<16; i2++)
  212. {
  213. //printk(KERN_ALERT "0x%2x,",XS508_DAT[i2] );
  214. if (XS508_DAT[i2] != XS508_id0[i2])
  215. {
  216. i1 = -5;
  217. break;
  218. }
  219. }
  220. //printk(KERN_ALERT "\n");
  221. if(i1 == 0) //pass
  222. {
  223. printk(KERN_INFO "XS508 verify pass\n" );
  224. goto xs508_handshake_over;
  225. }
  226. }
  227. }
  228. xs508_handshake_over:
  229. for(i2=0; i2<16; i2++)
  230. {
  231. //destroy key and id
  232. //XS508_KEY[i2] += get_xs_srand();
  233. XS508_DAT[i2] += get_xs_srand();
  234. //XS508_id0[i2] += get_xs_srand();
  235. }
  236. return i1;
  237. }
  238. #endif
  239. static int xs508_open(struct inode *inode, struct file *file)
  240. {
  241. if(xs508_priv_data)
  242. {
  243. file->private_data = xs508_priv_data;
  244. //nonseekable_open(inode, file);
  245. }
  246. return 0;
  247. }
  248. static int xs508_release(struct inode *inode, struct file *file)
  249. {
  250. file->private_data = NULL;
  251. #ifdef XS508_SLEEP
  252. //xs508 sleep
  253. if(xs508_sleep_handshake() == 0)
  254. {
  255. xs508_sleep = true;
  256. }
  257. #endif
  258. return 0;
  259. }
  260. static long xs508_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  261. {
  262. unsigned char key[16] = {0};
  263. unsigned char id[16] = {0};
  264. int ret;
  265. switch(cmd)
  266. {
  267. case XS508_IOCTL_CMD_HANDSHAKE_KEY:
  268. if(copy_from_user(key, (unsigned char *)arg, 16))
  269. return -EFAULT;
  270. ret = XS508_Handshake(key, id);
  271. #ifdef XS508_SLEEP
  272. //when xs508 is sleeping, it will not pass while handshake again, need one more time(twice).
  273. if(ret != 0)
  274. {
  275. if(xs508_sleep == true)
  276. {
  277. XS508_Handshake(key, id);
  278. }
  279. }
  280. xs508_sleep = false;
  281. #endif
  282. if(copy_to_user((unsigned char *)arg, &id, 16))
  283. return -EFAULT;
  284. break;
  285. default:
  286. break;
  287. }
  288. return 0;
  289. }
  290. static struct file_operations xs508_fops = {
  291. .owner = THIS_MODULE,
  292. .open = xs508_open,
  293. .release = xs508_release,
  294. .unlocked_ioctl = xs508_ioctl,
  295. };
  296. static struct miscdevice xs508_device = {
  297. .minor = MISC_DYNAMIC_MINOR,
  298. .name = XS508_DEVICE_NAME,
  299. .fops =&xs508_fops,
  300. };
  301. static int xs508_probe(struct i2c_client *client, const struct i2c_device_id *id)
  302. {
  303. struct xs508_private_data *pdata;
  304. int ret = 0;
  305. printk(KERN_DEBUG "%s\n", __FUNCTION__);
  306. pdata = kzalloc(sizeof(struct xs508_private_data), GFP_KERNEL);
  307. if(pdata == NULL)
  308. {
  309. printk(KERN_ERR "err %s, kzmalloc failed\n", __FUNCTION__);
  310. return -ENOMEM;
  311. }
  312. pdata->client = client;
  313. pdata->id = (struct i2c_device_id *)id;
  314. mutex_init(&(pdata->lock));
  315. xs508_priv_data = pdata;
  316. if(misc_register(&xs508_device))
  317. {
  318. ret = -ENOMEM;
  319. goto fail_misc_register;
  320. }
  321. i2c_set_clientdata(client, pdata);
  322. return 0;
  323. fail_misc_register:
  324. mutex_destroy(&pdata->lock);
  325. kfree(pdata);
  326. xs508_priv_data = NULL;
  327. return ret;
  328. }
  329. static int xs508_remove(struct i2c_client *client)
  330. {
  331. struct xs508_private_data *pdata = i2c_get_clientdata(client);
  332. if(pdata == NULL)
  333. {
  334. printk(KERN_ERR "err %s, no device to remove\n",__FUNCTION__);
  335. return -ENODEV;
  336. }
  337. misc_deregister(&xs508_device);
  338. mutex_destroy(&pdata->lock);
  339. kfree(pdata);
  340. i2c_set_clientdata(client, NULL);
  341. xs508_priv_data = NULL;
  342. return 0;
  343. }
  344. #if 0
  345. static void xs508_shutdown(struct i2c_client *client)
  346. {
  347. struct xs508_private_data *pdata = i2c_get_clientdata(client);
  348. if(pdata)
  349. {
  350. }
  351. }
  352. #endif
  353. static const struct i2c_device_id xs508_id[] = {
  354. {XS508_I2C_NAME, 0},
  355. {}
  356. };
  357. static const struct of_device_id xs508_of_match[] = {
  358. { .compatible = "arkmicro,dvr_xs508", },
  359. { }
  360. };
  361. static struct i2c_driver xs805_driver = {
  362. .driver = {
  363. .name = XS508_I2C_NAME,
  364. .of_match_table = xs508_of_match,
  365. },
  366. .id_table = xs508_id,
  367. .probe = xs508_probe,
  368. .remove = xs508_remove,
  369. //.shutdown = xs508_shutdown,
  370. };
  371. module_i2c_driver(xs805_driver);
  372. MODULE_AUTHOR("arkmicro");
  373. MODULE_DESCRIPTION("I2C Encrypt IC XS805 Driver");
  374. MODULE_LICENSE("GPL");