One thing to note on all I2C interfaces is that when GPIO is driven high (IN direction,dir=0) on the master (e.g. CS8409), SDA should be a constant HIGH, e.g. data=1. No matter if there is any I2C device connected to the bus, if you have a pull-up it will always pull-up the constant value 1. This 1 is usually a NACK that get received if you dont find the address. So far I couldn't get the IO[7] (SDA) with dir=0 (in,also known as HIGH direction) to deliver a data=1. IO[7] is with constant data=0. This means the pull-up is not pulling 1, and the I2C interface is not enabled by default after reset of the CS8409 codec. this is expected value for enabled I2C: IO[7]: enable=1, dir=0, wake=0, sticky=0, data=*1*, unsol=0 but what I get is: IO[7]: enable=1, dir=0, wake=0, sticky=0, data=0, unsol=0 which means I2C mode not initialized. I was just going to give up totally, and i looked up into one of my emails where i found the following: IO[7]: enable=1, dir=0, wake=0, sticky=0, data=1, unsol=0 after using my amateur send_sequence script (when i had no idea how I2C works) or some random sequence of events i executed and I had at this point IO[7] data as HIGH which means I2C was working at that exact moment. tho i did decipher the GPIO1ExtAmpCFG=hex:01,00,00,01 which if you check the schematics, the daisy-chained CS42L83A codec is powered by GPIO1 on CS8409 by keeping data=1, because there is pull-down on the CS42L83A's CODEC_RESET_L. There is also CODEC_INT_L which is the interrupt line, which is directly tied to GPIO[0] on CS8409. This actually returns a constant data=1, which gives some hope as well. IO[0]: enable=1, dir=0, wake=0, sticky=0, data=*1*, unsol=1 Opening AppleHDA in IDA reveals AppleHDAFunctionGroupCS4208::enableI2C(bool) Anyone knowing anything about TDM Config in Cirrus Logic ? Enabling I2C ? Is it Vendor specific verb ? Maybe it's some general way on most HDA's ? The reason to have I2C disabled on reset is that some of the devices like the amps and the speakers need to be configured in a specific order to save power and to avoid sound glitches. On Fri, Nov 23, 2018 at 7:26 PM David Ulricht <david.ulricht434@xxxxxxxxx> wrote: > > Once when it's confirmed to work from user-space, we can think of the >> kernel-side implementation, too. Instead of setting up the whole >> complex i2c subsystem, we may wire up the existing stuff in >> sound/i2c/*, too. >> > Okay > > You should try to initialize over i2c over HD-audio GPIO pins using a >> user-space program at first. The GPIO pins can be read/written via >> hda-verb as I already mentioned, hence you can access to i2c bus from >> the user-space directly. > > > I have written the following bash script, > >> #!/bin/bash >> # DIR 0 (low) = out 40 (high) = in >> # low to write, high to read >> # SCL == 0x40 SDA == 0x80 >> function send() { >> str1=$1 >> str2=$2 >> str3=$3 >> hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_MASK 0x$str1 >> # we send 0 to bus by enabling gpio_dir >> hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_DIR 0x$str2 >> # we send data=0 to send to the bus >> hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_DATA 0x$str3 >> } >> # reads the values I set, no different return value from i2c/codec >> function recv() { >> hda-verb /dev/snd/hwC0D0 0x01 GET_GPIO_MASK 0x$str1 >> hda-verb /dev/snd/hwC0D0 0x01 GET_GPIO_DIR 0x$str2 >> hda-verb /dev/snd/hwC0D0 0x01 GET_GPIO_DATA 0x$str3 >> } >> >> >> function send_sequence() { >> data=$1 >> #split hexes by coma to be able to send 1 by 1 >> hexes=$(echo $data|tr "," "\n") >> for hex in $hexes; do >> echo 'sending hex: ' $hex >> send 40 0 0 # 0 to scl >> > mask of SCL enabled, data 0 , dir 0, is that correct ? > >> sleep 0.003 >> send 80 0 $hex # send 0x28 to sda if $hex=28 >> > mask of SDA enabled, direction 0, hex to data > >> sleep 0.003 >> send 0 40 40 # 1 to scl >> > mask of SCL disabled, direction 1, data 1 > >> sleep 0.003 >> echo sent >> done >> } >> > below i'm sending the hexes from Win10ini but in the exact same order, > which worries me a bit, maybe they need to be reversed 4by4? > like 01,90,02,00,11,01,02 could become: 00,02,90,01,02,01,11 .. because > for the InitVerbs i did that reversing 4by4 and it works only correctly if > the hexes are reversed 4by4. (at the end of the email i am attaching the > exitverbs conversion which is perfect). > >> #initi2c >> send_sequence >> "01,90,3a,00,10,10,b0,00,1d,01,00,02,06,00,11,07,01,00,10,09,02,07,03,00,12,01,00,08,13,05,ff,06,00,07,20,02,0d,00,2a,02,02,03,00,04,00,05,02,06,00,07,20,08,02,09,00,0a,80,0b,02,0c,00,0d,a0,01,0c,00,29,02,01,03,02,04,00,05,00,01,01,00,11,01,0a,02,84,00,23,01,00,03,00,02,3f,00,20,01,03,00,1b,75,b6,73,c2,00,11,29,01,21,f3,03,20,05,00,12,00,13,80,00,1c,03,c0" >> #streamstarti2c >> send_sequence "01,90,02,00,11,01,02" >> #powerup-amps >> send_sequence >> "04,28,2a,2c,2e,07,00,81,01,11,02,32,03,48,04,11,05,10,00,80" >> send_sequence >> "01,28,01,05,00,01,2a,01,05,02,01,2c,01,05,01,01,2e,01,05,03" >> #streamstopi2c >> send_sequence "01,90,02,00,11,01,0a" >> #echo read >> #recv 0 0 0 >> > > For example something that works is > > "ExitVerbs"=hex:00,05,17,00,01,00,75,04,00,00,74,04,82,00,75,04,00,00,74,04,03,\ > > 00,75,04,00,80,74,04,04,00,75,04,01,28,74,04,06,00,75,04,00,80,74,04,07,00,\ > 75,04,01,28,74,04,65,00,75,04,00,00,74,04,00,03,77,04,03,05,17,00 > >> hda-verb /dev/snd/hwC0D0 0x01 0x705 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x01 >> hda-verb /dev/snd/hwC0D0 0x47 0x400 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x82 >> hda-verb /dev/snd/hwC0D0 0x47 0x400 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x03 >> hda-verb /dev/snd/hwC0D0 0x47 0x480 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x04 >> hda-verb /dev/snd/hwC0D0 0x47 0x428 0x01 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x06 >> hda-verb /dev/snd/hwC0D0 0x47 0x480 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x07 >> hda-verb /dev/snd/hwC0D0 0x47 0x428 0x01 >> hda-verb /dev/snd/hwC0D0 0x47 0x500 0x65 >> hda-verb /dev/snd/hwC0D0 0x47 0x400 0x00 >> hda-verb /dev/snd/hwC0D0 0x47 0x703 0x00 >> hda-verb /dev/snd/hwC0D0 0x01 0x705 0x03 >> >> Also InitVerbs from windows10ini and ExitVerbs from windows10ini reversed > hexes 4by4 sent with hda-verb work perfect. They initiate the CS8409 codec > or shut it down properly as i can see in the codec#0 status changing from > D3 to D0 and D0 to D3. > But the above exitverbs are sent to the widgets AFG node and the 0x47 > widget, (InitVerbs have a few more widgets). > > I tried to do the same for the InitI2C hexes, but apperently they are not > supposed to be send as hexes directly to the widgets like InitVerbs or > ExitVerbs. All the I2C related stuff are strictly I2C related for executing > on the SDA/SCL GPIO7/6. > > So my idea is, do I need to reverse the hexes 4 by 4, when sending to the > SDA ? > And if you have any examples how can i get a read value from the SDA > please. > > > Btw: > root@debian:~# cat /proc/asound/card0/codec#0 |head -n 25|tail -n 8 > IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[3]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[4]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[5]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[6]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[7]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > the default values are IO7 which is GPIO7 which is SDA. is enabled=0 dir=0 > data=0 > > root@debian:~# hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_MASK 0x80 > nid = 0x1, verb = 0x716, param = 0x80 > value = 0x0 > root@debian:~# hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_DIR 0x0 > nid = 0x1, verb = 0x717, param = 0x0 > value = 0x0 > root@debian:~# hda-verb /dev/snd/hwC0D0 0x01 SET_GPIO_DATA 0x28 > nid = 0x1, verb = 0x715, param = 0x28 > value = 0x0 > After i send the above, data becomes data=1 but i sent 0x28. > > root@debian:~# cat /proc/asound/card0/codec#0 |head -n 25|tail -n 8 > IO[0]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[1]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[2]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[3]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[4]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[5]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[6]: enable=0, dir=0, wake=0, sticky=0, data=0, unsol=0 > IO[7]: enable=1, dir=0, wake=0, sticky=0, data=1, unsol=0 > > But if i read GPIO_DATA, > root@debian:~# hda-verb /dev/snd/hwC0D0 0x01 GET_GPIO_DATA 0x0 > nid = 0x1, verb = 0xf15, param = 0x0 > value = 0x80 > > the value returned is 0x80. > Which leads me to the idea the only type of data you can send is either > 0x40 for 1 on SCL, 0x80 for 1 on SDA, or 0x00 for 0 on both( if you enable > mask of SCL it will send 0 to SCL only, and if you enable mask of SDA it > will send 0 to SDA only). > > If thats true, you can only send 0/1 to the GPIOs, which means if i have > to send the address of 1st SSM3515 "0x28", I have to send it as "101000" to > the SDA. > > How could I try to read register 0x00 of I2C address 0x28 (one of the > four SSM3515 amplifier) ? It should return value 0x83 according to the > documentation of SSM3515 as a "reset value for register 0x00". > > If it is true that I can read data with GET_GPIO_DATA will it return as > well only one bit of data like 0/1 at a time? If I need get a value of > 0x83 thru the GPIO7 its binary value should be 10000011 , so this means > that If i execute GET_GPIO_DATA 8 times in a row i will receive this > piece by piece 1, 0 , 0 , 0 , 0 , 0 , 1, 1. Meanwhile I try to execute 8 > times GET_GPIO_DATA should i be sending to the SCL (GPIO6) each time a > clock value 0 ? or also a SET_GPIO_DATA value to the GPIO7 with value 0 for > reading? > Please advise. > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel