From mboxrd@z Thu Jan 1 00:00:00 1970 From: Yakir Yang Subject: Re: [PATCH 1/3] drm/rockchip: inno_hdmi: add audio support Date: Tue, 2 Aug 2016 10:16:04 +0800 Message-ID: <57A00264.2050603@rock-chips.com> References: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8"; Format="flowed" Content-Transfer-Encoding: base64 Return-path: In-Reply-To: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Mark Yao , Heiko Stuebner Cc: Mark Rutland , devicetree@vger.kernel.org, Zheng Yang , Pawel Moll , Ian Campbell , Ken Mixte , Russell King , dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, Rob Herring , Kumar Gala , Thierry Reding , linux-arm-kernel@lists.infradead.org, Ben Chan List-Id: linux-rockchip.vger.kernel.org SGkgTWFyayAmIEhlaWtvLAoKUGluZy4uLi4uLgoKVGhhbmtzLAotIFlha2lyCgpPbiAwNi8xNS8y MDE2IDA5OjI4IFBNLCBZYWtpciBZYW5nIHdyb3RlOgo+IFVzaW5nIHRoZSBjb21tb24gaGRtaS1j b2RlYyBkcml2ZXIgdG8gc3VwcG9ydCBoZG1pIGF1ZGlvIGZ1bmN0aW9uLgo+Cj4gU2lnbmVkLW9m Zi1ieTogWWFraXIgWWFuZyA8eWtrQHJvY2stY2hpcHMuY29tPgo+IC0tLQo+ICAgZHJpdmVycy9n cHUvZHJtL3JvY2tjaGlwL2lubm9faGRtaS5jIHwgMjM3ICsrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKystCj4gICBkcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmggfCAg IDIgKwo+ICAgMiBmaWxlcyBjaGFuZ2VkLCAyMzcgaW5zZXJ0aW9ucygrKSwgMiBkZWxldGlvbnMo LSkKPgo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmMg Yi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmMKPiBpbmRleCBmOGI0ZmViLi5j MzFkYzA3IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWku Ywo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWkuYwo+IEBAIC0yOSw2 ICsyOSw4IEBACj4gICAjaW5jbHVkZSA8ZHJtL2RybV9jcnRjX2hlbHBlci5oPgo+ICAgI2luY2x1 ZGUgPGRybS9kcm1fZWRpZC5oPgo+ICAgCj4gKyNpbmNsdWRlIDxzb3VuZC9oZG1pLWNvZGVjLmg+ Cj4gKwo+ICAgI2luY2x1ZGUgInJvY2tjaGlwX2RybV9kcnYuaCIKPiAgICNpbmNsdWRlICJyb2Nr Y2hpcF9kcm1fdm9wLmgiCj4gICAKPiBAQCAtMzYsNiArMzgsMTIgQEAKPiAgIAo+ICAgI2RlZmlu ZSB0b19pbm5vX2hkbWkoeCkJY29udGFpbmVyX29mKHgsIHN0cnVjdCBpbm5vX2hkbWksIHgpCj4g ICAKPiArc3RydWN0IGF1ZGlvX2luZm8gewo+ICsJaW50IHNhbXBsZV9yYXRlOwo+ICsJaW50IGNo YW5uZWxzOwo+ICsJaW50IHNhbXBsZV93aWR0aDsKPiArfTsKPiArCj4gICBzdHJ1Y3QgaGRtaV9k YXRhX2luZm8gewo+ICAgCWludCB2aWM7Cj4gICAJYm9vbCBzaW5rX2lzX2hkbWk7Cj4gQEAgLTcx LDYgKzc5LDkgQEAgc3RydWN0IGlubm9faGRtaSB7Cj4gICAKPiAgIAl1bnNpZ25lZCBpbnQgdG1k c19yYXRlOwo+ICAgCj4gKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICphdWRpb19wZGV2Owo+ICsJ Ym9vbCBhdWRpb19lbmFibGU7Cj4gKwo+ICAgCXN0cnVjdCBoZG1pX2RhdGFfaW5mbwloZG1pX2Rh dGE7Cj4gICAJc3RydWN0IGRybV9kaXNwbGF5X21vZGUgcHJldmlvdXNfbW9kZTsKPiAgIH07Cj4g QEAgLTMwNiw2ICszMTcsNTcgQEAgc3RhdGljIGludCBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX2F2 aShzdHJ1Y3QgaW5ub19oZG1pICpoZG1pLAo+ICAgCXJldHVybiBpbm5vX2hkbWlfdXBsb2FkX2Zy YW1lKGhkbWksIHJjLCAmZnJhbWUsIElORk9GUkFNRV9BVkksIDAsIDAsIDApOwo+ICAgfQo+ICAg Cj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2NvbmZpZ19hdWRpb19hYWkoc3RydWN0IGlubm9faGRt aSAqaGRtaSwKPiArCQkJCSAgICAgIHN0cnVjdCBhdWRpb19pbmZvICphdWRpbykKPiArewo+ICsJ c3RydWN0IGhkbWlfYXVkaW9faW5mb2ZyYW1lICpmYXVkaW87Cj4gKwl1bmlvbiBoZG1pX2luZm9m cmFtZSBmcmFtZTsKPiArCWludCByYzsKPiArCj4gKwlyYyA9IGhkbWlfYXVkaW9faW5mb2ZyYW1l X2luaXQoJmZyYW1lLmF1ZGlvKTsKPiArCWZhdWRpbyA9IChzdHJ1Y3QgaGRtaV9hdWRpb19pbmZv ZnJhbWUgKikmZnJhbWU7Cj4gKwo+ICsJZmF1ZGlvLT5jaGFubmVscyA9IGF1ZGlvLT5jaGFubmVs czsKPiArCj4gKwlzd2l0Y2ggKGF1ZGlvLT5zYW1wbGVfd2lkdGgpIHsKPiArCWNhc2UgMTY6Cj4g KwkJZmF1ZGlvLT5zYW1wbGVfc2l6ZSA9IEhETUlfQVVESU9fU0FNUExFX1NJWkVfMTY7Cj4gKwkJ YnJlYWs7Cj4gKwljYXNlIDIwOgo+ICsJCWZhdWRpby0+c2FtcGxlX3NpemUgPSBIRE1JX0FVRElP X1NBTVBMRV9TSVpFXzIwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSAyNDoKPiArCQlmYXVkaW8tPnNh bXBsZV9zaXplID0gSERNSV9BVURJT19TQU1QTEVfU0laRV8yNDsKPiArCQlicmVhazsKPiArCX0K PiArCj4gKwlzd2l0Y2ggKGF1ZGlvLT5zYW1wbGVfcmF0ZSkgewo+ICsJY2FzZSAzMjAwMDoKPiAr CQlmYXVkaW8tPnNhbXBsZV9mcmVxdWVuY3kgPSBIRE1JX0FVRElPX1NBTVBMRV9GUkVRVUVOQ1lf MzIwMDA7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIDQ0MTAwOgo+ICsJCWZhdWRpby0+c2FtcGxlX2Zy ZXF1ZW5jeSA9IEhETUlfQVVESU9fU0FNUExFX0ZSRVFVRU5DWV80NDEwMDsKPiArCQlicmVhazsK PiArCWNhc2UgNDgwMDA6Cj4gKwkJZmF1ZGlvLT5zYW1wbGVfZnJlcXVlbmN5ID0gSERNSV9BVURJ T19TQU1QTEVfRlJFUVVFTkNZXzQ4MDAwOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSA4ODIwMDoKPiAr CQlmYXVkaW8tPnNhbXBsZV9mcmVxdWVuY3kgPSBIRE1JX0FVRElPX1NBTVBMRV9GUkVRVUVOQ1lf ODgyMDA7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIDk2MDAwOgo+ICsJCWZhdWRpby0+c2FtcGxlX2Zy ZXF1ZW5jeSA9IEhETUlfQVVESU9fU0FNUExFX0ZSRVFVRU5DWV85NjAwMDsKPiArCQlicmVhazsK PiArCWNhc2UgMTc2NDAwOgo+ICsJCWZhdWRpby0+c2FtcGxlX2ZyZXF1ZW5jeSA9IEhETUlfQVVE SU9fU0FNUExFX0ZSRVFVRU5DWV8xNzY0MDA7Cj4gKwkJYnJlYWs7Cj4gKwljYXNlIDE5MjAwMDoK PiArCQlmYXVkaW8tPnNhbXBsZV9mcmVxdWVuY3kgPSBIRE1JX0FVRElPX1NBTVBMRV9GUkVRVUVO Q1lfMTkyMDAwOwo+ICsJCWJyZWFrOwo+ICsJfQo+ICsKPiArCXJldHVybiBpbm5vX2hkbWlfdXBs b2FkX2ZyYW1lKGhkbWksIHJjLCAmZnJhbWUsIElORk9GUkFNRV9BQUksIDAsIDAsIDApOwo+ICt9 Cj4gKwo+ICAgc3RhdGljIGludCBpbm5vX2hkbWlfY29uZmlnX3ZpZGVvX2NzYyhzdHJ1Y3QgaW5u b19oZG1pICpoZG1pKQo+ICAgewo+ICAgCXN0cnVjdCBoZG1pX2RhdGFfaW5mbyAqZGF0YSA9ICZo ZG1pLT5oZG1pX2RhdGE7Cj4gQEAgLTQ3OCw4ICs1NDAsOSBAQCBzdGF0aWMgaW50IGlubm9faGRt aV9zZXR1cChzdHJ1Y3QgaW5ub19oZG1pICpoZG1pLAo+ICAgCWlubm9faGRtaV9pMmNfaW5pdCho ZG1pKTsKPiAgIAo+ICAgCS8qIFVubXV0ZSB2aWRlbyBhbmQgYXVkaW8gb3V0cHV0ICovCj4gLQlo ZG1pX21vZGIoaGRtaSwgSERNSV9BVl9NVVRFLCBtX0FVRElPX01VVEUgfCBtX1ZJREVPX0JMQUNL LAo+IC0JCSAgdl9BVURJT19NVVRFKDApIHwgdl9WSURFT19NVVRFKDApKTsKPiArCWhkbWlfbW9k YihoZG1pLCBIRE1JX0FWX01VVEUsIG1fVklERU9fQkxBQ0ssIHZfVklERU9fTVVURSgwKSk7Cj4g KwlpZiAoaGRtaS0+YXVkaW9fZW5hYmxlKQo+ICsJCWhkbWlfbW9kYihoZG1pLCBIRE1JX0FWX01V VEUsIG1fQVVESU9fTVVURSwgdl9BVURJT19NVVRFKDApKTsKPiAgIAo+ICAgCXJldHVybiAwOwo+ ICAgfQo+IEBAIC02MTYsNiArNjc5LDE3NCBAQCBzdGF0aWMgc3RydWN0IGRybV9jb25uZWN0b3Jf aGVscGVyX2Z1bmNzIGlubm9faGRtaV9jb25uZWN0b3JfaGVscGVyX2Z1bmNzID0gewo+ICAgCS5i ZXN0X2VuY29kZXIgPSBpbm5vX2hkbWlfY29ubmVjdG9yX2Jlc3RfZW5jb2RlciwKPiAgIH07Cj4g ICAKPiAraW50IGlubm9faGRtaV9hdWRpb19jb25maWdfc2V0KHN0cnVjdCBpbm5vX2hkbWkgKmhk bWksIHN0cnVjdCBhdWRpb19pbmZvICphdWRpbykKPiArewo+ICsJaW50IHJhdGUsIE4sIGNoYW5u ZWw7Cj4gKwo+ICsJaWYgKGF1ZGlvLT5jaGFubmVscyA8IDMpCj4gKwkJY2hhbm5lbCA9IEkyU19D SEFOTkVMXzFfMjsKPiArCWVsc2UgaWYgKGF1ZGlvLT5jaGFubmVscyA8IDUpCj4gKwkJY2hhbm5l bCA9IEkyU19DSEFOTkVMXzNfNDsKPiArCWVsc2UgaWYgKGF1ZGlvLT5jaGFubmVscyA8IDcpCj4g KwkJY2hhbm5lbCA9IEkyU19DSEFOTkVMXzVfNjsKPiArCWVsc2UKPiArCQljaGFubmVsID0gSTJT X0NIQU5ORUxfN184Owo+ICsKPiArCXN3aXRjaCAoYXVkaW8tPnNhbXBsZV9yYXRlKSB7Cj4gKwlj YXNlIDMyMDAwOgo+ICsJCXJhdGUgPSBBVURJT18zMks7Cj4gKwkJTiA9IE5fMzJLOwo+ICsJCWJy ZWFrOwo+ICsJY2FzZSA0NDEwMDoKPiArCQlyYXRlID0gQVVESU9fNDQxSzsKPiArCQlOID0gTl80 NDFLOwo+ICsJCWJyZWFrOwo+ICsJY2FzZSA0ODAwMDoKPiArCQlyYXRlID0gQVVESU9fNDhLOwo+ ICsJCU4gPSBOXzQ4SzsKPiArCQlicmVhazsKPiArCWNhc2UgODgyMDA6Cj4gKwkJcmF0ZSA9IEFV RElPXzg4Mks7Cj4gKwkJTiA9IE5fODgySzsKPiArCQlicmVhazsKPiArCWNhc2UgOTYwMDA6Cj4g KwkJcmF0ZSA9IEFVRElPXzk2SzsKPiArCQlOID0gTl85Nks7Cj4gKwkJYnJlYWs7Cj4gKwljYXNl IDE3NjQwMDoKPiArCQlyYXRlID0gQVVESU9fMTc2NEs7Cj4gKwkJTiA9IE5fMTc2NEs7Cj4gKwkJ YnJlYWs7Cj4gKwljYXNlIDE5MjAwMDoKPiArCQlyYXRlID0gQVVESU9fMTkySzsKPiArCQlOID0g Tl8xOTJLOwo+ICsJCWJyZWFrOwo+ICsJZGVmYXVsdDoKPiArCQlkZXZfZXJyKGhkbWktPmRldiwg Ilslc10gbm90IHN1cHBvcnQgc3VjaCBzYW1wbGUgcmF0ZSAlZFxuIiwKPiArCQkJX19mdW5jX18s IGF1ZGlvLT5zYW1wbGVfcmF0ZSk7Cj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwl9Cj4gKwo+ICsJ Lyogc2V0X2F1ZGlvIHNvdXJjZSBJMlMgKi8KPiArCWhkbWlfd3JpdGViKGhkbWksIEhETUlfQVVE SU9fQ1RSTDEsIDB4MDEpOwo+ICsJaGRtaV93cml0ZWIoaGRtaSwgQVVESU9fU0FNUExFX1JBVEUs IHJhdGUpOwo+ICsJaGRtaV93cml0ZWIoaGRtaSwgQVVESU9fSTJTX01PREUsIHZfSTJTX01PREUo STJTX1NUQU5EQVJEKSB8Cj4gKwkJICAgIHZfSTJTX0NIQU5ORUwoY2hhbm5lbCkpOwo+ICsKPiAr CWhkbWlfd3JpdGViKGhkbWksIEFVRElPX0kyU19NQVAsIDB4MDApOwo+ICsJaGRtaV93cml0ZWIo aGRtaSwgQVVESU9fSTJTX1NXQVBTX1NQRElGLCAwKTsKPiArCj4gKwkvKiBTZXQgTiB2YWx1ZSAq Lwo+ICsJaGRtaV93cml0ZWIoaGRtaSwgQVVESU9fTl9ILCAoTiA+PiAxNikgJiAweDBGKTsKPiAr CWhkbWlfd3JpdGViKGhkbWksIEFVRElPX05fTSwgKE4gPj4gOCkgJiAweEZGKTsKPiArCWhkbWlf d3JpdGViKGhkbWksIEFVRElPX05fTCwgTiAmIDB4RkYpOwo+ICsKPiArCS8qU2V0IGhkbWkgbmxw Y20gbW9kZSB0byBzdXBwb3J0IGhkbWkgYml0c3RyZWFtKi8KPiArCWhkbWlfd3JpdGViKGhkbWks IEhETUlfQVVESU9fQ0hBTk5FTF9TVEFUVVMsIHZfQVVESU9fU1RBVFVTX05MUENNKDApKTsKPiAr Cj4gKwlyZXR1cm4gaW5ub19oZG1pX2NvbmZpZ19hdWRpb19hYWkoaGRtaSwgYXVkaW8pOwo+ICt9 Cj4gKwo+ICtzdGF0aWMgaW50IGlubm9faGRtaV9hdWRpb19od19wYXJhbXMoc3RydWN0IGRldmlj ZSAqZGV2LAo+ICsJCQkJICAgICBzdHJ1Y3QgaGRtaV9jb2RlY19kYWlmbXQgKmRhaWZtdCwKPiAr CQkJCSAgICAgc3RydWN0IGhkbWlfY29kZWNfcGFyYW1zICpwYXJhbXMpCj4gK3sKPiArCXN0cnVj dCBpbm5vX2hkbWkgKmhkbWkgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiArCXN0cnVjdCBhdWRp b19pbmZvIGF1ZGlvID0gewo+ICsJCS5zYW1wbGVfd2lkdGggPSBwYXJhbXMtPnNhbXBsZV93aWR0 aCwKPiArCQkuc2FtcGxlX3JhdGUgPSBwYXJhbXMtPnNhbXBsZV9yYXRlLAo+ICsJCS5jaGFubmVs cyA9IHBhcmFtcy0+Y2hhbm5lbHMsCj4gKwl9Owo+ICsKPiArCWlmICghaGRtaS0+aGRtaV9kYXRh LnNpbmtfaGFzX2F1ZGlvKSB7Cj4gKwkJZGV2X2VycihoZG1pLT5kZXYsICJTaW5rIGRvIG5vdCBz dXBwb3J0IGF1ZGlvIVxuIik7Cj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwl9Cj4gKwo+ICsJaWYg KCFoZG1pLT5lbmNvZGVyLmNydGMpCj4gKwkJcmV0dXJuIC1FTk9ERVY7Cj4gKwo+ICsJc3dpdGNo IChkYWlmbXQtPmZtdCkgewo+ICsJY2FzZSBIRE1JX0kyUzoKPiArCQlicmVhazsKPiArCWRlZmF1 bHQ6Cj4gKwkJZGV2X2VycihkZXYsICIlczogSW52YWxpZCBmb3JtYXQgJWRcbiIsIF9fZnVuY19f LCBkYWlmbXQtPmZtdCk7Cj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJcmV0dXJu IGlubm9faGRtaV9hdWRpb19jb25maWdfc2V0KGhkbWksICZhdWRpbyk7Cj4gK30KPiArCj4gK3N0 YXRpYyB2b2lkIGlubm9faGRtaV9hdWRpb19zaHV0ZG93bihzdHJ1Y3QgZGV2aWNlICpkZXYpCj4g K3sKPiArCS8qIGRvIG5vdGhpbmcgKi8KPiArfQo+ICsKPiArc3RhdGljIGludCBpbm5vX2hkbWlf YXVkaW9fZGlnaXRhbF9tdXRlKHN0cnVjdCBkZXZpY2UgKmRldiwgYm9vbCBtdXRlKQo+ICt7Cj4g KwlzdHJ1Y3QgaW5ub19oZG1pICpoZG1pID0gZGV2X2dldF9kcnZkYXRhKGRldik7Cj4gKwo+ICsJ aWYgKCFoZG1pLT5oZG1pX2RhdGEuc2lua19oYXNfYXVkaW8pIHsKPiArCQlkZXZfZXJyKGhkbWkt PmRldiwgIlNpbmsgZG8gbm90IHN1cHBvcnQgYXVkaW8hXG4iKTsKPiArCQlyZXR1cm4gLUVOT0RF VjsKPiArCX0KPiArCj4gKwloZG1pLT5hdWRpb19lbmFibGUgPSAhbXV0ZTsKPiArCj4gKwlpZiAo bXV0ZSkKPiArCQloZG1pX21vZGIoaGRtaSwgSERNSV9BVl9NVVRFLCBtX0FVRElPX01VVEUgfCBt X0FVRElPX1BELAo+ICsJCQkgIHZfQVVESU9fTVVURSgxKSB8IHZfQVVESU9fUEQoMSkpOwo+ICsJ ZWxzZQo+ICsJCWhkbWlfbW9kYihoZG1pLCBIRE1JX0FWX01VVEUsIG1fQVVESU9fTVVURSB8IG1f QVVESU9fUEQsCj4gKwkJCSAgdl9BVURJT19NVVRFKDApIHwgdl9BVURJT19QRCgwKSk7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2F1ZGlvX2dldF9l bGQoc3RydWN0IGRldmljZSAqZGV2LCB1aW50OF90ICpidWYsIHNpemVfdCBsZW4pCj4gK3sKPiAr CXN0cnVjdCBpbm5vX2hkbWkgKmhkbWkgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsKPiArCXN0cnVj dCBkcm1fbW9kZV9jb25maWcgKmNvbmZpZyA9ICZoZG1pLT5lbmNvZGVyLmRldi0+bW9kZV9jb25m aWc7Cj4gKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yOwo+ICsJaW50IHJldCA9IC1F Tk9ERVY7Cj4gKwo+ICsJbXV0ZXhfbG9jaygmY29uZmlnLT5tdXRleCk7Cj4gKwlsaXN0X2Zvcl9l YWNoX2VudHJ5KGNvbm5lY3RvciwgJmNvbmZpZy0+Y29ubmVjdG9yX2xpc3QsIGhlYWQpIHsKPiAr CQlpZiAoJmhkbWktPmVuY29kZXIgPT0gY29ubmVjdG9yLT5lbmNvZGVyKSB7Cj4gKwkJCW1lbWNw eShidWYsIGNvbm5lY3Rvci0+ZWxkLAo+ICsJCQkgICAgICAgbWluKHNpemVvZihjb25uZWN0b3It PmVsZCksIGxlbikpOwo+ICsJCQlyZXQgPSAwOwo+ICsJCX0KPiArCX0KPiArCW11dGV4X3VubG9j aygmY29uZmlnLT5tdXRleCk7Cj4gKwo+ICsJcmV0dXJuIHJldDsKPiArfQo+ICsKPiArc3RhdGlj IGNvbnN0IHN0cnVjdCBoZG1pX2NvZGVjX29wcyBhdWRpb19jb2RlY19vcHMgPSB7Cj4gKwkuaHdf cGFyYW1zID0gaW5ub19oZG1pX2F1ZGlvX2h3X3BhcmFtcywKPiArCS5hdWRpb19zaHV0ZG93biA9 IGlubm9faGRtaV9hdWRpb19zaHV0ZG93biwKPiArCS5kaWdpdGFsX211dGUgPSBpbm5vX2hkbWlf YXVkaW9fZGlnaXRhbF9tdXRlLAo+ICsJLmdldF9lbGQgPSBpbm5vX2hkbWlfYXVkaW9fZ2V0X2Vs ZCwKPiArfTsKPiArCj4gK3N0YXRpYyBpbnQgaW5ub19oZG1pX2F1ZGlvX2NvZGVjX2luaXQoc3Ry dWN0IGlubm9faGRtaSAqaGRtaSwKPiArCQkJCSAgICAgIHN0cnVjdCBkZXZpY2UgKmRldikKPiAr ewo+ICsJc3RydWN0IGhkbWlfY29kZWNfcGRhdGEgY29kZWNfZGF0YSA9IHsKPiArCQkuaTJzID0g MSwKPiArCQkub3BzID0gJmF1ZGlvX2NvZGVjX29wcywKPiArCQkubWF4X2kyc19jaGFubmVscyA9 IDgsCj4gKwl9Owo+ICsKPiArCWhkbWktPmF1ZGlvX2VuYWJsZSA9IGZhbHNlOwo+ICsJaGRtaS0+ YXVkaW9fcGRldiA9IHBsYXRmb3JtX2RldmljZV9yZWdpc3Rlcl9kYXRhKAo+ICsJCQkJZGV2LCBI RE1JX0NPREVDX0RSVl9OQU1FLCBQTEFURk9STV9ERVZJRF9OT05FLAo+ICsJCQkJJmNvZGVjX2Rh dGEsIHNpemVvZihjb2RlY19kYXRhKSk7Cj4gKwo+ICsJcmV0dXJuIFBUUl9FUlJfT1JfWkVSTyho ZG1pLT5hdWRpb19wZGV2KTsKPiArfQo+ICsKPiAgIHN0YXRpYyBpbnQgaW5ub19oZG1pX3JlZ2lz dGVyKHN0cnVjdCBkcm1fZGV2aWNlICpkcm0sIHN0cnVjdCBpbm5vX2hkbWkgKmhkbWkpCj4gICB7 Cj4gICAJc3RydWN0IGRybV9lbmNvZGVyICplbmNvZGVyID0gJmhkbWktPmVuY29kZXI7Cj4gQEAg LTY0NSw2ICs4NzYsOCBAQCBzdGF0aWMgaW50IGlubm9faGRtaV9yZWdpc3RlcihzdHJ1Y3QgZHJt X2RldmljZSAqZHJtLCBzdHJ1Y3QgaW5ub19oZG1pICpoZG1pKQo+ICAgCj4gICAJZHJtX21vZGVf Y29ubmVjdG9yX2F0dGFjaF9lbmNvZGVyKCZoZG1pLT5jb25uZWN0b3IsIGVuY29kZXIpOwo+ICAg Cj4gKwlpbm5vX2hkbWlfYXVkaW9fY29kZWNfaW5pdChoZG1pLCBkZXYpOwo+ICsKPiAgIAlyZXR1 cm4gMDsKPiAgIH0KPiAgIAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAv aW5ub19oZG1pLmggYi9kcml2ZXJzL2dwdS9kcm0vcm9ja2NoaXAvaW5ub19oZG1pLmgKPiBpbmRl eCBhYTdjNDE1Li44YjIzMDM3IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hp cC9pbm5vX2hkbWkuaAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9yb2NrY2hpcC9pbm5vX2hkbWku aAo+IEBAIC0xMDQsMTEgKzEwNCwxMyBAQCBlbnVtIHsKPiAgICNkZWZpbmUgSERNSV9BVl9NVVRF CQkJMHgwNQo+ICAgI2RlZmluZSBtX0FWTVVURV9DTEVBUgkJCSgxIDw8IDcpCj4gICAjZGVmaW5l IG1fQVZNVVRFX0VOQUJMRQkJCSgxIDw8IDYpCj4gKyNkZWZpbmUgbV9BVURJT19QRAkJCSgxIDw8 IDIpCj4gICAjZGVmaW5lIG1fQVVESU9fTVVURQkJCSgxIDw8IDEpCj4gICAjZGVmaW5lIG1fVklE RU9fQkxBQ0sJCQkoMSA8PCAwKQo+ICAgI2RlZmluZSB2X0FWTVVURV9DTEVBUihuKQkJKG4gPDwg NykKPiAgICNkZWZpbmUgdl9BVk1VVEVfRU5BQkxFKG4pCQkobiA8PCA2KQo+ICAgI2RlZmluZSB2 X0FVRElPX01VVEUobikJCQkobiA8PCAxKQo+ICsjZGVmaW5lIHZfQVVESU9fUEQobikJCQkobiA8 PCAyKQo+ICAgI2RlZmluZSB2X1ZJREVPX01VVEUobikJCQkobiA8PCAwKQo+ICAgCj4gICAjZGVm aW5lIEhETUlfVklERU9fVElNSU5HX0NUTAkJMHgwOAoKCl9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWlsaW5nIGxpc3QKZHJpLWRldmVs QGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZyZWVkZXNrdG9wLm9yZy9tYWls bWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo= From mboxrd@z Thu Jan 1 00:00:00 1970 From: ykk@rock-chips.com (Yakir Yang) Date: Tue, 2 Aug 2016 10:16:04 +0800 Subject: [PATCH 1/3] drm/rockchip: inno_hdmi: add audio support In-Reply-To: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> References: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> Message-ID: <57A00264.2050603@rock-chips.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hi Mark & Heiko, Ping...... Thanks, - Yakir On 06/15/2016 09:28 PM, Yakir Yang wrote: > Using the common hdmi-codec driver to support hdmi audio function. > > Signed-off-by: Yakir Yang > --- > drivers/gpu/drm/rockchip/inno_hdmi.c | 237 ++++++++++++++++++++++++++++++++++- > drivers/gpu/drm/rockchip/inno_hdmi.h | 2 + > 2 files changed, 237 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c > index f8b4feb..c31dc07 100644 > --- a/drivers/gpu/drm/rockchip/inno_hdmi.c > +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c > @@ -29,6 +29,8 @@ > #include > #include > > +#include > + > #include "rockchip_drm_drv.h" > #include "rockchip_drm_vop.h" > > @@ -36,6 +38,12 @@ > > #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x) > > +struct audio_info { > + int sample_rate; > + int channels; > + int sample_width; > +}; > + > struct hdmi_data_info { > int vic; > bool sink_is_hdmi; > @@ -71,6 +79,9 @@ struct inno_hdmi { > > unsigned int tmds_rate; > > + struct platform_device *audio_pdev; > + bool audio_enable; > + > struct hdmi_data_info hdmi_data; > struct drm_display_mode previous_mode; > }; > @@ -306,6 +317,57 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, > return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0); > } > > +static int inno_hdmi_config_audio_aai(struct inno_hdmi *hdmi, > + struct audio_info *audio) > +{ > + struct hdmi_audio_infoframe *faudio; > + union hdmi_infoframe frame; > + int rc; > + > + rc = hdmi_audio_infoframe_init(&frame.audio); > + faudio = (struct hdmi_audio_infoframe *)&frame; > + > + faudio->channels = audio->channels; > + > + switch (audio->sample_width) { > + case 16: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; > + break; > + case 20: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_20; > + break; > + case 24: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_24; > + break; > + } > + > + switch (audio->sample_rate) { > + case 32000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_32000; > + break; > + case 44100: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_44100; > + break; > + case 48000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000; > + break; > + case 88200: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_88200; > + break; > + case 96000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_96000; > + break; > + case 176400: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_176400; > + break; > + case 192000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_192000; > + break; > + } > + > + return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AAI, 0, 0, 0); > +} > + > static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) > { > struct hdmi_data_info *data = &hdmi->hdmi_data; > @@ -478,8 +540,9 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi, > inno_hdmi_i2c_init(hdmi); > > /* Unmute video and audio output */ > - hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, > - v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0)); > + if (hdmi->audio_enable) > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE, v_AUDIO_MUTE(0)); > > return 0; > } > @@ -616,6 +679,174 @@ static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = { > .best_encoder = inno_hdmi_connector_best_encoder, > }; > > +int inno_hdmi_audio_config_set(struct inno_hdmi *hdmi, struct audio_info *audio) > +{ > + int rate, N, channel; > + > + if (audio->channels < 3) > + channel = I2S_CHANNEL_1_2; > + else if (audio->channels < 5) > + channel = I2S_CHANNEL_3_4; > + else if (audio->channels < 7) > + channel = I2S_CHANNEL_5_6; > + else > + channel = I2S_CHANNEL_7_8; > + > + switch (audio->sample_rate) { > + case 32000: > + rate = AUDIO_32K; > + N = N_32K; > + break; > + case 44100: > + rate = AUDIO_441K; > + N = N_441K; > + break; > + case 48000: > + rate = AUDIO_48K; > + N = N_48K; > + break; > + case 88200: > + rate = AUDIO_882K; > + N = N_882K; > + break; > + case 96000: > + rate = AUDIO_96K; > + N = N_96K; > + break; > + case 176400: > + rate = AUDIO_1764K; > + N = N_1764K; > + break; > + case 192000: > + rate = AUDIO_192K; > + N = N_192K; > + break; > + default: > + dev_err(hdmi->dev, "[%s] not support such sample rate %d\n", > + __func__, audio->sample_rate); > + return -ENOENT; > + } > + > + /* set_audio source I2S */ > + hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x01); > + hdmi_writeb(hdmi, AUDIO_SAMPLE_RATE, rate); > + hdmi_writeb(hdmi, AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | > + v_I2S_CHANNEL(channel)); > + > + hdmi_writeb(hdmi, AUDIO_I2S_MAP, 0x00); > + hdmi_writeb(hdmi, AUDIO_I2S_SWAPS_SPDIF, 0); > + > + /* Set N value */ > + hdmi_writeb(hdmi, AUDIO_N_H, (N >> 16) & 0x0F); > + hdmi_writeb(hdmi, AUDIO_N_M, (N >> 8) & 0xFF); > + hdmi_writeb(hdmi, AUDIO_N_L, N & 0xFF); > + > + /*Set hdmi nlpcm mode to support hdmi bitstream*/ > + hdmi_writeb(hdmi, HDMI_AUDIO_CHANNEL_STATUS, v_AUDIO_STATUS_NLPCM(0)); > + > + return inno_hdmi_config_audio_aai(hdmi, audio); > +} > + > +static int inno_hdmi_audio_hw_params(struct device *dev, > + struct hdmi_codec_daifmt *daifmt, > + struct hdmi_codec_params *params) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + struct audio_info audio = { > + .sample_width = params->sample_width, > + .sample_rate = params->sample_rate, > + .channels = params->channels, > + }; > + > + if (!hdmi->hdmi_data.sink_has_audio) { > + dev_err(hdmi->dev, "Sink do not support audio!\n"); > + return -ENODEV; > + } > + > + if (!hdmi->encoder.crtc) > + return -ENODEV; > + > + switch (daifmt->fmt) { > + case HDMI_I2S: > + break; > + default: > + dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt); > + return -EINVAL; > + } > + > + return inno_hdmi_audio_config_set(hdmi, &audio); > +} > + > +static void inno_hdmi_audio_shutdown(struct device *dev) > +{ > + /* do nothing */ > +} > + > +static int inno_hdmi_audio_digital_mute(struct device *dev, bool mute) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + > + if (!hdmi->hdmi_data.sink_has_audio) { > + dev_err(hdmi->dev, "Sink do not support audio!\n"); > + return -ENODEV; > + } > + > + hdmi->audio_enable = !mute; > + > + if (mute) > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD, > + v_AUDIO_MUTE(1) | v_AUDIO_PD(1)); > + else > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD, > + v_AUDIO_MUTE(0) | v_AUDIO_PD(0)); > + > + return 0; > +} > + > +static int inno_hdmi_audio_get_eld(struct device *dev, uint8_t *buf, size_t len) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + struct drm_mode_config *config = &hdmi->encoder.dev->mode_config; > + struct drm_connector *connector; > + int ret = -ENODEV; > + > + mutex_lock(&config->mutex); > + list_for_each_entry(connector, &config->connector_list, head) { > + if (&hdmi->encoder == connector->encoder) { > + memcpy(buf, connector->eld, > + min(sizeof(connector->eld), len)); > + ret = 0; > + } > + } > + mutex_unlock(&config->mutex); > + > + return ret; > +} > + > +static const struct hdmi_codec_ops audio_codec_ops = { > + .hw_params = inno_hdmi_audio_hw_params, > + .audio_shutdown = inno_hdmi_audio_shutdown, > + .digital_mute = inno_hdmi_audio_digital_mute, > + .get_eld = inno_hdmi_audio_get_eld, > +}; > + > +static int inno_hdmi_audio_codec_init(struct inno_hdmi *hdmi, > + struct device *dev) > +{ > + struct hdmi_codec_pdata codec_data = { > + .i2s = 1, > + .ops = &audio_codec_ops, > + .max_i2s_channels = 8, > + }; > + > + hdmi->audio_enable = false; > + hdmi->audio_pdev = platform_device_register_data( > + dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE, > + &codec_data, sizeof(codec_data)); > + > + return PTR_ERR_OR_ZERO(hdmi->audio_pdev); > +} > + > static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) > { > struct drm_encoder *encoder = &hdmi->encoder; > @@ -645,6 +876,8 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) > > drm_mode_connector_attach_encoder(&hdmi->connector, encoder); > > + inno_hdmi_audio_codec_init(hdmi, dev); > + > return 0; > } > > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h b/drivers/gpu/drm/rockchip/inno_hdmi.h > index aa7c415..8b23037 100644 > --- a/drivers/gpu/drm/rockchip/inno_hdmi.h > +++ b/drivers/gpu/drm/rockchip/inno_hdmi.h > @@ -104,11 +104,13 @@ enum { > #define HDMI_AV_MUTE 0x05 > #define m_AVMUTE_CLEAR (1 << 7) > #define m_AVMUTE_ENABLE (1 << 6) > +#define m_AUDIO_PD (1 << 2) > #define m_AUDIO_MUTE (1 << 1) > #define m_VIDEO_BLACK (1 << 0) > #define v_AVMUTE_CLEAR(n) (n << 7) > #define v_AVMUTE_ENABLE(n) (n << 6) > #define v_AUDIO_MUTE(n) (n << 1) > +#define v_AUDIO_PD(n) (n << 2) > #define v_VIDEO_MUTE(n) (n << 0) > > #define HDMI_VIDEO_TIMING_CTL 0x08 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755808AbcHBCSB (ORCPT ); Mon, 1 Aug 2016 22:18:01 -0400 Received: from lucky1.263xmail.com ([211.157.147.133]:39558 "EHLO lucky1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755615AbcHBCRq (ORCPT ); Mon, 1 Aug 2016 22:17:46 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 1 X-MAIL-DELIVERY: 0 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-RL-SENDER: ykk@rock-chips.com X-FST-TO: linux-arm-kernel@lists.infradead.org X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: ykk@rock-chips.com X-UNIQUE-TAG: <529c75e523c0eb9718a95314acda627d> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 Subject: Re: [PATCH 1/3] drm/rockchip: inno_hdmi: add audio support To: Mark Yao , Heiko Stuebner References: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> Cc: Russell King , David Airlie , Thierry Reding , Rob Herring , Ken Mixte , Ben Chan , Zheng Yang , Kumar Gala , Ian Campbell , Pawel Moll , Mark Rutland , dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-rockchip@lists.infradead.org, linux-arm-kernel@lists.infradead.org From: Yakir Yang Message-ID: <57A00264.2050603@rock-chips.com> Date: Tue, 2 Aug 2016 10:16:04 +0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.8.0 MIME-Version: 1.0 In-Reply-To: <1465997312-17777-1-git-send-email-ykk@rock-chips.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Mark & Heiko, Ping...... Thanks, - Yakir On 06/15/2016 09:28 PM, Yakir Yang wrote: > Using the common hdmi-codec driver to support hdmi audio function. > > Signed-off-by: Yakir Yang > --- > drivers/gpu/drm/rockchip/inno_hdmi.c | 237 ++++++++++++++++++++++++++++++++++- > drivers/gpu/drm/rockchip/inno_hdmi.h | 2 + > 2 files changed, 237 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.c b/drivers/gpu/drm/rockchip/inno_hdmi.c > index f8b4feb..c31dc07 100644 > --- a/drivers/gpu/drm/rockchip/inno_hdmi.c > +++ b/drivers/gpu/drm/rockchip/inno_hdmi.c > @@ -29,6 +29,8 @@ > #include > #include > > +#include > + > #include "rockchip_drm_drv.h" > #include "rockchip_drm_vop.h" > > @@ -36,6 +38,12 @@ > > #define to_inno_hdmi(x) container_of(x, struct inno_hdmi, x) > > +struct audio_info { > + int sample_rate; > + int channels; > + int sample_width; > +}; > + > struct hdmi_data_info { > int vic; > bool sink_is_hdmi; > @@ -71,6 +79,9 @@ struct inno_hdmi { > > unsigned int tmds_rate; > > + struct platform_device *audio_pdev; > + bool audio_enable; > + > struct hdmi_data_info hdmi_data; > struct drm_display_mode previous_mode; > }; > @@ -306,6 +317,57 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi, > return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AVI, 0, 0, 0); > } > > +static int inno_hdmi_config_audio_aai(struct inno_hdmi *hdmi, > + struct audio_info *audio) > +{ > + struct hdmi_audio_infoframe *faudio; > + union hdmi_infoframe frame; > + int rc; > + > + rc = hdmi_audio_infoframe_init(&frame.audio); > + faudio = (struct hdmi_audio_infoframe *)&frame; > + > + faudio->channels = audio->channels; > + > + switch (audio->sample_width) { > + case 16: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_16; > + break; > + case 20: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_20; > + break; > + case 24: > + faudio->sample_size = HDMI_AUDIO_SAMPLE_SIZE_24; > + break; > + } > + > + switch (audio->sample_rate) { > + case 32000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_32000; > + break; > + case 44100: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_44100; > + break; > + case 48000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_48000; > + break; > + case 88200: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_88200; > + break; > + case 96000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_96000; > + break; > + case 176400: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_176400; > + break; > + case 192000: > + faudio->sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_192000; > + break; > + } > + > + return inno_hdmi_upload_frame(hdmi, rc, &frame, INFOFRAME_AAI, 0, 0, 0); > +} > + > static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi) > { > struct hdmi_data_info *data = &hdmi->hdmi_data; > @@ -478,8 +540,9 @@ static int inno_hdmi_setup(struct inno_hdmi *hdmi, > inno_hdmi_i2c_init(hdmi); > > /* Unmute video and audio output */ > - hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_VIDEO_BLACK, > - v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0)); > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_VIDEO_BLACK, v_VIDEO_MUTE(0)); > + if (hdmi->audio_enable) > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE, v_AUDIO_MUTE(0)); > > return 0; > } > @@ -616,6 +679,174 @@ static struct drm_connector_helper_funcs inno_hdmi_connector_helper_funcs = { > .best_encoder = inno_hdmi_connector_best_encoder, > }; > > +int inno_hdmi_audio_config_set(struct inno_hdmi *hdmi, struct audio_info *audio) > +{ > + int rate, N, channel; > + > + if (audio->channels < 3) > + channel = I2S_CHANNEL_1_2; > + else if (audio->channels < 5) > + channel = I2S_CHANNEL_3_4; > + else if (audio->channels < 7) > + channel = I2S_CHANNEL_5_6; > + else > + channel = I2S_CHANNEL_7_8; > + > + switch (audio->sample_rate) { > + case 32000: > + rate = AUDIO_32K; > + N = N_32K; > + break; > + case 44100: > + rate = AUDIO_441K; > + N = N_441K; > + break; > + case 48000: > + rate = AUDIO_48K; > + N = N_48K; > + break; > + case 88200: > + rate = AUDIO_882K; > + N = N_882K; > + break; > + case 96000: > + rate = AUDIO_96K; > + N = N_96K; > + break; > + case 176400: > + rate = AUDIO_1764K; > + N = N_1764K; > + break; > + case 192000: > + rate = AUDIO_192K; > + N = N_192K; > + break; > + default: > + dev_err(hdmi->dev, "[%s] not support such sample rate %d\n", > + __func__, audio->sample_rate); > + return -ENOENT; > + } > + > + /* set_audio source I2S */ > + hdmi_writeb(hdmi, HDMI_AUDIO_CTRL1, 0x01); > + hdmi_writeb(hdmi, AUDIO_SAMPLE_RATE, rate); > + hdmi_writeb(hdmi, AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | > + v_I2S_CHANNEL(channel)); > + > + hdmi_writeb(hdmi, AUDIO_I2S_MAP, 0x00); > + hdmi_writeb(hdmi, AUDIO_I2S_SWAPS_SPDIF, 0); > + > + /* Set N value */ > + hdmi_writeb(hdmi, AUDIO_N_H, (N >> 16) & 0x0F); > + hdmi_writeb(hdmi, AUDIO_N_M, (N >> 8) & 0xFF); > + hdmi_writeb(hdmi, AUDIO_N_L, N & 0xFF); > + > + /*Set hdmi nlpcm mode to support hdmi bitstream*/ > + hdmi_writeb(hdmi, HDMI_AUDIO_CHANNEL_STATUS, v_AUDIO_STATUS_NLPCM(0)); > + > + return inno_hdmi_config_audio_aai(hdmi, audio); > +} > + > +static int inno_hdmi_audio_hw_params(struct device *dev, > + struct hdmi_codec_daifmt *daifmt, > + struct hdmi_codec_params *params) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + struct audio_info audio = { > + .sample_width = params->sample_width, > + .sample_rate = params->sample_rate, > + .channels = params->channels, > + }; > + > + if (!hdmi->hdmi_data.sink_has_audio) { > + dev_err(hdmi->dev, "Sink do not support audio!\n"); > + return -ENODEV; > + } > + > + if (!hdmi->encoder.crtc) > + return -ENODEV; > + > + switch (daifmt->fmt) { > + case HDMI_I2S: > + break; > + default: > + dev_err(dev, "%s: Invalid format %d\n", __func__, daifmt->fmt); > + return -EINVAL; > + } > + > + return inno_hdmi_audio_config_set(hdmi, &audio); > +} > + > +static void inno_hdmi_audio_shutdown(struct device *dev) > +{ > + /* do nothing */ > +} > + > +static int inno_hdmi_audio_digital_mute(struct device *dev, bool mute) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + > + if (!hdmi->hdmi_data.sink_has_audio) { > + dev_err(hdmi->dev, "Sink do not support audio!\n"); > + return -ENODEV; > + } > + > + hdmi->audio_enable = !mute; > + > + if (mute) > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD, > + v_AUDIO_MUTE(1) | v_AUDIO_PD(1)); > + else > + hdmi_modb(hdmi, HDMI_AV_MUTE, m_AUDIO_MUTE | m_AUDIO_PD, > + v_AUDIO_MUTE(0) | v_AUDIO_PD(0)); > + > + return 0; > +} > + > +static int inno_hdmi_audio_get_eld(struct device *dev, uint8_t *buf, size_t len) > +{ > + struct inno_hdmi *hdmi = dev_get_drvdata(dev); > + struct drm_mode_config *config = &hdmi->encoder.dev->mode_config; > + struct drm_connector *connector; > + int ret = -ENODEV; > + > + mutex_lock(&config->mutex); > + list_for_each_entry(connector, &config->connector_list, head) { > + if (&hdmi->encoder == connector->encoder) { > + memcpy(buf, connector->eld, > + min(sizeof(connector->eld), len)); > + ret = 0; > + } > + } > + mutex_unlock(&config->mutex); > + > + return ret; > +} > + > +static const struct hdmi_codec_ops audio_codec_ops = { > + .hw_params = inno_hdmi_audio_hw_params, > + .audio_shutdown = inno_hdmi_audio_shutdown, > + .digital_mute = inno_hdmi_audio_digital_mute, > + .get_eld = inno_hdmi_audio_get_eld, > +}; > + > +static int inno_hdmi_audio_codec_init(struct inno_hdmi *hdmi, > + struct device *dev) > +{ > + struct hdmi_codec_pdata codec_data = { > + .i2s = 1, > + .ops = &audio_codec_ops, > + .max_i2s_channels = 8, > + }; > + > + hdmi->audio_enable = false; > + hdmi->audio_pdev = platform_device_register_data( > + dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE, > + &codec_data, sizeof(codec_data)); > + > + return PTR_ERR_OR_ZERO(hdmi->audio_pdev); > +} > + > static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) > { > struct drm_encoder *encoder = &hdmi->encoder; > @@ -645,6 +876,8 @@ static int inno_hdmi_register(struct drm_device *drm, struct inno_hdmi *hdmi) > > drm_mode_connector_attach_encoder(&hdmi->connector, encoder); > > + inno_hdmi_audio_codec_init(hdmi, dev); > + > return 0; > } > > diff --git a/drivers/gpu/drm/rockchip/inno_hdmi.h b/drivers/gpu/drm/rockchip/inno_hdmi.h > index aa7c415..8b23037 100644 > --- a/drivers/gpu/drm/rockchip/inno_hdmi.h > +++ b/drivers/gpu/drm/rockchip/inno_hdmi.h > @@ -104,11 +104,13 @@ enum { > #define HDMI_AV_MUTE 0x05 > #define m_AVMUTE_CLEAR (1 << 7) > #define m_AVMUTE_ENABLE (1 << 6) > +#define m_AUDIO_PD (1 << 2) > #define m_AUDIO_MUTE (1 << 1) > #define m_VIDEO_BLACK (1 << 0) > #define v_AVMUTE_CLEAR(n) (n << 7) > #define v_AVMUTE_ENABLE(n) (n << 6) > #define v_AUDIO_MUTE(n) (n << 1) > +#define v_AUDIO_PD(n) (n << 2) > #define v_VIDEO_MUTE(n) (n << 0) > > #define HDMI_VIDEO_TIMING_CTL 0x08