35
35
UAC_RATE_CTRL ,
36
36
};
37
37
38
+ #define CLK_PPM_GROUP_SIZE 20
39
+
38
40
/* Runtime data params for one stream */
39
41
struct uac_rtd_params {
40
42
struct snd_uac_chip * uac ; /* parent chip */
@@ -1278,6 +1280,10 @@ static void g_audio_work(struct work_struct *data)
1278
1280
snprintf (str , sizeof (str ), "VOLUME=0x%hx" , prm -> volume );
1279
1281
uac_event [2 ] = str ;
1280
1282
break ;
1283
+ case SET_AUDIO_CLK :
1284
+ uac_event [0 ] = "USB_STATE=SET_AUDIO_CLK" ;
1285
+ snprintf (str , sizeof (str ), "PPM=%d" , audio -> params .ppm );
1286
+ uac_event [1 ] = str ;
1281
1287
default :
1282
1288
break ;
1283
1289
}
@@ -1290,6 +1296,107 @@ static void g_audio_work(struct work_struct *data)
1290
1296
}
1291
1297
}
1292
1298
1299
+ static void ppm_calculate_work (struct work_struct * data )
1300
+ {
1301
+ struct g_audio * g_audio = container_of (data , struct g_audio ,
1302
+ ppm_work .work );
1303
+ struct usb_gadget * gadget = g_audio -> gadget ;
1304
+ uint32_t frame_number , fn_msec , clk_msec ;
1305
+ struct frame_number_data * fn = g_audio -> fn ;
1306
+ uint64_t time_now , time_msec_tmp ;
1307
+ int32_t ppm ;
1308
+ static int32_t ppms [CLK_PPM_GROUP_SIZE ];
1309
+ static int32_t ppm_sum ;
1310
+ int32_t cnt = fn -> second % CLK_PPM_GROUP_SIZE ;
1311
+
1312
+ time_now = ktime_get_raw ();
1313
+ frame_number = gadget -> ops -> get_frame (gadget );
1314
+
1315
+ if (g_audio -> fn -> time_last &&
1316
+ time_now - g_audio -> fn -> time_last > 1500000000ULL )
1317
+ dev_warn (g_audio -> device , "PPM work scheduled too slow!\n" );
1318
+
1319
+ g_audio -> fn -> time_last = time_now ;
1320
+
1321
+ /*
1322
+ * If usb is disconnected, the controller will not receive the
1323
+ * SoF signal and frame number will be invalid. Because we can't
1324
+ * get accurate time of disconnect and whether the gadget will be
1325
+ * plugged into the same host next time or not. We must clear all
1326
+ * statistics.
1327
+ */
1328
+ if (gadget -> state != USB_STATE_CONFIGURED ) {
1329
+ memset (g_audio -> fn , 0 , sizeof (* g_audio -> fn ));
1330
+ dev_dbg (g_audio -> device , "Disconnect. frame number is cleared\n" );
1331
+ goto out ;
1332
+ }
1333
+
1334
+ /* Fist statistic to record begin frame number and system time */
1335
+ if (!g_audio -> fn -> second ++ ) {
1336
+ g_audio -> fn -> time_begin = g_audio -> fn -> time_last ;
1337
+ g_audio -> fn -> fn_begin = frame_number ;
1338
+ g_audio -> fn -> fn_last = frame_number ;
1339
+ goto out ;
1340
+ }
1341
+
1342
+ /*
1343
+ * For DWC3 Controller, only 13 bits is used to store frame(micro)
1344
+ * number. In other words, the frame number will overflow at most
1345
+ * 2.047 seconds. We add another registor fn_overflow the record
1346
+ * total frame number.
1347
+ */
1348
+ if (frame_number <= g_audio -> fn -> fn_last )
1349
+ g_audio -> fn -> fn_overflow ++ ;
1350
+ g_audio -> fn -> fn_last = frame_number ;
1351
+
1352
+ if (!g_audio -> fn -> fn_overflow )
1353
+ goto out ;
1354
+
1355
+ /* The lower 3 bits represent micro number frame, we don't need it */
1356
+ fn_msec = (((fn -> fn_overflow - 1 ) << 14 ) +
1357
+ (BIT (14 ) + fn -> fn_last - fn -> fn_begin ) + BIT (2 )) >> 3 ;
1358
+ time_msec_tmp = fn -> time_last - fn -> time_begin + 500000ULL ;
1359
+ do_div (time_msec_tmp , 1000000U );
1360
+ clk_msec = (uint32_t )time_msec_tmp ;
1361
+
1362
+ /*
1363
+ * According to the definition of ppm:
1364
+ * host_clk = (1 + ppm / 1000000) * gadget_clk
1365
+ * we can get:
1366
+ * ppm = (host_clk - gadget_clk) * 1000000 / gadget_clk
1367
+ */
1368
+ ppm = (fn_msec > clk_msec ) ?
1369
+ (fn_msec - clk_msec ) * 1000000L / clk_msec :
1370
+ - ((clk_msec - fn_msec ) * 1000000L / clk_msec );
1371
+
1372
+ ppm_sum = ppm_sum - ppms [cnt ] + ppm ;
1373
+ ppms [cnt ] = ppm ;
1374
+
1375
+ dev_dbg (g_audio -> device ,
1376
+ "frame %u msec %u ppm_calc %d ppm_avage(%d) %d\n" ,
1377
+ fn_msec , clk_msec , ppm , CLK_PPM_GROUP_SIZE ,
1378
+ ppm_sum / CLK_PPM_GROUP_SIZE );
1379
+
1380
+ /*
1381
+ * We calculate the average of ppm over a period of time. If the
1382
+ * latest frame number is too far from the average, no event will
1383
+ * be sent.
1384
+ */
1385
+ if (abs (ppm_sum / CLK_PPM_GROUP_SIZE - ppm ) < 3 ) {
1386
+ ppm = ppm_sum > 0 ?
1387
+ (ppm_sum + CLK_PPM_GROUP_SIZE / 2 ) / CLK_PPM_GROUP_SIZE :
1388
+ (ppm_sum - CLK_PPM_GROUP_SIZE / 2 ) / CLK_PPM_GROUP_SIZE ;
1389
+ if (ppm != g_audio -> params .ppm ) {
1390
+ g_audio -> params .ppm = ppm ;
1391
+ g_audio -> usb_state [SET_AUDIO_CLK ] = true;
1392
+ schedule_work (& g_audio -> work );
1393
+ }
1394
+ }
1395
+
1396
+ out :
1397
+ schedule_delayed_work (& g_audio -> ppm_work , 1 * HZ );
1398
+ }
1399
+
1293
1400
int g_audio_setup (struct g_audio * g_audio , const char * pcm_name ,
1294
1401
const char * card_name )
1295
1402
{
@@ -1314,6 +1421,12 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
1314
1421
p_chmask = params -> p_chmask ;
1315
1422
c_chmask = params -> c_chmask ;
1316
1423
1424
+ g_audio -> fn = kzalloc (sizeof (* g_audio -> fn ), GFP_KERNEL );
1425
+ if (!g_audio -> fn ) {
1426
+ err = - ENOMEM ;
1427
+ goto fail ;
1428
+ }
1429
+
1317
1430
if (c_chmask ) {
1318
1431
struct uac_rtd_params * prm = & uac -> c_prm ;
1319
1432
@@ -1543,6 +1656,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
1543
1656
}
1544
1657
1545
1658
INIT_WORK (& g_audio -> work , g_audio_work );
1659
+ INIT_DELAYED_WORK (& g_audio -> ppm_work , ppm_calculate_work );
1660
+ ppm_calculate_work (& g_audio -> ppm_work .work );
1546
1661
1547
1662
if (!err )
1548
1663
return 0 ;
@@ -1555,6 +1670,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
1555
1670
kfree (uac -> p_prm .rbuf );
1556
1671
kfree (uac -> c_prm .rbuf );
1557
1672
kfree (uac );
1673
+ kfree (g_audio -> fn );
1558
1674
1559
1675
return err ;
1560
1676
}
@@ -1569,6 +1685,7 @@ void g_audio_cleanup(struct g_audio *g_audio)
1569
1685
return ;
1570
1686
1571
1687
cancel_work_sync (& g_audio -> work );
1688
+ cancel_delayed_work_sync (& g_audio -> ppm_work );
1572
1689
device_destroy (g_audio -> device -> class , g_audio -> device -> devt );
1573
1690
g_audio -> device = NULL ;
1574
1691
@@ -1582,6 +1699,7 @@ void g_audio_cleanup(struct g_audio *g_audio)
1582
1699
kfree (uac -> p_prm .rbuf );
1583
1700
kfree (uac -> c_prm .rbuf );
1584
1701
kfree (uac );
1702
+ kfree (g_audio -> fn );
1585
1703
}
1586
1704
EXPORT_SYMBOL_GPL (g_audio_cleanup );
1587
1705
0 commit comments